Project in progress
IOTca2

IOTca2

A home security application, providing surveillance of the front door and the kitchen.

  • 253 views
  • 0 comments
  • 1 respect

Components and supplies

Apps and online services

About this project

ST0324 Internet of Things CA2 Step-by-step Tutorial

SCHOOL OF COMPUTING (SOC)

IOT CA2: HOME SECURITY

------------------------------------------------------------------------------------------------

Section 1 Overview of project

------------------------------------------------------------------------------------------------

A. Where we have uploaded our tutorial

Paste the link here of your Youtube and tutorial document here

B. What is the application about?

The Motley Crew’s project is designed to simulate a home surveillance system. With our setup, it consists of 2 main areas with the first being the front door and the second being the kitchen.

The front door section will let the user be updated on any motion detected at the door as well as require a permitted access card to be able to“enter” the house. The light sensor will be used to automatically control a led acting as a light system which is designed to light up if it gets dark so that our PiCam is able to take a picture regardless of time. The user is also able to control the state of the door via the telegram bot.

The kitchen section will constantly note the amount of gas and infrared inside the kitchen and a buzzer will sound, acting as an alarm if the value gets out of the safe range. The user will also be sent a message warning them of any problems that might have occurred.

C. How does the final RPI set-up look like?

D. How does the web or mobile application look like?

Web interface:

Telegram bot (Door Control) :

Telegram bot (Front door notification):

E. System architecture of our system

------------------------------------------------------------------------------------------------

Section 2 Hardware requirements

------------------------------------------------------------------------------------------------

As our application has multiple functions such as detecting flame,gas and motion, here are the hardware needed and what they are used for. There will be a total of 2 areas covered for our project.

Outside the House

1. PIR MotionSensor

A PIR Sensor is able to tell when something nearby moves.

The sensor detects the pattern of infrared energy in its surroundings. If the pattern changes, the sensor outputs a high value.

The sensor has 3 pins.

o VCC – Connect this to power (5V or 3.3V)

o VOUT – Connect this to a GPIO pin to read its value

o GND – Connect this to ground

2. 3 LED ( 2 Green, 1 Red)

To connect the LEDs, ensure that the longer leg is connected to the positive supply of the circuit(power) while the shorter one is to the negative side of the circuit(ground). In this case, for the status of the door, we will be using 2 LEDs (1 red, 1 green) to represent whether the door is locked or unlocked as well as the other LED ( 1 green) to represent if the lights are turned on outside the front door.

3. 2 LCD Screen

For this application, we will use the LCD Screen for the kitchen and the door to show information such as the current concentration of gas and infrared in the kitchen and the safety level as well as whether the key card used is granted access to open the door.

4. 7 Resistors(6 x 330 Ω Resistors, 1 x 10k Ω Resistor)

a) Resistors help ensure that small current will flow and that the Raspberry Pi will not be damaged. As this application requires multiple LEDs, we will use 1 330 Ω resistor for each LED used in the setup.

b) As our application requires the use of abutton, we will be using a 10k Ω resistor to help moderate the flow of current.

5.1 RFID / NFC MFRC522 Card Reader Module

We will be using a RFID reader for the door. This RFID will scan to check if a key card is used to open the door. This will be used to check if the key card has been authorised to be able to open the door.

6. 1 Gravity: Digital Push Button

We will be using a digital push button as a doorbell to send input to our Raspberry Pi and trigger the buzzer.

The button acts as a form of input and to know whether a push-button is pressed or unpressed, we can detect its HIGH or LOW state, which are passed through the 'legs'

7. 3 Buzzers

We will be using a buzzer for each of our Raspberry Pi which will trigger upon meeting a certain requirement such as the concentration of gas going above a certain range.

A buzzer is an audio signaling device which is commonly found in circuits to create a buzzing or beeping noise.

An active buzzer can be connected just like an LED but they are even easier to use because a resistor is not needed.

A buzzer typically has 2 pins

o VOUT – Connect this to a GPIO pin to control its value

o GND – Connect this to ground

Kitchen

8. Grove – Gas Sensor(MQ2)

This sensor is used to display the amount of flammable gas in its surrounding. This will be deployed in the kitchen, and with the help of this component and a “if” statement, the Arduino will be able to know if the amount of flammable gas is too high in the room, signalling that whether a gas leak or a fire is happening.

The gas sensor typically has 4 pins

o VCC – Connect this to the 5Vpower pin

o GND – Connect this to ground

o A0 – Connect this to any Analog output pin. Produces analog output

o D0 – Connect this to any Digital output pin. Produces digital output

For the case of this setup, only the A0 will be used

9. Flame Sensor

This flame sensor is used to detect fire as the sensor detects the amount of infrared rays shone into the sensor. This will be deployed away from sunlight and the stove, to ensure that a dangerous fire is truly occurring when the sensor shows a high reading. If both this sensor and the gas sensor show high readings, this means that a fire is happening in the kitchen.

The flame sensor used for the setup has 4pins

o VCC – Connect this to the 5V power pin

o GND – Connect this to ground

o A0 – Connect this to any Analog output pin. Produces analog output

o D0 – Connect this to any Digital output pin. Produces digital output

For the case of this setup, only the A0 will be used

10. RGB LED

A RGB LED is a LED with red, green and blue diodes inside the bulb. For this setup, the green light will be active to display that the Arduino setup is active, and that all readings are normal, and red will be used when either a fire or gas leak has been detected. This RGB LED will work alongside the buzzer and LCD display to ensure the user near the Arduino knows about the detected event, by having the LCD display the error,the buzzer emitting a differing sound between a gas leak and a fire, and the RGB LED shining red when the buzzer triggers.

The RGB LED for this case has 4 pins, 3 belonging to the red, green and blue diodes in the component, labelled R, G and B respectively. These pins will each be connected to a digital pin on the Arduino.The 4th pin is the cathode pin, meant to be connected to the ground pin.

------------------------------------------------------------------------------------------------

Section 3 Hardware setup

------------------------------------------------------------------------------------------------

In this section, we will connect the necessary components described in Section 2.

RPI 1 – Kitchen

RPI 2 – Front door part 1

RPi 3 - Front door part 2

------------------------------------------------------------------------------------------------

Section 4 Software Requirements

------------------------------------------------------------------------------------------------

