Raspberry-Pi / SMS Alarm System

https://sites.google.com/site/jfpayeur/raspberrypi

Raspberry-Pi / SMS Alarm System

Description

Here are some information about a little Python Project I’ve made based on a Raspberry-Pi Platform. This is My first Python Project Ever, my code is not super clean, but it works great.

 

This system send me an SMS and/or Email if my door is open, or if the PIR (passive infrared movement detector) is triggered. This can be easily expanded to 8 or mores zones, or control something else.

In my case , I’m using a secret switch (zone3) to disable the PIR (zone2)

I’m not a super linux geek myself, every thing described here is do-able from a normal pc running windows

 

Some features :

-Send Email or SMS when alarm is trigered

-Send Periodic report , 12-24 hours (configurable)

-Send report when system boot, quit, is activated or desactivated

-Get the system IP ant Time at boot-up and Present Time

-Can Send email or SMS via private SMTP server or ISP SMTP server , or via Gmail secure SMTP server

-Flash a led when code is running

-Has a saftety so it doesnt send more than x Email by every X sec time-laps.

 

Photos:

 

Hardware:

  •    RasberryPi model B

                            

                        http://www.raspberrypi.org/faqs
  •    Adafruit Prototyping Pi Plate Kit , or get another way to plug your stuff

                        http://www.adafruit.com/products/801

  • 2Gb SD Card Min.
  • Movement Detector(S)
  • Door switche(s)

 

Shematic:

Raspberry-Pi Pin-Out:

 

Software:


Get Raspbian “wheezy”
     
http://www.raspberrypi.org/downloads
(do not use the GUI, it waste CPU power)


Flash the SD card using 

win32diskimager


Get remote acces with: 

    Command Line Acces  Putty
File transfer FileZilla 

Instal Python 
http://www.raspberrypi-spy.co.uk/2012/07/install-rpi-gpio-library-in-raspbian/

Upload the script
   Upload the script, named main.py to the folder /home/pi/code 


Verify / Adapt / Edit the script

    cd code
sudo nano main.py

Make the script executable

    sudo chmod +x startup_mailer.py

Test the script

    sudo python main.py

To start the script at startup: 

    sudo nano /etc/rc.local

Edit the file so it look like this:

To Manually stop the script started at startup
Step #1
Find the PID
—> ps -ef | grep python
root      1876  1874  0 22:23 ?        00:00:00 sudo python /home/pi/code/main.py
root      1877  1876 97 22:23 ?        00:04:53 python /home/pi/code/main.py
pi        1986  1970  0 22:28 pts/1    00:00:00 grep –color=auto python

Step#2
Kill the 2 first pids
—> sudo kill -9 1876
—> sudo kill -9 1877

Code:

 

# My first python project 

# Sources and Ref.
#           http://elinux.org/RPi_Email_IP_On_Boot_Debian

#           http://elinux.org/RPi_BCM2835_GPIOs
#           http://docs.python.org/2/library/thread.html
#           http://elinux.org/RPi_Low-level_peripherals
#           http://pypi.python.org/pypi/RPi.GPIO

system_name='Alarm Name'
code_version='V022'
alarm_email1  = '5141234567@txt.bell.ca'
# see http://en.wikipedia.org/wiki/List_of_SMS_gateways

status_email1 = 'youre_destination_email@gmail.com'
my_ip_now='empty'
my_ip_boot='empty'

smtp_email_from = 'your_source_email@your_provider.com'
smtp_email_from_password='xxxx'#only used if secure smtp is used 
smtp_email_server  = 'smtp.your_provider.com'
#smtp_email_server = 'smtp.teksavvy.com'
#smtp_email_server = 'relai.videotron.ca'
#smtp_email_server = 'smtp.gmail.com'

email_max_count=0
email_max_qte=20        #max of 20 emails 
email_max_timelaps=60   #per 60secondes
email_max_skiped_qte=0

zone1_name='Front Door'
zone2_name='PIR'
zone3_name='Secret Switch'
zone4_name='Door4'
zone5_name='Door5'
zone6_name='Door6'
zone7_name='Door7'
zone8_name='Door8'

zone1_active=True
zone2_active=True
zone3_active=True
zone4_active=False
zone5_active=False
zone6_active=False
zone7_active=False
zone8_active=False

