jasper
Published

JTTQE Smart Home

A smart home that is able to let user know about the status of their house and control it using IoT and cloud services.

ExpertProtip3 hours255
JTTQE Smart Home

Things used in this project

Hardware components

Raspberry Pi 3 Model B
Raspberry Pi 3 Model B
×2
Camera Module
Raspberry Pi Camera Module
×2
RFID reader (generic)
×2
PIR Motion Sensor (generic)
PIR Motion Sensor (generic)
×1
RGB Backlight LCD - 16x2
Adafruit RGB Backlight LCD - 16x2
×1
MCP3008
×1
Light Dependent Resistor
×1
Resistor 330 ohm
Resistor 330 ohm
×4
Resistor 10k ohm
Resistor 10k ohm
×2
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×1
DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1
Buzzer
Buzzer
×1
RFID Cards
×1

Software apps and online services

Raspbian
Raspberry Pi Raspbian
AWS DynamoDB
Amazon Web Services AWS DynamoDB
Telegram
MQTT
MQTT

Story

Read more

Custom parts and enclosures

Full tutorial

Schematics

Raspberry Pi 1 Setup

Raspberry Pi 2 Setup

How the webpage will look like

Code

pi1_one.py

Python
Python program that will run the sever for the web page and retrieve data from DynamoDB
from flask import Flask, render_template, jsonify, request, Response
from picam import Camera
from gpiozero import LED

app = Flask(__name__)

import dynamodb
import jsonconverter as jsonc
import boto3
import json
import decimal
import MFRC522
import time

light3 = LED(13) #green
light2 = LED(19) #yellow
light1 = LED(26) #red

@app.route("/api/switchRed",methods=['POST','GET'])
def switchRed():

    try:
        command = request.form["command"]

        if command == "on":
            light1.on()
            message = "Room light is turned on"
        else:
            light1.off()
            message = "Room light is turned off"
    except:
        message = "Error changing red"
        import sys
        print(sys.exc_info()[0])
        print(sys.exc_info()[1])

    data = {"message" : message}

    return jsonify(data)

@app.route("/api/switchYellow",methods=['POST','GET'])
def switchYellow():

    try:
        command = request.form["command"]

        if command == "on":
            light2.on()
            message = "Room light is on"
        else:
            light2.off()
            message = "Room light is off"
    except:
        message = "Error changing yellow"
        import sys
        print(sys.exc_info()[0])
        print(sys.exc_info()[1])

    data = {"message" : message}

    return jsonify(data)

@app.route("/api/switchGreen",methods=['POST','GET'])
def switchGreen():

    try:
        command = request.form["command"]

        if command == "on":
            light3.on()
            message = "Room light is on"
        else:
            light3.off()
            message = "Room light is off"
    except:
        message = "Error changing green"
        import sys
        print(sys.exc_info()[0])
        print(sys.exc_info()[1])

    data = {"message" : message}

    return jsonify(data)

#aws
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient

# Custom MQTT message callback
def customCallback(client, userdata, message):
	print("Received a new message: ")
	print(message.payload)
	print("from topic: ")
	print(message.topic)
	print("--------------\n\n")
	
host = "abpl27ba00qyj-ats.iot.us-west-2.amazonaws.com"
rootCAPath = "rootca.pem"
certificatePath = "certificate.pem.crt"
privateKeyPath = "private.pem.key"
    
my_rpi = AWSIoTMQTTClient("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 and subscribe to AWS IoT
my_rpi.connect()
my_rpi.subscribe("sensors/uid", 1, customCallback)
time.sleep(2)
# End AWS

def pubUid(uid, name):
	message={}
	message["deviceid"] = "pi"
	message["uid"] = uid
	message["name"] = name
	#import json
	my_rpi.publish("sensors/uid", json.dumps(message), 1)

def pubUserLog1(uid, name):
    message={}
    message["uid"] = uid
    message["name"] = name
    message["stat"] = "out"
    my_rpi.publish("sensors/uidLog", json.dumps(message), 1)

@app.route("/api/getdata",methods=['POST','GET'])
def apidata_getdata():
    if request.method == 'POST' or request.method == 'GET':
        try:
            data = {'chart_data': jsonc.data_to_json(dynamodb.get_data_from_dynamodb()), 'title': "IOT Data"}
            return jsonify(data)

        except:
            import sys
            print(sys.exc_info()[0])
            print(sys.exc_info()[1])
			
@app.route("/api/getdata2",methods=['POST','GET'])
def apidata_getdata2():
    if request.method == 'POST' or request.method == 'GET':
        try:
            dldata = {'chart_data': jsonc.data_to_json(dynamodb.get_data_from_dynamodb()), 'title': "IOT Data"}
            return jsonify(dldata)

        except:
            import sys
            print(sys.exc_info()[0])
            print(sys.exc_info()[1])
			
@app.route("/api/getdata3",methods=['POST','GET'])
def apidata_getdata3():
    if request.method == 'POST' or request.method == 'GET':
        try:
            actdata = {'chart_data': jsonc.data_to_json(dynamodb.get_data_from_dynamodb3()), 'title': "Act Data"}
            return jsonify(actdata)

        except:
            import sys
            print(sys.exc_info()[0])
            print(sys.exc_info()[1])

# Helper class to convert a DynamoDB item to JSON.
class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, decimal.Decimal):
            if o % 1 > 0:
                return float(o)
            else:
                return int(o)
        return super(DecimalEncoder, self).default(o)

@app.route("/api/currentTemp",methods=['POST','GET'])
def currentTemp():
    if request.method == 'POST' or request.method == 'GET':
        try:
            dynamodb = boto3.resource('dynamodb', region_name='us-west-2', aws_access_key_id="your key ", aws_secret_access_key="your key ")
            table = dynamodb.Table('JTTQE-temp')
            update = True
            while update:
	            # Table scan
	            global temp
	            response = table.scan()

	            for i in response['Items']: 
		            # get all the table entries in json format
		            json_str = json.dumps(i, cls=DecimalEncoder)
		            resp_dict = json.loads(json_str)
	
	            temp = resp_dict.get('temp')
	            return jsonify(temp)
        except:
            import sys
            print(sys.exc_info()[0])
            print(sys.exc_info()[1])