In this section, we will cover the software required for our project.

· AWS DynamoDB

· AWS IoT

· Phpmyadmin

· Telegram bot

· Twilio

· Arduino IDE

· Boto3

· MQTT

------------------------------------------------------------------------------------------------

Section 5 Create a “Thing”

------------------------------------------------------------------------------------------------

A “thing” in this case is a Raspberry Pi registered in the AWS service to allow the Raspberry Pi to connect to AWS services. For the CA2 setup, only the Raspberry Pi used for the kitchen section of the application has to be used for this section.

Step 1) In the AWS console website, click on the “Services” tab in the main page, and find the link to “IOT Core”

Step 2) In the main page on the side navigation bar, click Manage > Things, and click on“Register a thing”.

Step 3) Choose “Create a single thing”

Step 4) Enter a name for the device that is about to be registered, and leave the other fields with their default values,then click Next

Step 5) Choose “Create certificate”

Step 6) When the page below shows, download all certificates, keys and the root CA showing below. Download Amazon Root CA1.

Step 7) Save all downloaded documents in a folder, move them into a folder in the registered Raspberry Pi and rename the files according to their types, like so:

Step 8) Click “Activate”, and then “Attach a Policy” on the page with the downloadable documents

Step 9) Click on “Register Thing”

Step 10) Here, we add a policy. At the main page of the IOT Core of the AWS console website at the side navigation bar,click on “Secure” > “Policies” and select “Create a Policy”

Step 11) Add in any name for the security policy, fill in the fields under “Add statements” as shown below, and click “Create”.

Step 12) Select the created certificate,and click on “Actions”, then “Attach policy” on the top right hand side of the page.

Step 13) Select the device registered as a Thing in the AWSservice, and click “Attach”

Step 14) At the IOT Core main page, click on “Manage” > “Things”, then double click on the registered Thing and select“Interact” on the new navigation sidebar to reach the page shown in the second image. Copy the link in the HTTPS section and save it in the same folder the downloaded certificates in Step 6 are located for ease of navigation.

Step 15) Start up the Raspberry Pi, and in the console,execute this lines of code:

------------------------------------------------------------------------------------------------

Section 6 DynamoDB Setup

------------------------------------------------------------------------------------------------

For this segment, a role will be created to direct data sent via MQTT to DynamoDB database, followed by the DynamoDB database that will store data sent using a specified topic, and lastly an IAM role, to allow access to the DynamoDB data via code.

Step 1) In the AWS console website, click on the “Services” tab in the main page, and find the link to “IAM”. Click on the “Roles” tab in the side navigation pane and click “Create role”

Step 2) Select “AWS service”, then “IOT”

Step 3) Select “IOT” for use case, then click “Next: Permissions”

Step 4) Click “Next: Tags”

Step 5) Click “Next: Review”

Step 6) Put in a role name, and complete the process.

Step 7) Click “Services” > “DynamoDB”and the click “Create table”

Step 8) Fill in the form fields as shown below, then click“Create”

Step 9) Click the “Services” button in the main page of the AWS console and then click “IOT Core”. Then, click “Act” on the navigation bar. Once the page shown below is reached, click “Create a rule”

Step 10) Fill in the form fields as shown below

Step 11) In the “Set one or more actions”section, click “Add action”

Step 12) Select the action shown below, and click “Configure action”

Step 13) For “Table name” choose the DynamoDB table that was set up in Step 8, and “Create rule”

Step 14) In the main page of the AWS console, click “Services” > “IAM” > “Users” and click “Add user”

Step 15) Fill in a User name , and choose“Programmatic access”. Once done, click “Next: Permissions”

Step 16) Select “Attach existing policies directly”, and click the textbox for the policy granting full access to AWS DynamoDB. The click “Next: Review”

Step 17) Click “Create User”

Step 18) Here, one can either download the.csv file which will contain the access key and secret access key or copy them when they are displayed in the webpage shown below (censored to hide the keys).Both keys will be used to access DynamoDB for retrieval of data via a python script (server.py in the case of this setup)

------------------------------------------------------------------------------------------------

Section 7 AWS EC2 Hosting of Web Application

------------------------------------------------------------------------------------------------

In this section, an EC2 instance will be created. At its base an EC2 instance is a virtual computer that AWS users can make use of for a variety of applications. In this case, we will use it to host a Flask web server, so that connection to the web server can be established globally.

Step 1) In the main page of the AWS console, click “Services”, “EC2” and then “Launch Instance”

Step 2) Select “Amazon Linux AMI”

Step 3) Click next until the “Configure Security Group” is dispayed,then choose “HTTP” in an empty dropdown field on the left of the screen, andensure that the chosen port range is 80. Click “Review and Launch”

Step 4) Click “Launch”, the choose “Createa new key pair” on the dropdown box in the popup shown below. Add a name forthe key pair, then click “Download key pair” Save the downloaded file, andclick “Launch Instances”

Step 5) Click “View Instances to be broughtto the page displaying all active EC2 instances. The EC2 will take time to comeonline. When the EC2 comes fully online, its Instance State will say “running”.

The following steps will involve establishing a connection to the EC2 through SSH so that commands can be sent to the EC2 instance, and a FTP connection to the EC2 instance to allow web application-related files to be placed in the EC2 instance to be run or used.

Step 6) Download and install PuTTY andWinSCP.

PuTTY: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

WinSCP: https://winscp.net/eng/download.php

Step 7) After installation, open up PuTTYgen.

Step 8) At the bottom, ensure that “Type of key to generate:”is RSA. Press Load and select the .pem file that you had downloaded previously from the key pair. Press Generate when .pem file is selected and press Ok when dialog box shows up.

Step 9) Press Save private key and Yes to the warning. Proceed to name it and place it some where you will remember.

Step 10) Head back to the EC2 Dashboard and note down the Public DNS for your instance. In this case, it is“ec2-3-112-152-125.ap-northeast-1.compute.amazonaws.com”.

Step 11) The default username for our instance is ec2-user.Using PuTTY, enter the host name as “ec2-user@ec2-3-112-152-125.ap-northeast-1.compute.amazonaws.com”(Defaultname@Public_DNS)

Step 12) Proceed to navigate to Auth which is under SSH from the left menu and click Browse to use your .ppk file that you had created using PuTTYgen.