zone1_alarm_count=0
zone2_alarm_count=0
zone3_alarm_count=0
zone4_alarm_count=0
zone5_alarm_count=0
zone6_alarm_count=0
zone7_alarm_count=0
zone8_alarm_count=0

io_led1=18
io_led2=17
io_zone1=23
io_zone2=24
io_zone3=25
io_zone4=4
io_zone5=4
io_zone6=4
io_zone7=4
io_zone8=4

latch_zone1=1
latch_zone2=1
latch_zone3=1
latch_zone4=1
latch_zone5=1
latch_zone6=1
latch_zone7=1
latch_zone8=1

flashing_led=0

test=0

#########################
#      IMPORT           #    
#########################
import RPi.GPIO as GPIO #for gpio 
import subprocess #for email 
import smtplib #for email 
import socket #for email 
from email.mime.text import MIMEText #for email 
import datetime #get date
import sys #to exit 
import thread #for tread 
import threading #for tread that send periodic status 
import time #for delay

########################
#       DEFINE         #
######################## 
def periodic_report():
    while(1):
        print 'Send periodic report'
        send_status_email(status_email1,'Periodic Report')
        time.sleep(60*60*12) #12hours

def periodic_email_max_reset(): #Prevent email flooding
    global email_max_count
    global email_max_timelaps
    while(1):
        print 'Reset email max counter'
        email_max_count=0
        time.sleep(email_max_timelaps) 

def periodic_test():
    global test
    while(1):
        time.sleep(2) 
        print 'Test'
        test=1

def get_ip():
    arg='ip route list'
    p=subprocess.Popen(arg,shell=True,stdout=subprocess.PIPE)
    data = p.communicate()
    split_data = data[0].split()
    ipaddr = split_data[split_data.index('src')+1]
    my_ip= ' %s' %  ipaddr
    return my_ip

def sendemail_alarm(to,subject,message):
    global email_max_count
    global email_max_qte
    global email_max_skiped_qte

    email_max_count=email_max_count+1
    print'trying to send email'

    if(email_max_count < email_max_qte):
        print'go'
        sendemail(to,subject,message)
    else:    
        print 'Cant send email. %i Emails sent in the last %i sec. Max is:%i' % (email_max_count,email_max_timelaps,email_max_qte)
        email_max_skiped_qte=email_max_skiped_qte+1

def sendemail(to,subject,message):
    #chose you sending way 
    thread.start_new_thread(send_through_smtp,(to,subject,message))
    #thread.start_new_thread(send_through_secure_smtp,(to,subject,message))

def send_through_secure_smtp(to,subject,message):
    GPIO.output(io_led1, GPIO.HIGH)
    gmail_user = smtp_email_from
    gmail_password = smtp_email_from_password
    server = smtplib.SMTP(smtp_email_server, 587)
    server.ehlo()
    server.starttls()
    server.ehlo
    server.login(gmail_user, gmail_password)
    today = datetime.date.today()
    arg='ip route list'
    p=subprocess.Popen(arg,shell=True,stdout=subprocess.PIPE)
    data = p.communicate()
    split_data = data[0].split()
    ipaddr = split_data[split_data.index('src')+1]
    my_ip =    'Alarm System Ip %s' %  ipaddr
    my_ip = my_ip + '\n' + message
    msg = MIMEText(my_ip)
    msg['Subject'] = subject
    msg['From'] = gmail_user
    msg['To'] = to
    server.sendmail(gmail_user, [to], msg.as_string())
    server.quit()
    GPIO.output(io_led1, GPIO.LOW)

def send_through_smtp(to,subject,message):
    GPIO.output(io_led1, GPIO.HIGH)
    user = smtp_email_from
    server = smtplib.SMTP(smtp_email_server, 25)
    message = system_name + '\n' + message
    msg = MIMEText(message)
    msg['Subject'] = subject
    msg['From'] = user
    msg['To'] = to
    server.sendmail(user, [to], msg.as_string())
    server.quit()
    GPIO.output(io_led1, GPIO.LOW)