@app.route("/api/uid",methods=['POST','GET'])
def uid():

    try:
        # Create an object of the class MFRC522
        MIFAREReader = MFRC522.MFRC522()
        command = request.form["command"]
        update = True
        print("Please scan card")
        while update:
            #Scan card
            (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
            #Get card UID
            (status,uid) = MIFAREReader.MFRC522_Anticoll()
            #If UID detacted
            if status == MIFAREReader.MI_OK:
                print("UID of tapped card: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]))
                uid = str(uid[0]) + str(uid[1]) + str(uid[2]) + str(uid[3])
                pubUid(uid,command)
                pubUserLog1(uid, command)
                print(uid,command)
                break
    except:
        import sys
        print(sys.exc_info()[0])
        print(sys.exc_info()[1])

    data = {"message" : "Added"}

    return jsonify(data)
	
@app.route("/api/getImages",methods=['POST','GET'])
def getImages():
    if request.method == 'POST' or request.method == 'GET':
        try:
		s3 = boto3.resource('s3', aws_access_key_id="your key ", aws_secret_access_key="your key ")
		bucket_name = 'iot-ay1819s2'
		my_bucket = s3.Bucket(bucket_name)
		objs = my_bucket.objects.filter(Prefix ='home/1819s2_iot_JT-TQE/')
		url = []
		for obj in objs:
			if str(obj.key).find(".jpg") >= 0:
				url.append(obj.key)
		return jsonify(url)
        except:
            import sys
            print(sys.exc_info()[0])
            print(sys.exc_info()[1])

@app.route("/")
def home():
    return render_template("index.html")
	
def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(Camera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

app.run(debug=True,threaded=True,host="0.0.0.0")

pi1_two.py

Python
Python program that will allow the user to send commands to the Telegram bot which will then turn on and off the light in the house depedning on which light the user choose, this program will also turn on and off a light when the LDR senses low light and lastly it will also publish the temp of the DHT sensor
import telepot
import time
import datetime
import Adafruit_DHT
from gpiozero import LED, MCP3008

# Start AWS
# Import SDK packages
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient

# Custom MQTT message callback
def customCallback(client, userdata, message):
	print("Received a new message: ")
	print(message.payload)
	print("from topic: ")
	print(message.topic)
	print("--------------\n\n")
	
host = "abpl27ba00qyj-ats.iot.us-west-2.amazonaws.com"
rootCAPath = "rootca.pem"
certificatePath = "certificate.pem.crt"
privateKeyPath = "private.pem.key"
    
my_rpi = AWSIoTMQTTClient("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 and subscribe to AWS IoT
my_rpi.connect()
my_rpi.subscribe("sensors/temp", 1, customCallback)
time.sleep(2)
# End AWS

my_bot_token = '791169392:AAED_dJSbR1y2epLsinLUcSVU2vUThK4l0I'

led1 = LED(13)
led2 = LED(19)
led3 = LED(26)
mcp3008 = MCP3008(channel=0)
light1 = LED(6)

def getDateTime():
	currentDt = datetime.datetime.now()
	fCurrentDt = currentDt.strftime("%Y-%m-%d %I:%M:%S:%p")
	return fCurrentDt

def pubTemp(datetime, temp):
	message={}
	message["deviceid"] = "pi"
	message["datetime"] = datetime#.isoformat()
	message["temp"] = temp
	import json
	my_rpi.publish("sensors/temp", json.dumps(message), 1)

def onLED1():
   led1.on()
   return "Turning on Room 1 light"

def offLED1():
   led1.off()    
   return "Turning off Room 1 light"

def onLED2():
   led2.on()
   return "Turning on Room 2 light"

def offLED2():
   led2.off()
   return "Turning off Room 2 light"

def onLED3():
   led3.on()
   return "Turning on Room 3 light"

def offLED3():
   led3.off()
   return "Turning off Room 3 light"

def respondToMsg(msg):
    chat_id = msg['chat']['id']
    command = msg['text']

    print('Got command: {}'.format(command))

    if command.upper() == '/ONROOM1':
       bot.sendMessage(chat_id, onLED1())
    elif command.upper() =='/OFFROOM1':
       bot.sendMessage(chat_id, offLED1())
    elif command.upper() == '/ONROOM2':
       bot.sendMessage(chat_id, onLED2())
    elif command.upper() == '/OFFROOM2':
       bot.sendMessage(chat_id, offLED2())
    elif command.upper() == '/ONROOM3':
       bot.sendMessage(chat_id, onLED3())
    elif command.upper() == '/OFFROOM3':
       bot.sendMessage(chat_id, offLED3())

bot = telepot.Bot(my_bot_token)
bot.message_loop(respondToMsg)
print('Listening for RPi commands...')

while True:
   time.sleep(5)
   humidity, temperature = Adafruit_DHT.read_retry(11, 4)
   pubTemp(getDateTime(), temperature)
   sensor_value = (1024*mcp3008.value)
   sensor_value = round(sensor_value)
   if sensor_value > 700:
      light1.on()
   else:
      light1.off()

pi2_one.py

Python
Python program that will sense for motion using the motion sensor and when the sensor is triped the program will take a video and send it to the user’s Telegram and also publish a mqtt message
import dynamodb
import jsonconverter as jsonc
import time
import datetime
import decimal
import gevent
import gevent.monkey
import os
import sys
import json
import numpy
import telepot
from subprocess import call
from picamera import PiCamera
from gevent.pywsgi import WSGIServer
from gpiozero import MotionSensor, LED
from rpi_lcd import LCD

# Declarations
pir = MotionSensor(17, sample_rate=5, queue_len=1)
led = LED(6)

# Start AWS
# Import SDK packages
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient

# Custom MQTT message callback
def customCallback(client, userdata, message):
	print("Received a new message: ")
	print(message.payload)
	print("from topic: ")
	print(message.topic)
	print("--------------\n\n")
	
host = "abpl27ba00qyj-ats.iot.us-west-2.amazonaws.com"
rootCAPath = "rootca.pem"
certificatePath = "certificate.pem.crt"
privateKeyPath = "private.pem.key"
    
my_rpi = AWSIoTMQTTClient("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 and subscribe to AWS IoT
my_rpi.connect()
my_rpi.subscribe("sensors/trip", 1, customCallback)
time.sleep(2)
# End AWS

def getTime():
	currentDt = datetime.datetime.now()
	fCurrentDt = currentDt.strftime("%I:%M:%S %p")
	return fCurrentDt
	
def getDate():
	currentDt = datetime.datetime.now()
	fCurrentDt = currentDt.strftime("%Y-%m-%d")
	return fCurrentDt

def pubTrip(time, date):
	message={}
	message["deviceid"] = "pi"
	message["time"] = time
	message["date"] = date
	message["trip"] = "1"
	import json
	my_rpi.publish("sensors/trip", json.dumps(message), 1)

def teleVid(): # Send video captured from pi cam to telegram
    
    print("Recording Vid")
    camera = PiCamera()
    camera.resolution = (640, 480)
    time.sleep(5)
    camera.start_recording('/home/pi/Desktop/video1.h264')
    camera.wait_recording(8)
    camera.stop_recording()
    command = "MP4Box -add /home/pi/Desktop/video1.h264 /home/pi/Desktop/out.mp4"
    call([command], shell=True)
    my_bot_token = '791169392:AAED_dJSbR1y2epLsinLUcSVU2vUThK4l0I'
    bot = telepot.Bot(my_bot_token)
    bot.sendMessage('130237501', "Motion detected, sending video!")
    #bot.sendMessage('314361200', "Motion detected")
    bot.sendVideo(chat_id=130237501, video=open('/home/pi/Desktop/out.mp4', 'rb'))
    #bot.sendVideo(chat_id=314361200, video=open('/home/pi/Desktop/out.mp4', 'rb'))
    os.remove("/home/pi/Desktop/out.mp4")
    camera.close()
    print("Video sent")

# Start of Motion Recording System
def ledOn():
    #led.on()
    global ledStat
    ledStat = 1
    while (ledStat < 2):
        pir.wait_for_motion()
        if ledStat > 1:
            #led.off()
            break
        timestring = time.strftime("%d-%m-%Y_%H:%M:%S", time.localtime())
        datenow = datetime.datetime.today().strftime('%Y-%m-%d')
        timenow = time.strftime("%H:%M:%S", time.localtime())
        trip = str(1)
        print("Motion detected, recording video at "+timestring)
        # Begin storing values to MQTT
        try:
            print("Debug 1:", datenow)
            print("Debug 2:", timenow)
            print("Debug 3:", trip)
            pubTrip(getTime(), getDate()) #publish trip to AWS MQTT
            teleVid()
        except:
            print("Error while inserting data...")
            print(sys.exc_info()[0])
            print(sys.exc_info()[1])
        # End storing values to MQTT
        print("Recording completed, waiting for motion")
        time.sleep(5)
        continue
    return
	
ledOn()

pi2_two.py

Python
Python program that will sense for motion using the motion sensor and when the sensor is triped the program will take a video and send it to the user’s Telegram and also publish a mqtt message
import boto3
import botocore
import json
import decimal
import MFRC522
import time
import telepot
import os
import datetime
from picamera import PiCamera
from gpiozero import Button, Buzzer
from rpi_lcd import LCD
from signal import pause
from boto3.dynamodb.conditions import Key, Attr

lcd = LCD()
button = Button(21)
bz = Buzzer(18)
# Image uploading
# Create an S3 resource
s3 = boto3.resource('s3')

# Start AWS
# Import SDK packages
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient

# Custom MQTT message callback
def customCallback(client, userdata, message):
	print("Received a new message: ")
	print(message.payload)
	print("from topic: ")
	print(message.topic)
	print("--------------\n\n")
	
host = "abpl27ba00qyj-ats.iot.us-west-2.amazonaws.com"
rootCAPath = "rootca.pem"
certificatePath = "certificate.pem.crt"
privateKeyPath = "private.pem.key"
    
my_rpi = AWSIoTMQTTClient("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 and subscribe to AWS IoT
my_rpi.connect()
time.sleep(2)
# End AWS Image uploading

# Set the filename and bucket name
s3 = boto3.resource('s3',
     aws_access_key_id='your key ',
     aws_secret_access_key='your key ')

bucket_name = 'iot-ay1819s2'
exists = True

try:
    s3.meta.client.head_bucket(Bucket=bucket_name)
except botocore.exceptions.ClientError as e:
    error_code = int(e.response['Error']['Code'])
    if error_code == 404:
        exists = False

if exists == False:
  s3.create_bucket(Bucket=bucket_name,CreateBucketConfiguration={
    'LocationConstraint': 'us-west-2'})

def beep1():
    bz.on()
    time.sleep(0.3)
    bz.off()

def beep2():
    bz.on()
    time.sleep(0.3)
    bz.off()
    time.sleep(0.1)
    bz.on()
    time.sleep(0.3)
    bz.off()

def beep3():
    bz.on()
    time.sleep(0.3)
    bz.off()
    time.sleep(0.1)
    bz.on()
    time.sleep(0.3)
    bz.off()
    time.sleep(0.1)
    bz.on()
    time.sleep(0.3)
    bz.off()

def displayLcd(line1, line2):
    lcd.text(line1, 1)
    lcd.text(line2, 2)

def displayLcdC(line1, line2):
    lcd.text(line1, 1)
    lcd.text(line2, 2)
    time.sleep(5)
    lcd.clear()

def telePic(): #  Send image captured from pi cam to telegram

    camera = PiCamera()
    print("Tele bot sending pic")
    my_bot_token = '791169392:AAED_dJSbR1y2epLsinLUcSVU2vUThK4l0I'
    bot = telepot.Bot(my_bot_token)
    #Take pic and upload to S3
    time1 = datetime.datetime.now()
    fileName = time1.strftime("%y%m%d_%H-%M-%S") + '.jpg'
    full_path = "/home/pi/Desktop/pic/{}".format(fileName)
    camera.capture(full_path)
    time.sleep(3)
    camera.close()
    print("Uploading to S3 / Telegram")
    bot.sendPhoto(chat_id=130237501, photo=open(full_path, 'rb'))
    s3.Object(bucket_name, 'home/1819s2_iot_JT-TQE/'+fileName).put(Body=open(full_path, 'rb'),ACL='public-read')
    #bot.sendPhoto(chat_id=314361200, photo=open('/home/pi/Desktop/image1.jpg', 'rb'))
    print("Uploaded to S3 / Telegram")


def teleText(text): #  Send text from pi to telegram
    print("Tele bot sending text")
    my_bot_token = '791169392:AAED_dJSbR1y2epLsinLUcSVU2vUThK4l0I'
    bot = telepot.Bot(my_bot_token)
    bot.sendMessage('130237501', text)
    #bot.sendMessage('314361200', text)
    print("Message sent")
    

# Helper class to convert a DynamoDB item to JSON.
class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, decimal.Decimal):
            if o % 1 > 0:
                return float(o)
            else:
                return int(o)
        return super(DecimalEncoder, self).default(o)

dynamodb = boto3.resource('dynamodb', region_name='us-west-2', aws_access_key_id="your key ", aws_secret_access_key="your key ")

table = dynamodb.Table('JTTQE-RfidUserLog')

print("waiting for press")
displayLcd("Kindly press","button to scan")
def updateUid():
    print("Starting")
    displayLcd("Please scan card","")
    global uid
    nameList = []
    nameList2 = []
    update = True
    while update:
        #Scan uid
        MIFAREReader = MFRC522.MFRC522()
        (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
        (status,uid) = MIFAREReader.MFRC522_Anticoll()
        if status == MIFAREReader.MI_OK:
            displayLcd("Scanning card","Please wait")
            print("UID of tapped card: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]))
            uid = str(uid[0]) + str(uid[1]) + str(uid[2]) + str(uid[3])
            time.sleep(2)
            #Scan table and put in nameList2
            response = table.scan()
            for i in response['Items']:
                nameList2.append(i['uid'])
                print(nameList2)
            #Check if tapped uid is inside db if inside update table if not inside reject
            if uid in nameList2:
                response = table.query(
                    KeyConditionExpression=Key('uid').eq(uid)
                )
        
                for i in response['Items']:
                    nameList.append(i['stat'])
                    print(nameList)
        
                    if 'out' in nameList:
                        response = table.update_item(
                            Key={
                                'uid': uid
                            },
                            UpdateExpression="set stat = :r",
                            ExpressionAttributeValues={
                                ':r': 'in',
                            },
                            ReturnValues="UPDATED_NEW"
                        )
                        nameList = []
                        update = False
                        beep1()
                        displayLcdC("Welcome Home :)","")
                        displayLcd("Kindly press","button to scan")
                        print("Updated to in")
                    else:
                        response = table.update_item(
                            Key={
                                'uid': uid
                            },
                            UpdateExpression="set stat = :r",
                            ExpressionAttributeValues={
                                ':r': 'out',
                            },
                            ReturnValues="UPDATED_NEW"
                        )
                        nameList = []
                        update = False
                        beep2()
                        displayLcdC("Goodbye :)","")
                        displayLcd("Kindly press","button to scan")
                        print("Updated to out")
            else:
                print("Card not in db")
                update = False
                beep3()
                teleText("Unauthorized card tapped, sending picture!")
                telePic()
                displayLcdC("Unauthorize User","")
                displayLcd("Kindly press","button to scan")

#Press button to start scanning
button.when_pressed = updateUid
pause()
            

MFRC522.py

Python
Supporting files
#!/usr/bin/env python
# -*- coding: utf8 -*-
#
#    Copyright 2014,2018 Mario Gomez <mario.gomez@teubi.co>
#
#    This file is part of MFRC522-Python
#    MFRC522-Python is a simple Python implementation for
#    the MFRC522 NFC Card Reader for the Raspberry Pi.
#
#    MFRC522-Python is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Lesser General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    MFRC522-Python is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Lesser General Public License for more details.
#
#    You should have received a copy of the GNU Lesser General Public License
#    along with MFRC522-Python.  If not, see <http://www.gnu.org/licenses/>.
#

import RPi.GPIO as GPIO
import spi
import signal
import time
  
class MFRC522:
  NRSTPD = 22
  
  MAX_LEN = 16
  
  PCD_IDLE       = 0x00
  PCD_AUTHENT    = 0x0E
  PCD_RECEIVE    = 0x08
  PCD_TRANSMIT   = 0x04
  PCD_TRANSCEIVE = 0x0C
  PCD_RESETPHASE = 0x0F
  PCD_CALCCRC    = 0x03
  
  PICC_REQIDL    = 0x26
  PICC_REQALL    = 0x52
  PICC_ANTICOLL  = 0x93
  PICC_SElECTTAG = 0x93
  PICC_AUTHENT1A = 0x60
  PICC_AUTHENT1B = 0x61
  PICC_READ      = 0x30
  PICC_WRITE     = 0xA0
  PICC_DECREMENT = 0xC0
  PICC_INCREMENT = 0xC1
  PICC_RESTORE   = 0xC2
  PICC_TRANSFER  = 0xB0
  PICC_HALT      = 0x50
  
  MI_OK       = 0
  MI_NOTAGERR = 1
  MI_ERR      = 2
  
  Reserved00     = 0x00
  CommandReg     = 0x01
  CommIEnReg     = 0x02
  DivlEnReg      = 0x03
  CommIrqReg     = 0x04
  DivIrqReg      = 0x05
  ErrorReg       = 0x06
  Status1Reg     = 0x07
  Status2Reg     = 0x08
  FIFODataReg    = 0x09
  FIFOLevelReg   = 0x0A
  WaterLevelReg  = 0x0B
  ControlReg     = 0x0C
  BitFramingReg  = 0x0D
  CollReg        = 0x0E
  Reserved01     = 0x0F
  
  Reserved10     = 0x10
  ModeReg        = 0x11
  TxModeReg      = 0x12
  RxModeReg      = 0x13
  TxControlReg   = 0x14
  TxAutoReg      = 0x15
  TxSelReg       = 0x16
  RxSelReg       = 0x17
  RxThresholdReg = 0x18
  DemodReg       = 0x19
  Reserved11     = 0x1A
  Reserved12     = 0x1B
  MifareReg      = 0x1C
  Reserved13     = 0x1D
  Reserved14     = 0x1E
  SerialSpeedReg = 0x1F
  
  Reserved20        = 0x20  
  CRCResultRegM     = 0x21
  CRCResultRegL     = 0x22
  Reserved21        = 0x23
  ModWidthReg       = 0x24
  Reserved22        = 0x25
  RFCfgReg          = 0x26
  GsNReg            = 0x27
  CWGsPReg          = 0x28
  ModGsPReg         = 0x29
  TModeReg          = 0x2A
  TPrescalerReg     = 0x2B
  TReloadRegH       = 0x2C
  TReloadRegL       = 0x2D
  TCounterValueRegH = 0x2E
  TCounterValueRegL = 0x2F
  
  Reserved30      = 0x30
  TestSel1Reg     = 0x31
  TestSel2Reg     = 0x32
  TestPinEnReg    = 0x33
  TestPinValueReg = 0x34
  TestBusReg      = 0x35
  AutoTestReg     = 0x36
  VersionReg      = 0x37
  AnalogTestReg   = 0x38
  TestDAC1Reg     = 0x39
  TestDAC2Reg     = 0x3A
  TestADCReg      = 0x3B
  Reserved31      = 0x3C
  Reserved32      = 0x3D
  Reserved33      = 0x3E
  Reserved34      = 0x3F
    
  serNum = []
  
  def __init__(self, dev='/dev/spidev0.1', spd=1000000):
    spi.openSPI(device=dev,speed=spd)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(self.NRSTPD, GPIO.OUT)
    GPIO.output(self.NRSTPD, 1)
    self.MFRC522_Init()
  
  def MFRC522_Reset(self):
    self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)
  
  def Write_MFRC522(self, addr, val):
    spi.transfer(((addr<<1)&0x7E,val))
  
  def Read_MFRC522(self, addr):
    val = spi.transfer((((addr<<1)&0x7E) | 0x80,0))
    return val[1]
  
  def SetBitMask(self, reg, mask):
    tmp = self.Read_MFRC522(reg)
    self.Write_MFRC522(reg, tmp | mask)
    
  def ClearBitMask(self, reg, mask):
    tmp = self.Read_MFRC522(reg);
    self.Write_MFRC522(reg, tmp & (~mask))
  
  def AntennaOn(self):
    temp = self.Read_MFRC522(self.TxControlReg)
    if(~(temp & 0x03)):
      self.SetBitMask(self.TxControlReg, 0x03)
  
  def AntennaOff(self):
    self.ClearBitMask(self.TxControlReg, 0x03)
  
  def MFRC522_ToCard(self,command,sendData):
    backData = []
    backLen = 0
    status = self.MI_ERR
    irqEn = 0x00
    waitIRq = 0x00
    lastBits = None
    n = 0
    i = 0
    
    if command == self.PCD_AUTHENT:
      irqEn = 0x12
      waitIRq = 0x10
    if command == self.PCD_TRANSCEIVE:
      irqEn = 0x77
      waitIRq = 0x30
    
    self.Write_MFRC522(self.CommIEnReg, irqEn|0x80)
    self.ClearBitMask(self.CommIrqReg, 0x80)
    self.SetBitMask(self.FIFOLevelReg, 0x80)
    
    self.Write_MFRC522(self.CommandReg, self.PCD_IDLE);  
    
    while(i<len(sendData)):
      self.Write_MFRC522(self.FIFODataReg, sendData[i])
      i = i+1
    
    self.Write_MFRC522(self.CommandReg, command)
      
    if command == self.PCD_TRANSCEIVE:
      self.SetBitMask(self.BitFramingReg, 0x80)
    
    i = 2000
    while True:
      n = self.Read_MFRC522(self.CommIrqReg)
      i = i - 1
      if ~((i!=0) and ~(n&0x01) and ~(n&waitIRq)):
        break
    
    self.ClearBitMask(self.BitFramingReg, 0x80)
  
    if i != 0:
      if (self.Read_MFRC522(self.ErrorReg) & 0x1B)==0x00:
        status = self.MI_OK

        if n & irqEn & 0x01:
          status = self.MI_NOTAGERR
      
        if command == self.PCD_TRANSCEIVE:
          n = self.Read_MFRC522(self.FIFOLevelReg)
          lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
          if lastBits != 0:
            backLen = (n-1)*8 + lastBits
          else:
            backLen = n*8
          
          if n == 0:
            n = 1
          if n > self.MAX_LEN:
            n = self.MAX_LEN
    
          i = 0
          while i<n:
            backData.append(self.Read_MFRC522(self.FIFODataReg))
            i = i + 1;
      else:
        status = self.MI_ERR

    return (status,backData,backLen)
  
  
  def MFRC522_Request(self, reqMode):
    status = None
    backBits = None
    TagType = []
    
    self.Write_MFRC522(self.BitFramingReg, 0x07)
    
    TagType.append(reqMode);
    (status,backData,backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, TagType)
  
    if ((status != self.MI_OK) | (backBits != 0x10)):
      status = self.MI_ERR
      
    return (status,backBits)
  
  
  def MFRC522_Anticoll(self):
    backData = []
    serNumCheck = 0
    
    serNum = []
  
    self.Write_MFRC522(self.BitFramingReg, 0x00)
    
    serNum.append(self.PICC_ANTICOLL)
    serNum.append(0x20)
    
    (status,backData,backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE,serNum)
    
    if(status == self.MI_OK):
      i = 0
      if len(backData)==5:
        while i<4:
          serNumCheck = serNumCheck ^ backData[i]
          i = i + 1
        if serNumCheck != backData[i]:
          status = self.MI_ERR
      else:
        status = self.MI_ERR
  
    return (status,backData)
  
  def CalulateCRC(self, pIndata):
    self.ClearBitMask(self.DivIrqReg, 0x04)
    self.SetBitMask(self.FIFOLevelReg, 0x80);
    i = 0
    while i<len(pIndata):
      self.Write_MFRC522(self.FIFODataReg, pIndata[i])
      i = i + 1
    self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
    i = 0xFF
    while True:
      n = self.Read_MFRC522(self.DivIrqReg)
      i = i - 1
      if not ((i != 0) and not (n&0x04)):
        break
    pOutData = []
    pOutData.append(self.Read_MFRC522(self.CRCResultRegL))
    pOutData.append(self.Read_MFRC522(self.CRCResultRegM))
    return pOutData
  
  def MFRC522_SelectTag(self, serNum):
    backData = []
    buf = []
    buf.append(self.PICC_SElECTTAG)
    buf.append(0x70)
    i = 0
    while i<5:
      buf.append(serNum[i])
      i = i + 1
    pOut = self.CalulateCRC(buf)
    buf.append(pOut[0])
    buf.append(pOut[1])
    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
    
    if (status == self.MI_OK) and (backLen == 0x18):
      print "Size: " + str(backData[0])
      return    backData[0]
    else:
      return 0
  
  def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum):
    buff = []

    # First byte should be the authMode (A or B)
    buff.append(authMode)

    # Second byte is the trailerBlock (usually 7)
    buff.append(BlockAddr)

    # Now we need to append the authKey which usually is 6 bytes of 0xFF
    i = 0
    while(i < len(Sectorkey)):
      buff.append(Sectorkey[i])
      i = i + 1
    i = 0

    # Next we append the first 4 bytes of the UID
    while(i < 4):
      buff.append(serNum[i])
      i = i +1

    # Now we start the authentication itself
    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT,buff)

    # Check if an error occurred
    if not(status == self.MI_OK):
      print "AUTH ERROR!!"
    if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:
      print "AUTH ERROR(status2reg & 0x08) != 0"

    # Return the status
    return status
  
  def MFRC522_StopCrypto1(self):
    self.ClearBitMask(self.Status2Reg, 0x08)

  def MFRC522_Read(self, blockAddr):
    recvData = []
    recvData.append(self.PICC_READ)
    recvData.append(blockAddr)
    pOut = self.CalulateCRC(recvData)
    recvData.append(pOut[0])
    recvData.append(pOut[1])
    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData)
    if not(status == self.MI_OK):
      print "Error while reading!"
    i = 0
    if len(backData) == 16:
      print "Sector "+str(blockAddr)+" "+str(backData)
  
  def MFRC522_Write(self, blockAddr, writeData):
    buff = []
    buff.append(self.PICC_WRITE)
    buff.append(blockAddr)
    crc = self.CalulateCRC(buff)
    buff.append(crc[0])
    buff.append(crc[1])
    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff)
    if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A):
        status = self.MI_ERR
    
    print "%s backdata &0x0F == 0x0A %s" % (backLen, backData[0]&0x0F)
    if status == self.MI_OK:
        i = 0
        buf = []
        while i < 16:
            buf.append(writeData[i])
            i = i + 1
        crc = self.CalulateCRC(buf)
        buf.append(crc[0])
        buf.append(crc[1])
        (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE,buf)
        if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A):
            print "Error while writing"
        if status == self.MI_OK:
            print "Data written"

  def MFRC522_DumpClassic1K(self, key, uid):
    i = 0
    while i < 64:
        status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid)
        # Check if authenticated
        if status == self.MI_OK:
            self.MFRC522_Read(i)
        else:
            print "Authentication error"
        i = i+1

  def MFRC522_Init(self):
    GPIO.output(self.NRSTPD, 1)
  
    self.MFRC522_Reset();
    
    
    self.Write_MFRC522(self.TModeReg, 0x8D)
    self.Write_MFRC522(self.TPrescalerReg, 0x3E)
    self.Write_MFRC522(self.TReloadRegL, 30)
    self.Write_MFRC522(self.TReloadRegH, 0)
    
    self.Write_MFRC522(self.TxAutoReg, 0x40)
    self.Write_MFRC522(self.ModeReg, 0x3D)
    self.AntennaOn()