Step 13) Click Open at the bottom right and press yes on the security alert. From there you are now accessing EC2 through SSH.

Step 14) Launch WinSCP. Enter in the Public DNS under hostname and ec2-user as User name.

Step 15) After inputting, click on Advanced and navigate to Authentication under SSH. Under private key, select the .ppk file that you had used for PuTTY previously.

Step 16) Click Ok and Save. Press Login and Yes when the warning pops up. You now can transfer files to the instance. (Example has files in it already, do not be confused.)

Step 17) Create a new directory called Home Security. Access it and transfer the necessary files for the web application and the rootca.pem,public.pem.key, private.pem.key and certificate.pem.crt that was downloaded previously.

Web Application Startup

Step 18) Open PuTTY and install tmux. Using tmux will allow the web application to continue running even is the connection to the SSH has been lost. Enter “y” when asked.

sudo yum install tmux         

Step 19) Continue to install the following:

sudo pip install numpy        
sudo pip install gevent        
sudo pip install flask        
sudo pip install AWSIoTPythonSDK        
sudo pip install boto3        

Step 20) On PuTTY, navigate to /HomeSecurity directory and launch tmux.

cd HomeSecurity/        
tmux        

Step 21) Run the following code:

sudo python server.py &        
tmux detach        

Step 22) You can close the PuTTY window if you want to. Check your instance in the EC2 Dashboard and take note of the IPv4 address provided and key that into your browser and your web application should be there.

------------------------------------------------------------------------------------------------

Section 8 Reading RFID/NFC tags setup

------------------------------------------------------------------------------------------------

Enable SPI and prepare the MFRC522 libraries

If your raspberry pi is not configured with the MFRC522 libraries, you can follow the following instructions to set it up.

<< Enable SPI via raspi-config >>

Step 1) Run raspi-config, choose menu item “5 Interfacing Options” and enable SPI.

sudo raspi-config        

Step 2) Modify the /boot/config.txt to enable SPI

sudo nano /boot/config.txt        

Step 3) Ensure these lines are included in config.txt

device_tree_param=spi=on        
dtoverlay=spi-bcm2835        

Step 4)Install the python development libraries

sudo apt-get install python-dev        

Step 5)Install the SPI-Py Library

Step 6) Clone the MFRC522-pythonlibrary to your home folder as follows:-

cd~        
git clone https://github.com/pimylifeup/MFRC522-python.git        
cd ~/MFRC522-python        
sudo python setup.py install        

Step 7) *Copy the MFRC522.py into the folder which you create your ReadF.py*