def send_status_email(to,message):
    my_ip_now=get_ip()
    today = datetime.datetime.today()
    time_now = ' %s' % today.strftime('%Y %b %d  %H:%M:%S')

    io_text1='  Zone1: %i Active: %i Count: %i Name: %s \n' % (GPIO.input(io_zone1) ,zone1_active, zone1_alarm_count ,zone1_name)
    io_text2='  Zone2: %i Active: %i Count: %i Name: %s \n' % (GPIO.input(io_zone2) ,zone2_active, zone2_alarm_count ,zone2_name)
    io_text3='  Zone3: %i Active: %i Count: %i Name: %s \n' % (GPIO.input(io_zone3) ,zone3_active, zone3_alarm_count ,zone3_name)
    io_text4='  Zone4: %i Active: %i Count: %i Name: %s \n' % (GPIO.input(io_zone4) ,zone4_active, zone4_alarm_count ,zone4_name)
    io_text5='  Zone5: %i Active: %i Count: %i Name: %s \n' % (GPIO.input(io_zone5) ,zone5_active, zone5_alarm_count ,zone5_name)
    io_text6='  Zone6: %i Active: %i Count: %i Name: %s \n' % (GPIO.input(io_zone6) ,zone6_active, zone6_alarm_count ,zone6_name)
    io_text7='  Zone7: %i Active: %i Count: %i Name: %s \n' % (GPIO.input(io_zone7) ,zone7_active, zone7_alarm_count ,zone7_name)
    io_text8='  Zone8: %i Active: %i Count: %i Name: %s \n' % (GPIO.input(io_zone8) ,zone8_active, zone8_alarm_count ,zone8_name)

    max_text1='  A Maximum of %i Alarm Email can be sended every %i Seconds \n' %(email_max_qte,email_max_timelaps) 
    max_text2='  Alarm Emails recently sended: %i \n' % email_max_count
    max_text3='  Alarm Emails skipped: %i  \n' % email_max_skiped_qte 

    io_text=io_text1 +io_text2 +io_text3 +io_text4 +io_text5 +io_text6 +io_text7 +io_text8 +max_text1 + max_text2 + max_text3

    sendemail(to,system_name+message, '\n Message: '+message+ '\n'+io_text+'\n Boot time:'+boot_time+ '\n Time Now:'+time_now+ '\n IP Boot :'+my_ip_boot+'\n IP Now  :'+my_ip_now+'\n Code Ver:'+code_version)

#########################
#        MAIN           #    
#########################
print'                                   '
print' J-F Payeur Alarm system                ' 
print' For Raspberry PI board v1.0'
print' BCMio Output 17,18 Input 23,24,25,4    '
print'                                   '
print'  To kill use ctrl-c' 
print'  If in background, find the PID  -->ps -ef | grep python'
print'  and kill the pid  -->kill -9 PID '
print' '

GPIO.cleanup()
GPIO.setmode(GPIO.BCM) # to use Raspberry Pi bcm chip pin numbers
GPIO.setwarnings(False) #remove anoying warning    
GPIO.setup(io_led1, GPIO.OUT) #status led output
GPIO.setup(io_led2, GPIO.OUT) #
GPIO.setup(io_zone1, GPIO.IN, pull_up_down=GPIO.PUD_UP) #alarm zone 1
GPIO.setup(io_zone2, GPIO.IN, pull_up_down=GPIO.PUD_UP) #alarm zone 2
GPIO.setup(io_zone3, GPIO.IN, pull_up_down=GPIO.PUD_UP) #alarm zone 3
GPIO.setup(io_zone4, GPIO.IN, pull_up_down=GPIO.PUD_UP) #alarm zone 4
GPIO.setup(io_zone5, GPIO.IN, pull_up_down=GPIO.PUD_UP) #alarm zone 5
GPIO.setup(io_zone6, GPIO.IN, pull_up_down=GPIO.PUD_UP) #alarm zone 6
GPIO.setup(io_zone7, GPIO.IN, pull_up_down=GPIO.PUD_UP) #alarm zone 7
GPIO.setup(io_zone8, GPIO.IN, pull_up_down=GPIO.PUD_UP) #alarm zone 8
GPIO.setwarnings(True) #warning back just in case 

#print 'Get boot time'
today = datetime.datetime.today()
boot_time = ' %s' % today.strftime('%Y %b %d  %H:%M:%S')
my_ip_boot=get_ip()

periodic_report_thread = threading.Thread(target=periodic_report)
periodic_report_thread.start()

periodic_test_thread = threading.Thread(target=periodic_test)
periodic_test_thread.start()

periodic_email_max_reset_thread = threading.Thread(target=periodic_email_max_reset)
periodic_email_max_reset_thread.start()

#Read input 
if(GPIO.input(io_zone1)==False):
    print' Zone1:Secure'
else:
    print' Zone1:Alarm'