picam.py

Python
Supporting files
import io
import time
import picamera
from base_camera import BaseCamera


class Camera(BaseCamera):
    @staticmethod
    def frames():
        with picamera.PiCamera() as camera:
            # let camera warm up
            time.sleep(2)

            stream = io.BytesIO()
            for _ in camera.capture_continuous(stream, 'jpeg',
                                                 use_video_port=True):
                # return current frame
                stream.seek(0)
                yield stream.read()

                # reset stream for next frame
                stream.seek(0)
                stream.truncate()

base_camera.py

Python
Supporting files
import time
import threading
try:
    from greenlet import getcurrent as get_ident
except ImportError:
    try:
        from thread import get_ident
    except ImportError:
        from _thread import get_ident


class CameraEvent(object):
    """An Event-like class that signals all active clients when a new frame is
    available.
    """
    def __init__(self):
        self.events = {}

    def wait(self):
        """Invoked from each client's thread to wait for the next frame."""
        ident = get_ident()
        if ident not in self.events:
            # this is a new client
            # add an entry for it in the self.events dict
            # each entry has two elements, a threading.Event() and a timestamp
            self.events[ident] = [threading.Event(), time.time()]
        return self.events[ident][0].wait()

    def set(self):
        """Invoked by the camera thread when a new frame is available."""
        now = time.time()
        remove = None
        for ident, event in self.events.items():
            if not event[0].isSet():
                # if this client's event is not set, then set it
                # also update the last set timestamp to now
                event[0].set()
                event[1] = now
            else:
                # if the client's event is already set, it means the client
                # did not process a previous frame
                # if the event stays set for more than 5 seconds, then assume
                # the client is gone and remove it
                if now - event[1] > 5:
                    remove = ident
        if remove:
            del self.events[remove]

    def clear(self):
        """Invoked from each client's thread after a frame was processed."""
        self.events[get_ident()][0].clear()


