from gpiozero import MotionSensor,Buzzer,LED,MCP3008, Button
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
from rpi_lcd import LCD
import serial
import picamera
from time import sleep
import json
from datetime import datetime, timedelta
import sys
from twilio.rest import Client
import re
import boto3
from boto3.dynamodb.conditions import Key, Attr
ser = serial.Serial('/dev/ttyUSB0', 9600) # Establish the connection on a specific port
sound_adc = MCP3008(channel=0)
light_adc = MCP3008(channel=1)
led = LED(18)
power = LED(21)
lcd = LCD()
deviceId = 'tehokosongBRUCE'
bz = Buzzer(23)
button = Button(24, pull_up=False)
currentBook = 0
#Preset token and stuff
account_sid = "[TWILLO SID]"
auth_token = "[AUTH TOKEN FOR TWILLO]"
client = Client(account_sid, auth_token)
twilio_hp = "[TWILLO HP]"
host = "[AWS ENDPOINT HERE]"
rootCAPath = "certs/rootca.pem"
certificatePath = "certs/certificate.pem.crt"
privateKeyPath = "certs/private.pem.key"
dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
#Update PiState
def updateState(stat):
try:
table = dynamodb.Table('TehOKosong_PiState')
table.update_item(
Key={
'DeviceId': deviceId
},UpdateExpression='SET stat = :val1',ExpressionAttributeValues={':val1': stat})
except:
print(sys.exc_info()[0])
print(sys.exc_info()[1])
#Get PiState
def getState():
try:
table = dynamodb.Table('TehOKosong_PiState')
response = table.query(KeyConditionExpression=Key('DeviceId').eq(deviceId),ScanIndexForward=False)
return response
except:
print(sys.exc_info()[0])
print(sys.exc_info()[1])
#Get Booking Time
def getNextBookingHour(now):
#If minute is 45, get next hour instead
hours = now.hour
minutes = now.minute
if minutes >= 45:
hours += 1
time = now.strftime("%Y-%m-%dT")
if(len(str(hours))):
time = time+"0"
time = time+str(hours)
return time
#Get Booking
def getBooking(now):
try:
table = dynamodb.Table('TehOKosong_Booking')
time = getNextBookingHour(now)
#Query if any booking within time
response = table.query(KeyConditionExpression=Key('DeviceId').eq(deviceId)
& Key('dateTimeIn').begins_with(time),ScanIndexForward=False)
#print(response)
return response
except:
print(sys.exc_info()[0])
print(sys.exc_info()[1])
#Get RFID of User
def getRFID(userId):
try:
table = dynamodb.Table('TehOKosong_Accounts')
response = table.query(KeyConditionExpression=Key('UserId').eq(userId),ScanIndexForward=False)
return response["Items"][0]["rfid"]
except:
print(sys.exc_info()[0])
print(sys.exc_info()[1])
def checkRFIDHist(now):
try:
hours = now.hour
table = dynamodb.Table('TehOKosong_RFIDHist')
time = now.strftime("%Y-%m-%dT")
if(len(str(hours))):
time = time+"0"
queryTime = time+str(hours)+str(":5")
#Query if any booking within 50minte period
response = table.query(KeyConditionExpression=Key('DeviceId').eq(deviceId)
& Key('dateTimeIn').begins_with(queryTime),ScanIndexForward=False)
if response["Items"]:
return true
else:
return false
except:
print(sys.exc_info()[0])
print(sys.exc_info()[1])
#Get Name of User based on ID
def getName(userId):
try:
table = dynamodb.Table('TehOKosong_Accounts')
response = table.query(KeyConditionExpression=Key('UserId').eq(userId),ScanIndexForward=False)
#print response
return response["Items"][0]["name"]
except:
print(sys.exc_info()[0])
print(sys.exc_info()[1])
#Get Phone of User based on ID
def getPhone(userId):
try:
table = dynamodb.Table('TehOKosong_Accounts')
response = table.query(KeyConditionExpression=Key('UserId').eq(userId),ScanIndexForward=False)
return response["Items"][0]["phone"]
except:
print(sys.exc_info()[0])
print(sys.exc_info()[1])
#Set Status Of Text
def setStatusText(stat):
text = ""
if stat == 1:
text = 'Status: ON'
elif stat == 2:
text = 'Status: OFF'
else:
text = 'Status: AUTO'
lcd.text(text, 2)
#print(text)
def buzzOn():
bz.on()
def buzzOff():
bz.off()
def ledOn():
led.on()
def ledOff():
led.off()
def powerOn():
power.on()
def powerOff():
power.off()
def sendSMS(phoneNo, msg):
message = client.api.account.messages.create(to=phoneNo,from_=twilio_hp,body=msg)
my_rpi = AWSIoTMQTTClient("Teh-OKosong-basicPubSub")
my_rpi.configureEndpoint(host, 8883)
my_rpi.configureCredentials(rootCAPath, privateKeyPath, certificatePath)
my_rpi.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing
my_rpi.configureDrainingFrequency(2) # Draining: 2 Hz
my_rpi.configureConnectDisconnectTimeout(10) # 10 sec
my_rpi.configureMQTTOperationTimeout(5) # 5 sec
# Connect
my_rpi.connect()
sleep(2)
print("Program starting...")
lcd.text("Smart Table",1)
while True:
now = datetime.now()
minutes = now.minute
seconds = now.second
print (seconds)
value = ser.readline()
if not re.match('^\s+$',value):
message = {}
print("RFID: "+value)
message["DeviceId"] = deviceId
message["timestamp"] = now.isoformat()
message["rfid"] = value
my_rpi.publish("tehokosong/rfidhist", json.dumps(message), 1)
booking = getBooking(now)
#No booking exist within 15min period
if not booking['Items']:
powerOn()
lcd.text("No Booking",1)
#Booking exist within 15min period, power on only if match
else:
userId = booking['Items'][0]['userId']
rfid = getRFID(userId)
name = getName(userId)
#Remove white space from both side
rfid = rfid.strip(' \t\n\r')
value = value.strip(' \t\n\r')
lcd.text("Now : "+str(name), 1)
#If RFID both match then on power
if(str(rfid) == str(value)):
powerOn()
else:
powerOff()
#Get latest state from DynamoDB
response = getState()
#Set latest state to current
stat = (response['Items'][0]['stat'])
lightThreshold = (response['Items'][0]['lightThreshold'])
soundThreshold = (response['Items'][0]['soundThreshold'])
#When button is press
if button.is_pressed:
print("Button Pressed")
if stat == 0:
stat = 1
elif stat == 1:
stat = 2
elif stat == 2:
stat = 0
#Update state to dynamodb
updateState(stat)
#Check state value
if stat == 2:
ledOff()
buzzOff()
powerOff()
elif stat == 1:
ledOn()
else:
light_value = light_adc.value*1024
sound_value = sound_adc.value*1024
print("Sound: "+str(sound_value)+" Light: "+str(light_value))
if(light_value > lightThreshold):
ledOn()
else:
ledOff()
if(sound_value > soundThreshold):
buzzOn()
lcd.text('Noise Level High', 2)
sleep(3)
buzzOff()
setStatusText(stat)
if minutes == 45 & textSent==0:
booking = getBooking(now)
if booking['Items']:
userId = booking['Items'][0]['userId']
name = getName(userId)
phone = getPhone(userId)
msg = "Hi "+name+", your booking is in 15 minutes time!"
sendSMS(phone, msg)
textSent = 1
lcd.text("Next: "+str(name), 1)
elif minutes == 00:
name = getName(userId)
lcd.text("Now : "+str(name), 1)
textSent = 0
# If no RFID tap within last 15 min
if not checkRFIDHist(now):
powerOff()
sleep(2)
Comments
Please log in or sign up to comment.