sudo cp ~/MFRC522-python/mfrc522/*.py ~/labs/IOTCA2Files        

------------------------------------------------------------------------------------------------

Section 9 Arduino Setup

------------------------------------------------------------------------------------------------

Before making use of the Arduino, one must first ensure theRaspberry Pi can run Arduino code

Step 1) Enter these commands into the Raspberry Pi command window.

Step 2) Once done, open Arduino IDE by clicking on the Raspbian logo on the top-left hand corner , the click“Programming”

Step 3) On top of the window, click on“Tools”, and ensure the Board has ‘Arduino Uno” selected. Since in this case only 1 Arduino will be connected to the Raspberry Pi, the serial port will only have1 selection. Select it.

Arduino code will be run using this IDE. To load the code, click “File” > “Open” then double click on the .ino file in the zip file containing the source code.

------------------------------------------------------------------------------------------------

Section 10 Program Setup

------------------------------------------------------------------------------------------------

1. kitchensensor.ino (RPi 1 - Kitchen)

This .ino file will be sent to the Arduino.Arduino code works in such a way, where after the library import commands have been run, the code will run through the “setup” method once, then repeatedly run the “loop” method repeatedly forever, until another code is uploaded to the Arduino, or the power has been reset, where the code will run from the import commands to the “loop” method once again

For this .ino file, the “setup” method will let the MQ2 gas sensor warm up for 20s while displaying “Calibrating” on the LCD display, then add a “Done” message and shine a green light using the RGB LED for 3s.

In the infinitely repeating “loop” method, every1 second the gas sensor and flame sensor will have their readings printed on the console of the Arduino IDE. The printed values in the console is not meant for the user to see, but for the subsequent python script to receive the data.

kitchensensor.ino also includes code that will trigger a buzzer, and change the RGB LED to red when the readings of the sensors show abnormal levels. For instance, if the gas sensor shows that there is a large amount of flammable gas but the flame sensor does not show a high reading, the LCD will indicate that there is a gas leak and the buzzer and RGB LED will make a beeping sound and flash respectively, and if both the gas sensor and flame sensor show high readings, the LCD will indicate a fire has been detected, the buzzer will make a drawn out sound, and the RGB LED will show red for the entire duration the buzzer sounds.

2.kitchen_db.py (RPi 1 - Kitchen)

In this python file, the code will first connect to the Arduino console and the MQTT topic used to send data from the Arduino, then wait for text to be printed in the Arduino console. Thus, each time the Arduino sends any data (completes the “loop method” stated above),kitchen_db.py will receive the printed data and send it to the MQTT topic.

At the same time, this python script also contains the same checks that will trigger when a gas leak or fire is detected.In the case of this python script, when either event is triggered, a message will be sent to the user via the Twilio messaging service. When a fire is detected, a sprinkler, represented in this setup as a LED light, will trigger to help in quelling the ongoing fire.

3. Doorbelltb.py (RPi 3 - Front door 2)

In this python script, the main code will trigger only when the button connected to the RPi is pressed. When it is pressed, the picamera will be used to take a photo, intended to be a photo taken of whoever is in the front door. A notification will also be sent to the user via Twilio and the telegram bot, and in the telegram bot the user can also send commands to the Telegram bot to control the lock on the door. The photo taken by the picamera will be sent to the user through Twilio alongside the notification of someone being outside the door,where the photo will be compressed and hosted on Imgur, using the python library called Pyimgur.

4. Telegrambot.py (RPI 2 – Front door 1)

In this python script, we have defined 3 functions, UnlockDoor,LockDoor and respondtoMsg. The first 2 functions will allow us to control the state of the door when we send a message “Lock” or“Unlock” to the bot. As we are making use of LEDs to represent the state of door,the green LED and red LED will light up respectively when “Unlock” and “Lock”are sent to the Telegram bot.

5.motionpicturetb.py (RPI 2 – Front door 1)

In this python script, we will be making use of the the motion sensor, buzzer and the picamera. After running the script, when the motion sensor detects any motion, it will trigger the method TakePictureAndSendwhere a picture is taken by the Picam and sent to the user via twilio alongside a image url. It will then proceed to send a telegram method via the method DetectandNotify with the message “Someone is outside” and sound the buzzer.

6.AddAccess.py (RPI 2 – Front door 1)

In this python script, we will be making use of a local database mysql as well as the rfid scanner to allow a new card to be added to our system. Upon running the script, our raspberry pi will connect to the mysql database, after scanning for an nfc card, the script will take the scanned uid and remove all the “,” between the string of numbers and store it as a varchar value inside the database.

7.DelAccess.py (RPI 2 – Front door 1)

In this python script, similar to AddAccess.py, we will simply be checking for any values that match the scanned uid inside the database and delete any matching uids.

8.ReadNFC.py(RPI 2 – Front door 1)

In this python script, after scanning for an nfc card and getting the uid, we will take the scanned uid and compare it to the values stored in the local database. If there is a match between the uid and any of the values stored, it will execute the methods ledOn and Open,whereas if it does not match any of the stored values, it will run the methods ledOn2, Close and bz.on before it is set to sleep.

------------------------------------------------------------------------------------------------

Section 11 Web Interface Setup

------------------------------------------------------------------------------------------------

We used WinSCP to move files to and from the EC2 that hosts our server. The following files are used for the web interface.

------------------------------------------------------------------------------------------------

Section 12 Expected Outcome

------------------------------------------------------------------------------------------------

Once the hardware setup for RPi 1: Kitchen is complete, create a directory in the RPi using a FTP client, and that the line of code has been executed in that RPi:

Simply open up kitchensensor.ino file using the downloaded Arduino IDE, and upload the code using the right-pointing arrow icon.

Then, open up the command line window of the Raspberry Pi, and run kitchen_db.py by typing in these commands (replace the first line with your own directory for your files)

With these done, the Arduino data will besent to the DynamoDB databse without any control required.

If all steps mentioned before in the tutorial are done correctly, the application should like something like this: https://www.youtube.com/watch?v=T5O9mbO8ww8&feature=youtu.be

The Arduino would be able to detect gases and flame and a buzzer would sound off if any of both sensors detect something wrong. The RGB LED would also turn red otherwise, the LED will remain green and will be as soon as the program runs.

The Front door would be able to send messages to the user's phone number and telegram when the motion sensor detector if someone pressses the doorbell. When someone presses the doorbell, the message will also include an URL to a picture that is taken from the PiCam as soon as the button is pressed. A buzzer will also sound off if the doors are open via RFID card reader when it reads a authenticated card or when the doorbell is pressed. When an authenticated card has been read, a green LED will be lit up while a red LED will always be lit up to simulate the status of the door.

The website will show a live line graph of gases and a history log of the previous 10 values will also be shown along with the date and time of when it was taken. At the side of the web page, there will be a live clock and the fire level. The fire level will update its color if it changes. E.g. White for "No Fire", yellow for "Low" and red for "High".

-- End of CA2 Step-by-step tutorial --

Code

ReadNFC.pyPython
#!/usr/bin/env python
# -*- coding: utf8 -*-
 
import sys
import Adafruit_DHT
import mysql.connector
import RPi.GPIO as GPIO
import MFRC522
import signal
import time

from gpiozero import LED
from gpiozero import Buzzer
from signal import pause

from rpi_lcd import LCD
from time import sleep
 
continue_reading = True
 
# Capture SIGINT for cleanup when the script is aborted
def end_read(signal,frame):
    global continue_reading
    continue_reading = False
    GPIO.cleanup()

led = LED(18)
led2 = LED(20)
bz = Buzzer(5)

def ledOn():
    led.on()
    led2.off()

def ledOn2():
	led2.on()
	led.off()
    
lcd = LCD()
def Open():
    lcd.text('Door Opened',1)
    sleep(5)
    lcd.clear()

def Close():
    lcd.text('Access Denied',1)
    lcd.text('Wrong Key',2)
    sleep(5)
    lcd.clear()
 
# Hook the SIGINT
signal.signal(signal.SIGINT, end_read)
 
# Create an object of the class MFRC522
MIFAREReader = MFRC522.MFRC522()

# Welcome message
 
# This loop keeps checking for chips. If one is near it will get the UID and authenticate
while continue_reading:    
    # Scan for cards    
    (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
 
    # If a card is found
    if status == MIFAREReader.MI_OK:
	time.sleep(2)    

    # Get the UID of the card
    (status,uid) = MIFAREReader.MFRC522_Anticoll()
 
    # If we have the UID, continue
    if status == MIFAREReader.MI_OK:

        
        # Select the scanned tag
        MIFAREReader.MFRC522_SelectTag(uid)
        
        #ENTER Your Card UID here
        my_uid = [136,4,20,190,38]

        uid1 = ''.join(str(e) for e in uid)
        uid1.replace("'","")
        cnx = mysql.connector.connect(user='iotuser',password='dmitiot',host='localhost',database='assignmentdatabase') 
        cursor = cnx.cursor()
        cursor.execute("Select rfid_values FROM rfid WHERE rfid_values =('%s')" %uid1)
        result = cursor.fetchone()

        
        #Check to see if card UID read matches your card UID
        if cursor.rowcount == 1:                
            print("Access Granted - {}".format(uid1))
            ledOn()
	    Open()
            bz.off()
		
        else:                            #Don't open if UIDs don't match
            print("Access Denied - {}".format(uid1))
	    ledOn2()
	    Close()
	    bz.on()
	    sleep(1)
	    bz.on()
	    sleep(1)
	    bz.off()
telegrambot.pyPython
import telepot
from gpiozero import LED
from time import sleep
#Import all libraries needed


my_bot_token = '943409193:AAHG7RMbNR1C31Y6PGACVsPvfkAx1KiHeyU'
#Enter the bot token 
led = LED(18)
led2 = LED(20)

def UnlockDoor():
   led.on()
   led2.off()
   return "Door is now unlocked..."

def LockDoor():
   led2.on()
   led.off()
   return "Door is now locked"

def respondToMsg(msg):
    chat_id = msg['chat']['id']
    command = msg['text']
	
    print('Got command: {}'.format(command))

    if command == 'Unlock':
       bot.sendMessage(chat_id, UnlockDoor())
    elif command =='Lock':
       bot.sendMessage(chat_id, LockDoor())

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


while True:
	 LockDoor()
     sleep(15)
	 
Doorbelltb.pyPython
import pyimgur
import time
import os
import sys
import re
import threading
import picamera
import telepot
import schedule
import requests
from gpiozero import Button, Buzzer
from time import sleep

my_bot_token = '943409193:AAHG7RMbNR1C31Y6PGACVsPvfkAx1KiHeyU'

def DetectAndNotify(bot_message):
    
    bot_token = '943409193:AAHG7RMbNR1C31Y6PGACVsPvfkAx1KiHeyU'
    bot_chatID = '-375074177'
    send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message

    response = requests.get(send_text)

    return response.json()

#for twilio
from twilio.rest import Client
account_sid = "ACbc81590032ee12b7e205394aae9130ec"
auth_twilio = "331dbfab7b747f16036c39d3545fb353"
client = Client(account_sid, auth_twilio)
my_hp = "+6591440914"
twilio_hp = "+19088544663"

# For Imgur
CLIENT_ID = "84017be6449ab0b"
im = pyimgur.Imgur(CLIENT_ID)

# Minimum time between each pictures
DELAY = 10

# Text messages
TXT_MSG = "Someone is at the door."

# Picture definition
IMG_WIDTH = 800
IMG_HEIGHT = 600

button = Button(13, pull_up=False)
bz = Buzzer(5)

def TakePictureAndSend():
  timestring = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime())
  filename = '/home/pi/photo_'+timestring+'.jpg'
  with picamera.PiCamera() as camera:
    camera.resolution = (IMG_WIDTH, IMG_HEIGHT)
    camera.capture(filename)
  uploaded_image = im.upload_image(filename, title=TXT_MSG)
  print "Sending message"
  client.messages.create(to=my_hp,
                      from_=twilio_hp,
                      body=TXT_MSG,
                      media_url=uploaded_image.link)

  # 20 Seconds between each picture
  time.sleep(DELAY)

def buzzOn():
	bz.on()
	sleep(2)
	bz.off()
	TakePictureAndSend()
	test = DetectAndNotify("Someone is at the door. You can control the door using the bot by typing 'Lock' or 'Unlock'.")
	print(test)
	sleep(2)
    
while True:
	button.when_pressed = buzzOn
styles.cssCSS
/* Colours used: #3AAFA9, #17252A, #2B7A7B, #DEF2F1, #FEFFFF */