class BaseCamera(object):
    thread = None  # background thread that reads frames from camera
    frame = None  # current frame is stored here by background thread
    last_access = 0  # time of last client access to the camera
    event = CameraEvent()

    def __init__(self):
        """Start the background camera thread if it isn't running yet."""
        if BaseCamera.thread is None:
            BaseCamera.last_access = time.time()

            # start background frame thread
            BaseCamera.thread = threading.Thread(target=self._thread)
            BaseCamera.thread.start()

            # wait until frames are available
            while self.get_frame() is None:
                time.sleep(0)

    def get_frame(self):
        """Return the current camera frame."""
        BaseCamera.last_access = time.time()

        # wait for a signal from the camera thread
        BaseCamera.event.wait()
        BaseCamera.event.clear()

        return BaseCamera.frame

    @staticmethod
    def frames():
        """"Generator that returns frames from the camera."""
        raise RuntimeError('Must be implemented by subclasses.')

    @classmethod
    def _thread(cls):
        """Camera background thread."""
        print('Starting camera thread.')
        frames_iterator = cls.frames()
        for frame in frames_iterator:
            BaseCamera.frame = frame
            BaseCamera.event.set()  # send signal to clients
            time.sleep(0)

            # if there hasn't been any clients asking for frames in
            # the last 10 seconds then stop the thread
            if time.time() - BaseCamera.last_access > 10:
                frames_iterator.close()
                print('Stopping camera thread due to inactivity.')
                break
        BaseCamera.thread = None