if(GPIO.input(io_zone2)==False):
    print' Zone2:Secure'
else:
    print' Zone2:Alarm'
if(GPIO.input(io_zone3)==False):
    print' Zone3:Secure'
else:
    print' Zone3:Alarm'
if(GPIO.input(io_zone4)==False):
    print' Zone4:Secure'
else:
    print' Zone4:Alarm'

print'Send Boot Emails'
send_status_email(status_email1,'Starting System ')

print'System armed' 
while 1:
    try:
        today = datetime.datetime.today()
        now_time = ' %s' % today.strftime(' %d%b %H:%M:%S')

        flashing_led=flashing_led+1
        if (flashing_led==500):
            GPIO.output(io_led2, GPIO.LOW)
        if (flashing_led==1000):
            GPIO.output(io_led2, GPIO.HIGH)
            flashing_led=0

        if(zone1_active==True): #test
            if((GPIO.input(io_zone1) == False)&(latch_zone1==0)):
                time.sleep(0.2) #cheap debounce 
                latch_zone1=1
                print 'Zone1 Secure '
                sendemail_alarm(alarm_email1,'Zone1 Secure'+now_time,'Zone1 Secure:'+zone1_name)
            if(((GPIO.input(io_zone1) == True)&(latch_zone1==1))|(test==1)):#test
                time.sleep(0.2) #cheap debounce 
                test=0#test
                zone1_alarm_count=zone1_alarm_count+1
                latch_zone1=0
                print 'Zone1 Triger, Sending email'
                sendemail_alarm(alarm_email1,'Zone1 Alarm'+now_time,'Zone1 Alarm:'+zone1_name)

        if(zone2_active==True):
            if((GPIO.input(io_zone2) == False)&(latch_zone2==0)):
                time.sleep(0.2) #cheap debounce 
                latch_zone2=1
                print 'Zone2 Secure  '
                sendemail_alarm(alarm_email1,'Zone2 Secure'+now_time,'Zone2 Secure:'+zone2_name)
            if((GPIO.input(io_zone2) == True)&(latch_zone2==1)):
                time.sleep(0.2) #cheap debounce 
                zone2_alarm_count=zone2_alarm_count+1
                latch_zone2=0
                print 'Zone2 Triger, Sending email'
                sendemail_alarm(alarm_email1,'Zone2 Alarm'+now_time,'Zone2 Alarm:'+zone2_name)

        if(zone3_active==True):
            if((GPIO.input(io_zone3) == False)&(latch_zone3==0)):
                time.sleep(0.2) #cheap debounce 
                latch_zone3=1
                print 'Zone2 Activated'
                zone2_active=True
                send_status_email(status_email1,'Zone2 Activated')
                
            if((GPIO.input(io_zone3) == True)&(latch_zone3==1)):
                time.sleep(0.2) #cheap debounce 
                latch_zone3=0
                print 'Zone2 Unactivated'
                zone2_active=False
                send_status_email(status_email1,'Zone2 Unactivated')

    except:
        print'Exit'

        periodic_report_thread._Thread__stop() 
        periodic_test_thread._Thread__stop() 
        periodic_email_max_reset_thread._Thread__stop() 

        GPIO.output(io_led1, GPIO.LOW)
        GPIO.output(io_led2, GPIO.LOW)
    
        send_status_email(status_email1,' Closing System')
        send_status_email(alarm_email1,' Closing System')
        print'Sending Closing Emails'
        time.sleep(2) #time so send last email 

        sys.exit(0)
        

Install an internal SMTP server (optional)

References and Links:

List of SMS gateways
http://en.wikipedia.org/wiki/List_of_SMS_gateways

This project is mainly based on :
http://elinux.org/RPi_Email_IP_On_Boot_Debian

Help on the IO library:
http://pypi.python.org/pypi/RPi.GPIO

Help on the RPi hardware
http://elinux.org/RPi_Low-level_peripherals
http://elinux.org/RPi_BCM2835_GPIOs

Help on python
http://docs.python.org/2/library/thread.html

Other interesting Project
https://sites.google.com/site/raspilapse/home

Wanted features:

-Log event to a file (and send file with report)

-Have a web based menu to configure settings

-Put a PIR ( movement detector) directly on the board

-Have a way to activate / desactivate stuff remotly with my cell-phone  (could be thrue the web based feature)

 

Comments
You do not have permission to add comments.