html {
    color: #17252A;
}

body {
    background-color: #3AAFA9;
    font-family: 'Merriweather', serif;
}

a {
    text-decoration: none;
}

.active, a:hover {
    color: #FEFFFF;
}

a:visited, a:link {
    color: #17252A;
}

.grid-container {
    display: grid;
    grid-template-areas:
        'header header header header'
        'main main main right';
    grid-gap: 10px;
    padding: 10px;
    background-color: #2B7A78;
}

.grid-container > div {
    padding: 20px 0;
    background-color: #3AAFA9;
}

.itemHeader { 
    text-align: center;
    grid-area: header;
}

.itemMain {
    grid-area: main;
}

.entryLog {
    padding: 10px;
}

.gasGraph {
    padding: 10px;
    width: 75%;
}

.dataTable {
    padding: 10px;
    width: 75%;
}

.btn {
    margin: 10px;
    background-color: #FEFFFF;
}

.itemRight {
    grid-area: right;
    text-align: center;
}

.welcome {
    font-family: 'Saira Extra Condensed', sans-serif;
    font-size: 2.5vw;
    color: #FEFFFF;
}

.FireLvL {
    font-weight: bold;
}

footer {
    position: relative;
    left: 0;
    bottom: 0;
    width: 100%;
    text-align: center;
    font-size: 1vw;
}
index.htmlHTML
<!DOCTYPE html>
<html lang=en>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Home Security - Front Door</title>
    <link href="https://fonts.googleapis.com/css?family=Merriweather|Saira+Extra+Condensed:900&display=swap" rel="stylesheet">
    <link type="text/css" rel="stylesheet" href="{{ url_for('static',filename='styles.css') }}">
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.js"></script>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    
    <!-- JScript for Clock -->
    <script>
        function startTime() {
            var today = new Date();
            var h = today.getHours();
            var m = today.getMinutes();
            var s = today.getSeconds();
            m = checkTime(m);
            s = checkTime(s);
            document.getElementById('clock').innerHTML = h + ":" + m + ":" + s;
            var t = setTimeout(startTime, 500);
        }
        function checkTime(i) {
            if (i < 10) {
                i = "0" + i;
            }
            return i;
        }
    </script>

    <!-- JScript for DataTable -->
    <script type="text/javascript">
        google.charts.load('current', {'packages': ['corechart', 'table']});
        google.charts.setOnLoadCallback(googlecharts_is_ready);

        var graphdata;

        function reset_status_messages() {
            $("#status").html("");
        }

        function googlecharts_is_ready() {
            $("#buttonloadchart").show();
            loadChart();
            $("#status").html("Google charts is ready");
        }

        function loadChart() {
            getData_and_drawChart();
        }

        function getData_and_drawChart() {
            getNewData();
        }

        function getNewData() {
            $("#status").html("Fetching data to plot graph...");

            jQuery.ajax({
                url: "/api/getdata",
                type: 'POST',
                success: function (ndata, textStatus, xhr) {
                    $("#status").html("Data fetched! Now plotting graph!");
                    console.log(ndata.chart_data.data);
                    chartdata = ndata.chart_data.data;
                    graphdata = createDataTable(chartdata);
                    drawLineChart(graphdata);
                    drawDataTable(graphdata);
                    $("#status").html("Graph plotted");
                }//end success
            });//end ajax
        } //end getNewData

        function createDataTable(newdata) {
            graphdata = new google.visualization.DataTable();
            graphdata.addColumn('string', 'Date');
            graphdata.addColumn('number', 'Gas Level');
            run_once = true;
            for (i in newdata) {
                datetime = newdata[i].Date;
                raw_value = String(newdata[i].RawValue);
                var splitvalue = raw_value.split("+"),
                a = splitvalue[0], b = splitvalue[1];
                var level = parseInt(b);
                var firelvl = a.bold();
                if (run_once == true){
                    if (a == "NO FIRE") {
                        document.getElementById("FireLvL").style.color = '#FEFFFF';
                        document.getElementById("FireLvL").innerHTML = firelvl;
                    }

                    else if (a == "LOW") {
                        document.getElementById("FireLvL").style.color = '#FFAE42';
                        document.getElementById("FireLvL").innerHTML = firelvl;
                    }

                    else if (a == "HIGH") {
                        document.getElementById("FireLvL").style.color = '#FF2323';
                        document.getElementById("FireLvL").innerHTML = firelvl;
                    }
                    run_once = false;
                }
                graphdata.addRows([[datetime, level]]);
            }//end for
            return graphdata
        }

        function drawDataTable(graphdata) {
            var table = new google.visualization.Table(document.getElementById('table'));
            table.draw(graphdata, { showRowNumber: true, width: '100%', height: '100%' });
        }//end drawTable

        function drawLineChart(graphdata) {
            var chart = new google.visualization.LineChart(document.getElementById('chart'));
            chart.draw(graphdata, {legend: 'none', vAxis: { baseline: 0 }, colors: ['#3AAFA9']});
        } //end drawChart

        $(document).ready(function() {
            reset_status_messages()
            setInterval(function() {loadChart()}, 1000);
        }); //end of Ready and setInterval
    </script>