dynamodb.py

Python
Supporting files
def get_data_from_dynamodb():

	try :
			import boto3
			from boto3.dynamodb.conditions import Key, Attr
			
			dynamodb = boto3.resource('dynamodb', region_name='us-west-2', aws_access_key_id="your key", aws_secret_access_key="your key")
			table = dynamodb.Table('JTTQE-trip')
			
			#Get all data in table
			response = table.scan()
			
			items = response['Items']
			
			return items
	except:
		import sys
        print(sys.exc_info()[0])
        print(sys.exc_info()[1])

def get_data_from_dynamodb2():

	try :
			import boto3
			import json
			from boto3.dynamodb.conditions import Key, Attr
			
			dynamodb = boto3.resource('dynamodb', region_name='us-west-2', aws_access_key_id="your key", aws_secret_access_key="your key ")
			table = dynamodb.Table('JTTQE-temp')
			update = True
			while update:
				# Table scan
				global temp
				response = table.scan()
				
				items = response['Items']
					
				#temp = items.get('temp')
				return items
	except:
		import sys
        print(sys.exc_info()[0])
        print(sys.exc_info()[1])
		
def get_data_from_dynamodb3():

	try :
			import boto3
			from boto3.dynamodb.conditions import Key, Attr
			
			dynamodb = boto3.resource('dynamodb', region_name='us-west-2', aws_access_key_id="your key", aws_secret_access_key="your key ")
			table = dynamodb.Table('JTTQE-RfidUserLog')
			#Get all data in table
			response = table.scan()
			
			items = response['Items']
			
			return items
	except:
		import sys
        print(sys.exc_info()[0])
        print(sys.exc_info()[1])


		
if __name__ == "__main__":
    query_data_from_dynamodb()

jsonconverter.py

Python
Supporting Files
from decimal import Decimal
import json
import datetime
import numpy

class GenericEncoder(json.JSONEncoder):

	def default(self, obj):
		if isinstance(obj, numpy.generic):
			return numpy.asscalar(obj)
		elif isinstance(obj, Decimal):
			return str(obj)
		elif isinstance(obj, datetime.date):
			return obj.strftime('%Y-%m-%d')
		elif isinstance(obj, datetime.time):
			return obj.strftime('%I:%M:%S %p')
		elif isinstance(obj, datetime.datetime):
			return obj.strftime('%Y-%m-%d %I:%M:%S %p')
		elif isinstance(obj, Decimal):
			if obj % 1 > 0:
				return float(obj)
			else:
				return int(obj)
		else:
			return json.JSONEncoder.default(self, obj)
			
def data_to_json(data):
    json_data = json.dumps(data,cls=GenericEncoder)
    #print(json_data)
    return json_data
	
def data_to_jsoni(data):
	json_data = json.dumps(data,cls=GenericEncoder)
	resp_dict = json.loads(json_data)
	return resp_dict

index.html

HTML
Webpages
<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>JTTQE Smart Home - Dashboard</title>

  <!-- Custom fonts for this template-->
  <link href="../static/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">

  <!-- Custom styles for this template-->
  <link href="../static/css/sb-admin-2.min.css" rel="stylesheet">

  <!-- Bootstrap core JavaScript-->
  <script src="../static/vendor/jquery/jquery.min.js"></script>
  <script src="../static/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
  
  <!-- Google chart JavaScript-->
  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  <script type="text/javascript" src="../static/js/gchart.js"></script>
  
  <!-- Export SQL JavaScript-->
  <script type="text/javascript" src="../static/js/exporttoexcel.js"></script>
  
  <!-- Page level custom scripts -->
  <script type="text/javascript" src="../static/js/app.js"></script>

</head>