</head>

<body onload="startTime()">
    <!-- Start of grid -->
    <div class="grid-container">

        <!-- Header -->
        <div class="itemHeader">
            <div class="welcome">
                <h2>Welcome to HomeSecurity</h2>
            </div>
        </div>

        <!-- Kitchen -->
        <div class="itemMain">
            <!-- LineGraph -->
            <div class="gasGraph">
                <h3>Gas Sensor Reading</h3>
                <div id="chart"></div>
            </div>

            <!-- Load Button -->
            <input class="btn" id="buttonloadchart" type="button" onclick="loadChart()" value="Update graph">

            <!-- DataTable -->
            <div class="dataTable">
                <h3>Gas Sensor History Log</h3>
                <div id="table"></div>
            </div>
        </div>

        <!-- Clock and Light indicator -->
        <div class="itemRight">
            <!-- Clock for user -->
            <div class="Clock">
                <h3 id="clock"></h3>
                <div class="Fire">
                    <h3>Fire Level:</h3>
                    <div id="FireLvL"></div>
                </div>
            </div>
        </div>
    </div>
    <!-- End of grid -->
</body>

<footer>
    <p>created by Ryan Tan, Tan Jia Liang and Aloysius Chng.</p>
</footer>
</html>
kitchen_db.pyPython
# Import SDK packages
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
from time import sleep
import serial
import re
import sys
from gpiozero import LED

#for twilio
from twilio.rest import Client

account_sid = "ACbc81590032ee12b7e205394aae9130ec"
auth_twilio = "331dbfab7b747f16036c39d3545fb353"
client = Client(account_sid, auth_twilio)
my_hp = "+6591440914"
twilio_hp = "+19088544663"

sprinkler = LED(18)

#establish connection to arduino IDE
device = "/dev/ttyUSB0"
baud = 9600

# 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 = "a1xbz9pmhe6x41-ats.iot.ap-northeast-1.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("iot/kitchen", 1, customCallback)
sleep(2)

# Test connection to Arduino
try:
    update = True
    print ("Connecting to {}".format(device)) 
    arduino = serial.Serial(device, baud) 
except: 
    print ("Failed to connect to {}".format(device)) 
    update = False   

sprinkler_counter = 0

# Publish to the same topic in a loop forever
while update:

    try:
        data=arduino.readline() # smoke detector sample data "FLAME_LEVEL+GAS_SENSOR_RAW_VALUE"

        if data.find("+") != -1: #returning -1 means .find cant find the specified string
            data = data.translate(None, "\n")
            ino_output = data.split('+')
            print(ino_output[0], ino_output[1]) #to display collection of data

            if(ino_output[0] == 'HIGH' and int(ino_output[1]) >= 300):
                TXT_MSG = 'FIRE DETECTED IN KITCHEN'
                client.messages.create(to=my_hp,
                from_=twilio_hp,
                body=TXT_MSG)
                sprinkler.on()
                print(ino_output[0], ino_output[1])
                sprinkler_counter = sprinkler_counter + 1
            
            elif(int(ino_output[1]) >= 300):
                TXT_MSG = 'GAS LEAK DETECTED IN KITCHEN'
                client.messages.create(to=my_hp,
                from_=twilio_hp,
                body=TXT_MSG)
                print('hello')
            
            if (sprinkler_counter >= 1 and sprinkler_counter <= 4):
                sprinkler_counter = sprinkler_counter + 1
            
            if(sprinkler_counter >= 4):
                sprinkler.off()

            msg_output = data
            message = {}
            message["deviceid"] = "deviceid_1836860_JL"
            import datetime as datetime
            now = datetime.datetime.now()
            dt = now.strftime("%d/%m/%Y %H:%M:%S")
            message["datetimeid"] = dt
            message["value"] = msg_output
            import json
            my_rpi.publish("iot/kitchen", json.dumps(message), 1)
            sleep(1)   

    except KeyboardInterrupt: # ctrl+c to stop program
        update = False
    
    except:
        print("Error while inserting data...")
        print(sys.exc_info()[0])
        print(sys.exc_info()[1])
kitchensensor.inoC/C++
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int MQ_PIN=A1;
int FLAME_PIN=A0;
const int sensorMin = 0;     // sensor minimum
const int sensorMax = 1024;  // sensor maximum
String flameLevel = ".";
const int maxGas = 300;
int redPin= 4;
int greenPin = 5;
int bluePin = 6;
int buzzPin = 10;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // sets the serial port to 9600
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  Serial.println("Gas sensor warming up!");
  lcd.clear();
  lcd.begin(16,2);
  lcd.print("Calibrating..."); 
  delay(20000); // allow the MQ-2 to warm up
  lcd.setCursor(0,1);
  lcd.print("Done");
  setColor(0, 255, 0); // Green Color
  delay(3000);
}