<body id="page-top">

  <!-- Page Wrapper -->
  <div id="wrapper">

    <!-- Sidebar -->
    <ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">

      <!-- Sidebar - Brand -->
      <a class="sidebar-brand d-flex align-items-center justify-content-center" href="/#"">
        <div class="sidebar-brand-icon rotate-n-15">
          <i class="fas fa-laugh-wink"></i>
        </div>
        <div class="sidebar-brand-text mx-3">JQTTQE Smart Home</div>
      </a>

      <!-- Divider -->
      <hr class="sidebar-divider my-0">

      <!-- Nav Item - Dashboard -->
      <li class="nav-item active">
        <a class="nav-link" href="/#">
          <i class="fas fa-fw fa-tachometer-alt"></i>
          <span>Dashboard</span></a>
      </li>

      <!-- Divider -->
      <hr class="sidebar-divider">

      <!-- Heading -->
      <div class="sidebar-heading">
        Interface
      </div>

      <!-- Nav Item - Modules Collapse Menu -->
      <li class="nav-item">
        <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
          <i class="fas fa-fw fa-cog"></i>
          <span>Modules</span>
        </a>
        <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionSidebar">
          <div class="bg-white py-2 collapse-inner rounded">
            <h6 class="collapse-header">Add Module:</h6>
            <a class="collapse-item" href="#" id="addLight">Lights</a>
			<a class="collapse-item" href="#" data-toggle="modal" data-target="#logoutModal">RFID Cards</a>
          </div>
        </div>
      </li>
	  
	  <!-- Nav Item - Images Collapse Menu -->
      <li class="nav-item">
        <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapsePages" aria-expanded="true" aria-controls="collapsePages">
          <i class="fas fa-fw fa-folder"></i>
          <span>Images</span>
        </a>
        <div id="collapsePages" class="collapse" aria-labelledby="headingPages" data-parent="#accordionSidebar">
          <div class="bg-white py-2 collapse-inner rounded">
            <h6 class="collapse-header">View:</h6>
            <a class="collapse-item" href="static/img.html">Images</a>
          </div>
        </div>
      </li>

      <!-- Divider -->
      <hr class="sidebar-divider">

      <!-- Sidebar Toggler (Sidebar) -->
      <div class="text-center d-none d-md-inline">
        <button class="rounded-circle border-0" id="sidebarToggle"></button>
      </div>

    </ul>
    <!-- End of Sidebar -->

    <!-- Content Wrapper -->
    <div id="content-wrapper" class="d-flex flex-column">

      <!-- Main Content -->
      <div id="content">

        <!-- Topbar -->
        <nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">

          <!-- Sidebar Toggle (Topbar) -->
          <button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
            <i class="fa fa-bars"></i>
          </button>

          <!-- Topbar Search -->
          <form class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
            <div class="input-group">
              <input type="text" id="txtSearch" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
              <div class="input-group-append">
                <button class="btn btn-primary" type="button" onclick="searchFunc()">
                  <i class="fas fa-search fa-sm"></i>
                </button>
              </div>
            </div>
          </form>

          <!-- Topbar Navbar -->
          <ul class="navbar-nav ml-auto">

            <!-- Nav Item - Search Dropdown (Visible Only XS) -->
            <li class="nav-item dropdown no-arrow d-sm-none">
              <a class="nav-link dropdown-toggle" href="#" id="searchDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <i class="fas fa-search fa-fw"></i>
              </a>
              <!-- Dropdown - Messages -->
              <div class="dropdown-menu dropdown-menu-right p-3 shadow animated--grow-in" aria-labelledby="searchDropdown">
                <form class="form-inline mr-auto w-100 navbar-search">
                  <div class="input-group">
                    <input type="text" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
                    <div class="input-group-append">
                      <button class="btn btn-primary" type="button">
                        <i class="fas fa-search fa-sm"></i>
                      </button>
                    </div>
                  </div>
                </form>
              </div>
            </li>

            <div class="topbar-divider d-none d-sm-block"></div>

            <!-- Nav Item - User Information -->
            <li class="nav-item dropdown no-arrow">
              <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <span class="mr-2 d-none d-lg-inline text-gray-600 small">
					Sarah Tan
				</span>
                <img class="img-profile rounded-circle" src="https://source.unsplash.com/QAB-WJcbgJk/60x60">
              </a>
            </li>

          </ul>

        </nav>
        <!-- End of Topbar -->

        <!-- Begin Page Content -->
        <div class="container-fluid">

          <!-- Page Heading -->
          <div class="d-sm-flex align-items-center justify-content-between mb-4">
            <h1 class="h3 mb-0 text-gray-800">Dashboard</h1>
            <a id="downloadAnchorElem" onclick="loadDL()" href="#" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="fas fa-download fa-sm text-white-50"></i> Generate Report</a>
          </div>

          <!-- Content Row -->
          <div class="row">

            <!-- Current Temperature -->
            <div class="col-xl-3 col-md-6 mb-4" id="divTemp">
              <div class="card border-left-primary shadow h-100 py-2">
                <div class="card-body">
                  <div class="row no-gutters align-items-center">
                    <div class="col mr-2">
                      <div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Temperature</div>
                      <div class="mb-0">
                        <div id="currentTemp">Loading temperature..  </div>
						<div class="progress progress-sm mr-2">
                            <div id="tempbar" class="progress-bar bg-primary" role="progressbar" style="width: 0%"></div>
                        </div>
					  </div>
                    </div>
                    <div class="col-auto">
						<img id="tempPic" src="static/img/cloud.png" />
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- Light 1 -->
            <div class="col-xl-3 col-md-6 mb-4" id="divLight1">
              <div class="card border-left-success shadow h-100 py-2">
                <div class="card-body">
                  <div class="row no-gutters align-items-center">
                    <div class="col mr-2">
                      <div class="text-xs font-weight-bold text-success text-uppercase mb-1">Light 1</div>
                      <div class="mb-0">
                        <div id="message2">Room light is off</div>
                        <button class="btn btn-primary" onclick="switchGreen('on');greenOn();">ON</button>
                        <button class="btn btn-secondary" onclick="switchGreen('off');greenOff();">OFF</button>
					  </div>
                    </div>
                    <div class="col-auto">
                      <img id="greenLed" src="static/img/led_green_off.png" />
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- Light 2 -->
            <div class="col-xl-3 col-md-6 mb-4" id="divLight2">
              <div class="card border-left-info shadow h-100 py-2">
                <div class="card-body">
                  <div class="row no-gutters align-items-center">
                    <div class="col mr-2">
                      <div class="text-xs font-weight-bold text-info text-uppercase mb-1">Light 2</div>
                        <div class="mb-0">
							<div id="message1">Room light is off</div>
								<button class="btn btn-primary" onclick="switchYellow('on');yellowOn();">ON</button>
								<button class="btn btn-secondary" onclick="switchYellow('off');yellowOff();">OFF</button>
						</div>
                    </div>
                    <div class="col-auto">
                      <img id="yellowLed" src="static/img/led_yellow_off.png" />
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- Light 3 -->
            <div id="lightfour" class="col-xl-3 col-md-6 mb-4">
              <div class="card border-left-warning shadow h-100 py-2">
                <div class="card-body">
                  <div class="row no-gutters align-items-center">
                    <div class="col mr-2">
                      <div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Light 3</div>
                      <div class="mb-0">
							<div id="message0">Room light is off</div>
								<button class="btn btn-primary" onclick="switchRed('on');redOn();">ON</button>
								<button class="btn btn-secondary" onclick="switchRed('off');redOff();">OFF</button>
						</div>
                    </div>
                    <div class="col-auto">
                      <img id="redLed" src="static/img/led_red_off.png" />
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- Content Row -->

          <div class="row">

            <!-- Trip Chart -->
            <div class="col-xl-8 col-lg-7" id="divGraph">
              <div class="card shadow mb-4">
                <!-- Card Header - Dropdown -->
                <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
                  <h6 class="m-0 font-weight-bold text-primary">Number of trips</h6>
                  <div class="dropdown no-arrow">
                    <a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                      <i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
                    </a>
                    <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
                      <div class="dropdown-header">Actions:</div>
                      <a class="dropdown-item" id="buttonloadchart" onclick="loadChart()" href="#">Refresh chart</a>
                    </div>
                  </div>
                </div>
                <!-- Card Body -->
                <div class="card-body">
                  <div class="chart-area pt-1 pb-1">
					<!-- Start Graph Chart -->
						<div id="status"></div>
						<div id="chart_div" style="width:100%"></div>
					<!-- End Graph Chart
                    <canvas id="myAreaChart"></canvas> -->
                  </div>
                </div>
              </div>
            </div>

            <!-- Table of information -->
            <div class="col-xl-4 col-lg-5" id="divTable">
              <div class="card shadow mb-4">
                <!-- Card Header - Dropdown -->
                <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
                  <h6 class="m-0 font-weight-bold text-primary">Table of information</h6>
                </div>
                <!-- Card Body -->
                <div class="card-body">
                  <div class="chart-pie pt-4 pb-2">
					<!-- Start Table -->
						<div id="table_div" style="width:100%"></div>
					<!-- End Table
                    <canvas id="myPieChart"></canvas> -->
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- Content Row -->
          <div class="row">

            <!-- Content Column -->
            <div class="col-lg-6 mb-4" id="divActivity">
              <!-- Recent Activity -->
              <div class="card shadow mb-4">
                <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
                  <h6 class="m-0 font-weight-bold text-primary">Recent Activities</h6>
				  <div class="dropdown no-arrow">
                    <a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                      <i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
                    </a>
                    <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
                      <div class="dropdown-header">Actions:</div>
                      <a class="dropdown-item" id="buttonloadchart" onclick="loadChart()" href="#">Refresh table</a>
                    </div>
                  </div>
                </div>
                <div class="card-body">
                  <!-- Start Table -->
						<div id="table2_div" style="width:100%"></div>
					<!-- End Table -->
                </div>
              </div>

            </div>
			
			<!-- Content Column -->
            <div class="col-lg-6 mb-4" id="divStream">
              <!-- Live Stream -->
              <div class="card shadow mb-4">
                <div class="card-header py-3">
                  <h6 class="m-0 font-weight-bold text-primary">Live Stream</h6>
                </div>
                <div class="card-body">
                  <img class="img-fluid px-3 px-sm-4 mt-3 mb-4" height="1200" width="800" src="{{ url_for('video_feed') }}">
                </div>
              </div>

            </div>
          </div>
        </div>
        <!-- /.container-fluid -->

      </div>
      <!-- End of Main Content -->

      <!-- Footer -->
      <footer class="sticky-footer bg-white">
        <div class="container my-auto">
          <div class="copyright text-center my-auto">
            <span>Copyright &copy; JTTQE | Smart Home 2019</span>
          </div>
        </div>
      </footer>
      <!-- End of Footer -->

    </div>
    <!-- End of Content Wrapper -->

  </div>
  <!-- End of Page Wrapper -->

  <!-- Scroll to Top Button-->
  <a class="scroll-to-top rounded" href="#page-top">
    <i class="fas fa-angle-up"></i>
  </a>

  <!-- Logout Modal-->
  <div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">Add a new RFID Record</h5>
          <button class="close" type="button" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true"></span>
          </button>
        </div>
        <div class="modal-body">
		Input your name below and select OK to register a new card
		<div><input type="text" id="rfidname" class="form-control bg-light border-0 small" placeholder="Your name.."></div>
		<p id="rfidscan" hidden="true">Please scan your new card on the card reader</p>
		</div>
        <div class="modal-footer">
          <a class="btn btn-primary" href="#" onclick="addRFID();">OK</a>
          <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
        </div>
      </div>
    </div>
  </div>

  <!-- Core plugin JavaScript-->
  <script src="../static/vendor/jquery-easing/jquery.easing.min.js"></script>

  <!-- Custom scripts for all pages-->
  <script src="../static/js/sb-admin-2.min.js"></script>