void loop() {
  // put your main code here, to run repeatedly:
    // read the sensor on analog A0:
  int flameReading = analogRead(FLAME_PIN);
  int gasReading = analogRead(MQ_PIN);
  // map the sensor range (four options):
  // ex: 'long int map(long int, long int, long int, long int, long int)'
  int range = map(flameReading, sensorMin, sensorMax, 0, 3);

  switch (range) {
  case 0:    // A fire closer than 1.5 feet away.
    flameLevel = "HIGH";
    break;
  case 1:    // A fire between 1-3 feet away.
    flameLevel = "LOW";
    break;
  case 2:    // No fire detected.
    flameLevel = "NO FIRE";
    break;
  }
 
    
    Serial.print(flameLevel);
    Serial.print("+");
    Serial.print(gasReading);
    Serial.print("\n");

    if( gasReading >= maxGas && flameLevel.equals("HIGH") ){ //maxGas is a constant 300
      lcd.clear();
      lcd.setCursor(4,0);
      lcd.print("DANGER!!!");
      lcd.setCursor(1,1);
      lcd.print("FIRE DETECTED");
      setColor(255, 0, 0); // Red Color
      tone(buzzPin,1000);
      delay(4000);  
      noTone(buzzPin);
    }
    else if(gasReading >= maxGas){
      lcd.clear();
      lcd.setCursor(4,0);
      lcd.print("DANGER!!!");
      lcd.setCursor(0,1);
      lcd.print("GAS LEAK ACTIVE");
      int counter = 0;

      while(counter <= 4){
      tone(buzzPin,1000);
      setColor(255, 0, 0); // Red Color
      delay(750);
      noTone(buzzPin);
      setColor(0, 0, 0); // Red Color
      delay(250);
      counter++;        
      }

    }
    else{
    
    setColor(0, 255, 0); // Green Color
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("GAS LV  FLAME LV");
    lcd.setCursor(0,1);
    lcd.print(gasReading);
    lcd.setCursor(8,1);
    lcd.print(flameLevel);
    delay(1000);  // delay between reads
    }    
    


}
void setColor(int redValue, int greenValue, int blueValue) {
      analogWrite(redPin, redValue);
      analogWrite(greenPin, greenValue);
      analogWrite(bluePin, blueValue);
}
AddAccess.pyPython
import sys
import Adafruit_DHT
import mysql.connector
import RPi.GPIO as GPIO
import MFRC522
import signal
from rpi_lcd import LCD
from time import sleep

uid = None
prev_uid = None 
continue_reading = True
#GPIO.setwarnings(False)

# Capture SIGINT for cleanup when the script is aborted
def end_read(signal,frame):
    global continue_reading
    print "Ctrl+C captured, ending read."
    continue_reading = False
    GPIO.cleanup()

lcd = LCD()
def Add():
    lcd.text('User Added',1)
    sleep(5)
    lcd.clear()
    

# Hook the SIGINT
signal.signal(signal.SIGINT, end_read)

# Create an object of the class MFRC522
mfrc522 = MFRC522.MFRC522()


try:
    u='iotuser';pw='dmitiot';
    h='localhost';db='assignmentdatabase'

    cnx = mysql.connector.connect(user=u,password=pw,host=h,database=db) 
    cursor = cnx.cursor()
    print("Successfully connected to database!")
    # Scan for cards    
    (status,TagType) = mfrc522.MFRC522_Request(mfrc522.PICC_REQIDL)

    # If a card is found
    if status == mfrc522.MI_OK:
	
        # Get the UID of the card
        (status,uid) = mfrc522.MFRC522_Anticoll()
        if uid!=prev_uid:
           prev_uid = uid
	   uid1 = ''.join(str(e) for e in uid)
	   uid1.replace("'","")

	   print("Card is added! UID of card is {}".format(uid1))
	   Add()
      	   cursor.execute("INSERT INTO rfid (rfid_values) VALUES ('%s')" %(uid1))
	   cnx.commit()
		   
 
except:
    print(sys.exc_info()[0])
    print(sys.exc_info()[1])
DelAccess.pyPython
import sys
import Adafruit_DHT
import mysql.connector
import RPi.GPIO as GPIO
import MFRC522
import signal
from rpi_lcd import LCD
from time import sleep


uid = None
prev_uid = None 
continue_reading = True

# Capture SIGINT for cleanup when the script is aborted
def end_read(signal,frame):
    global continue_reading
    continue_reading = False
    GPIO.cleanup()

lcd = LCD()
def Del():
    lcd.text('User Deleted',1)
    sleep(5)
    lcd.clear()
# Hook the SIGINT
signal.signal(signal.SIGINT, end_read)

# Create an object of the class MFRC522
mfrc522 = MFRC522.MFRC522()


try:
    u='iotuser';pw='dmitiot';
    h='localhost';db='assignmentdatabase'

    cnx = mysql.connector.connect(user=u,password=pw,host=h,database=db) 
    cursor = cnx.cursor()
    # Scan for cards    
    (status,TagType) = mfrc522.MFRC522_Request(mfrc522.PICC_REQIDL)

    # If a card is found
    if status == mfrc522.MI_OK:
        # Get the UID of the card
        (status,uid) = mfrc522.MFRC522_Anticoll()
        if uid!=prev_uid:
           prev_uid = uid
	   uid1 = ''.join(str(e) for e in uid)
           uid1.replace("'","")
		   Del()
           cursor.execute("DELETE FROM rfid WHERE rfid_values = %s" %(uid1))
           print("Card is deleted! UID of card is {}".format(uid1))

           cnx.commit()
 
except:
    print(sys.exc_info()[0])
    print(sys.exc_info()[1])
MFRC522.pyPython
#!/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 spidev
import signal
import time
import logging

class MFRC522:
    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, bus=0, device=0, spd=1000000, pin_mode=10, pin_rst=-1, debugLevel='WARNING'):
        self.spi = spidev.SpiDev()
        self.spi.open(bus, device)
        self.spi.max_speed_hz = spd

        self.logger = logging.getLogger('mfrc522Logger')
        self.logger.addHandler(logging.StreamHandler())
        level = logging.getLevelName(debugLevel)
        self.logger.setLevel(level)

        gpioMode = GPIO.getmode()
        
        if gpioMode is None:
            GPIO.setmode(pin_mode)
        else:
            pin_mode = gpioMode
            
        if pin_rst == -1:
            if pin_mode == 11:
                pin_rst = 15
            else:
                pin_rst = 22
            
        GPIO.setup(pin_rst, GPIO.OUT)
        GPIO.output(pin_rst, 1)
        self.MFRC522_Init()

    def MFRC522_Reset(self):
        self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)

    def Write_MFRC522(self, addr, val):
        val = self.spi.xfer2([(addr << 1) & 0x7E, val])

    def Read_MFRC522(self, addr):
        val = self.spi.xfer2([((addr << 1) & 0x7E) | 0x80, 0])
        return val[1]

    def Close_MFRC522(self):
        self.spi.close()
        GPIO.cleanup()

    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

        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)

        for i in range(len(sendData)):
            self.Write_MFRC522(self.FIFODataReg, sendData[i])

        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 -= 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

                    for i in range(n):
                        backData.append(self.Read_MFRC522(self.FIFODataReg))
            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:
                for i in range(4):
                    serNumCheck = serNumCheck ^ backData[i]
                if serNumCheck != backData[4]:
                    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)

        for i in range(len(pIndata)):
            self.Write_MFRC522(self.FIFODataReg, pIndata[i])

        self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
        i = 0xFF
        while True:
            n = self.Read_MFRC522(self.DivIrqReg)
            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)
        
        for i in range(5):
            buf.append(serNum[i])

        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):
            self.logger.debug("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
        for i in range(len(Sectorkey)):
            buff.append(Sectorkey[i])

        # Next we append the first 4 bytes of the UID
        for i in range(4):
            buff.append(serNum[i])

        # 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):
            self.logger.error("AUTH ERROR!!")
        if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:
            self.logger.error("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):
            self.logger.error("Error while reading!")

        if len(backData) == 16:
            self.logger.debug("Sector " + str(blockAddr) + " " + str(backData))
            return backData
        else:
            return None

    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

        self.logger.debug("%s backdata &0x0F == 0x0A %s" % (backLen, backData[0] & 0x0F))
        if status == self.MI_OK:
            buf = []
            for i in range(16):
                buf.append(writeData[i])

            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):
                self.logger.error("Error while writing")
            if status == self.MI_OK:
                self.logger.debug("Data written")


    def MFRC522_DumpClassic1K(self, key, uid):
        for i in range(64):
            status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid)
            # Check if authenticated
            if status == self.MI_OK:
                self.MFRC522_Read(i)
            else:
                self.logger.error("Authentication error")

    def MFRC522_Init(self):
        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()
motionpicturetb.pyPython
import pyimgur
import time
import os
import sys
import re
import mysql.connector
import threading
import picamera
from gpiozero import LED, MCP3008, Button
from time import sleep
from gpiozero import Buzzer
from gpiozero import MotionSensor
import telepot
import schedule
import requests

my_bot_token = '943409193:AAHG7RMbNR1C31Y6PGACVsPvfkAx1KiHeyU'

# For Twilio
from twilio.rest import Client
account_sid = "ACbc81590032ee12b7e205394aae9130ec"
auth_twilio = "331dbfab7b747f16036c39d3545fb353"
client = Client(account_sid, auth_twilio)
my_hp = "+6591440914"
twilio_hp = "+19088544663"

# For Imgur
CLIENT_ID = "84017be6449ab0b"
im = pyimgur.Imgur(CLIENT_ID)

adc = MCP3008(channel=0)
btn = Button(13, pull_up=False)

# Minimum time between each pictures
DELAY = 20

# Text messages
TXT_MSG = "Someone is outside"

# Picture definition
IMG_WIDTH = 800
IMG_HEIGHT = 600

#Buzzer connected to GPIO5
pir = MotionSensor(26, sample_rate=5,queue_len=1)
bz = Buzzer(5)

#Minimum time between captures
DELAY = 5


def TakePictureAndSend():
  timestring = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime())
  filename = '/home/pi/photo_'+timestring+'.jpg'
  with picamera.PiCamera() as camera:
    camera.resolution = (IMG_WIDTH, IMG_HEIGHT)
    camera.capture(filename)
  uploaded_image = im.upload_image(filename, title=TXT_MSG)
  print "Sending message"
  client.messages.create(to=my_hp,
                      from_=twilio_hp,
                      body=TXT_MSG,
                      media_url=uploaded_image.link)

  # 20 Seconds between each picture
  time.sleep(DELAY)


def DetectAndNotify(bot_message):
    
    bot_token = '943409193:AAHG7RMbNR1C31Y6PGACVsPvfkAx1KiHeyU'
    bot_chatID = '-375074177'
    send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message

    response = requests.get(send_text)

    return response.json()

#motion sensor waits for motion --> detects motion --> takes a picture --> buzzer on --> delay --> buzzer off
while True:
	bz.off()
	pir.wait_for_motion()
	if pir.motion_detected:
		TakePictureAndSend()
		test = DetectAndNotify("Someone is outside")
		print(test)
		bz.on()
		time.sleep(DELAY)
		bz.off()

Schematics

RPi 1: Kitchen
Uploads2ftmp2f2f970cf9 3bca 4011 9b95 576f683ec5862fkitchen bb sj7cq3enyb
RPi 3: Front door part 2
Uploads2ftmp2f8c5f4f2d d41e 4495 a289 917732b477172ffrontdoorpart2fritz d6dowelmyr
RPi 2: Front door part 1
Uploads2ftmp2f1c448b13 f2a0 4bf2 85bc b78366aa00c82fpt2 xzq9dimgig

Comments

Similar projects you might like

Octopod: Smart IoT Home/Industry Automation Project

Project tutorial by Saksham Bhutani

  • 10,636 views
  • 9 comments
  • 37 respects

Intelligent Door Lock

Project in progress by Md. Khairul Alam

  • 22,713 views
  • 24 comments
  • 112 respects

ECOPlant - Plant Monitoring

Project in progress by PohWL

  • 2,964 views
  • 1 comment
  • 21 respects

Intrusion Alert System using Arduino and Bolt IoT

Project tutorial by Rohit Kumar

  • 2,341 views
  • 0 comments
  • 12 respects

IoT Home Security Model

Project showcase by Aaron Kow

  • 62,547 views
  • 43 comments
  • 182 respects
Add projectSign up / Login