</body>

</html>

img.html

HTML
Webpage
<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>JTTQE Smart Home - Dashboard</title>

  <!-- Custom fonts for this template-->
  <link href="../static/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">

  <!-- Custom styles for this template-->
  <link href="../static/css/sb-admin-2.min.css" rel="stylesheet">

  <!-- Bootstrap core JavaScript-->
  <script src="../static/vendor/jquery/jquery.min.js"></script>
  <script src="../static/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
  
  <!-- Google chart JavaScript-->
  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  <script type="text/javascript" src="../static/js/gchart.js"></script>
  
  <!-- Export SQL JavaScript-->
  <script type="text/javascript" src="../static/js/exporttoexcel.js"></script>
  
  <!-- Page level custom scripts -->
  <script type="text/javascript" src="../static/js/s3.js"></script>

</head>

<body id="page-top">

  <!-- Page Wrapper -->
  <div id="wrapper">

    <!-- Sidebar -->
    <ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">

      <!-- Sidebar - Brand -->
      <a class="sidebar-brand d-flex align-items-center justify-content-center" href="/"">
        <div class="sidebar-brand-icon rotate-n-15">
          <i class="fas fa-laugh-wink"></i>
        </div>
        <div class="sidebar-brand-text mx-3">JQTTQE Smart Home</div>
      </a>

      <!-- Divider -->
      <hr class="sidebar-divider my-0">

      <!-- Nav Item - Dashboard -->
      <li class="nav-item active">
        <a class="nav-link" href="/">
          <i class="fas fa-fw fa-tachometer-alt"></i>
          <span>Dashboard</span></a>
      </li>

      <!-- Divider -->
      <hr class="sidebar-divider">

      <!-- Heading -->
      <div class="sidebar-heading">
        Interface
      </div>

      <!-- Nav Item - Modules Collapse Menu -->
      <li class="nav-item">
        <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
          <i class="fas fa-fw fa-cog"></i>
          <span>Modules</span>
        </a>
        <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionSidebar">
          <div class="bg-white py-2 collapse-inner rounded">
            <h6 class="collapse-header">Add Module:</h6>
            <a class="collapse-item" href="#" id="addLight">Lights</a>
			<a class="collapse-item" href="#" data-toggle="modal" data-target="#logoutModal">RFID Cards</a>
          </div>
        </div>
      </li>
	  
	  <!-- Nav Item - Images Collapse Menu -->
      <li class="nav-item">
        <a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapsePages" aria-expanded="true" aria-controls="collapsePages">
          <i class="fas fa-fw fa-folder"></i>
          <span>Images</span>
        </a>
        <div id="collapsePages" class="collapse" aria-labelledby="headingPages" data-parent="#accordionSidebar">
          <div class="bg-white py-2 collapse-inner rounded">
            <h6 class="collapse-header">View:</h6>
            <a class="collapse-item" href="#" onclick="showS3()">Images</a>
          </div>
        </div>
      </li>

      <!-- Divider -->
      <hr class="sidebar-divider">

      <!-- Sidebar Toggler (Sidebar) -->
      <div class="text-center d-none d-md-inline">
        <button class="rounded-circle border-0" id="sidebarToggle"></button>
      </div>

    </ul>
    <!-- End of Sidebar -->

    <!-- Content Wrapper -->
    <div id="content-wrapper" class="d-flex flex-column">

      <!-- Main Content -->
      <div id="content">

        <!-- Topbar -->
        <nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">

          <!-- Sidebar Toggle (Topbar) -->
          <button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
            <i class="fa fa-bars"></i>
          </button>

          <!-- Topbar Search -->
          <form class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
            <div class="input-group">
              <input type="text" id="txtSearch" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
              <div class="input-group-append">
                <button class="btn btn-primary" type="button" onclick="searchFunc()">
                  <i class="fas fa-search fa-sm"></i>
                </button>
              </div>
            </div>
          </form>

          <!-- Topbar Navbar -->
          <ul class="navbar-nav ml-auto">

            <!-- Nav Item - Search Dropdown (Visible Only XS) -->
            <li class="nav-item dropdown no-arrow d-sm-none">
              <a class="nav-link dropdown-toggle" href="#" id="searchDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <i class="fas fa-search fa-fw"></i>
              </a>
              <!-- Dropdown - Messages -->
              <div class="dropdown-menu dropdown-menu-right p-3 shadow animated--grow-in" aria-labelledby="searchDropdown">
                <form class="form-inline mr-auto w-100 navbar-search">
                  <div class="input-group">
                    <input type="text" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
                    <div class="input-group-append">
                      <button class="btn btn-primary" type="button">
                        <i class="fas fa-search fa-sm"></i>
                      </button>
                    </div>
                  </div>
                </form>
              </div>
            </li>

            <div class="topbar-divider d-none d-sm-block"></div>

            <!-- Nav Item - User Information -->
            <li class="nav-item dropdown no-arrow">
              <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <span class="mr-2 d-none d-lg-inline text-gray-600 small">
					Sarah Tan
				</span>
                <img class="img-profile rounded-circle" src="https://source.unsplash.com/QAB-WJcbgJk/60x60">
              </a>
            </li>

          </ul>

        </nav>
        <!-- End of Topbar -->

        <!-- Begin Page Content -->
        <div class="container-fluid">

          <!-- Page Heading -->
          <div class="d-sm-flex align-items-center justify-content-between mb-4">
            <h1 class="h3 mb-0 text-gray-800">View Images</h1>
          </div>
		  <!-- Content Row -->
          <div class="row" id="s3pics">

            <!-- Content Column -->
            <div class="col-lg-6 mb-4" id="divActivity">
              <!-- Recent Activity -->
              <div class="card shadow mb-4">
                <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
                  <h6 class="m-0 font-weight-bold text-primary">Pictures</h6>
                </div>
                <div class="card-body">
					<div id="s3img"></div>
                </div>
              </div>

            </div>
		  </div>

        </div>
        <!-- /.container-fluid -->

      </div>
      <!-- End of Main Content -->

      <!-- Footer -->
      <footer class="sticky-footer bg-white">
        <div class="container my-auto">
          <div class="copyright text-center my-auto">
            <span>Copyright &copy; JTTQE | Smart Home 2019</span>
          </div>
        </div>
      </footer>
      <!-- End of Footer -->

    </div>
    <!-- End of Content Wrapper -->

  </div>
  <!-- End of Page Wrapper -->

  <!-- Scroll to Top Button-->
  <a class="scroll-to-top rounded" href="#page-top">
    <i class="fas fa-angle-up"></i>
  </a>

  <!-- Logout Modal-->
  <div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">Add a new RFID Record</h5>
          <button class="close" type="button" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true"></span>
          </button>
        </div>
        <div class="modal-body">
		Input your name below and select OK to register a new card
		<div><input type="text" id="rfidname" class="form-control bg-light border-0 small" placeholder="Your name.."></div>
		<p id="rfidscan" hidden="true">Please scan your new card on the card reader</p>
		</div>
        <div class="modal-footer">
          <a class="btn btn-primary" href="#" onclick="addRFID();">OK</a>
          <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
        </div>
      </div>
    </div>
  </div>

  <!-- Core plugin JavaScript-->
  <script src="../static/vendor/jquery-easing/jquery.easing.min.js"></script>

  <!-- Custom scripts for all pages-->
  <script src="../static/js/sb-admin-2.min.js"></script>

</body>

</html>

Credits

jasper

jasper

1 project • 0 followers

Comments

Add projectSign up / Login