samedi 2 mai 2015

Wireless alarm with a Raspberry Pi with python

Part 4 : Send Alarm

The best way to alert someone is to phone it and let him a record. But i search an easy way to do it, finally i decided to send a sms and a mail. Most of the time, where i am not at home, i am at work and i can read my mails, or i keep a mobile phone on me.

Send mail

We need to install SSMTP :

  sudo apt-get install ssmtp  

next we have to create a piece of code to in ptyhon to send mail using this lib :

 import smtplib  
 from email.mime.text import MIMEText   
 def Send(Destinataire,Msg):  
      s =smtplib.SMTP('smtp.gmail.com:587')  
      s.starttls()  
      s.login('XXXXXXXX@gmail.com','XXXXXXXX')  
      s.sendmail('XXXXXXXXX@gmail.com',Destinataire ,Msg)  
      s.quit()  


Send SMS

The code can change according your phone operator. In my case i use french operator "Free Mobile". This operator offer a free web service to send a sms to myself, very useful for home automation .

The code below :

 #!/usr/bin/python  
 # -*- coding: utf-8 -*-  
 import urllib,urllib2  
 def SendSMS(Message):  
      #remplace les espaces du message par des %20  
      Message=Message.replace(' ','%20')  
      # URL du formulaire  
      url = 'https://smsapi.free-mobile.fr/sendmsg'  
      #Champ et valeur du formulaire  
      params = urllib.urlencode({'user': 'XXXXXXX','pass':'XXXXXXXX'})  
      #Message espace remplace par des %20  
      #params =params + '&msg=Alarme%20Intrusion'  
      params =params + '&msg=' + Message  
      #Envoi de la requête  
      req = urllib2.Request(url+'?'+ params)  
      response=urllib2.urlopen(req)  

Nice, now we made the sensors communication, Daemon service to start alarm and the way to send message. It remains two tasks :
  • the database to remeber the alarm state,
  • web site.
Part 5 Database (mysql)

vendredi 1 mai 2015

Wireless alarm with a Raspberry Pi with python

Part 3 : Create a "Daemon" for alarm

in the folder "cd /etc/init.d/". Create a file "alarme.sh" put the following code inside :

 #!/bin/sh  
 ### BEGIN INIT INFO  
 # Provides:     myservice  
 # Required-Start:  $remote_fs $syslog  
 # Required-Stop:   $remote_fs $syslog  
 # Default-Start:   2 3 4 5  
 # Default-Stop:   0 1 6  
 # Short-Description: Put a short description of the service here  
 # Description:    Put a long description of the service here  
 ### END INIT INFO  
 # Change the next 3 lines to suit where you install your script and what you wa$  
 DIR=/myScriptPython  
 DAEMON=$DIR/Alarme.py  
 DAEMON_NAME=alarme  
 #PATH=/usr/sbin:/usr/bin:/sbin:/bin:/myScriptPython  
 # Add any command line options for your daemon here  
 DAEMON_OPTS=""  
 # This next line determines what user the script runs as.  
 # Root generally not recommended but necessary if you are using the Raspberry P$  
 DAEMON_USER=root  
 # The process ID of the script when it runs is stored here:  
 PIDFILE=/var/run/$DAEMON_NAME.pid  
 . /lib/lsb/init-functions  
 #PATH=/usr/sbin:/usr/bin:/sbin:/bin:/ScryptPython  
 # Add any command line options for your daemon here  
 DAEMON_OPTS=""  
 # This next line determines what user the script runs as.  
 # Root generally not recommended but necessary if you are using the Raspberry P$  
 DAEMON_USER=root  
 # The process ID of the script when it runs is stored here:  
 PIDFILE=/var/run/$DAEMON_NAME.pid  
 . /lib/lsb/init-functions  
 do_start () {  
   log_daemon_msg "Starting system $DAEMON_NAME daemon"  
   start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --$  
   log_end_msg $?  
 }  
 do_stop () {  
   log_daemon_msg "Stopping system $DAEMON_NAME daemon"  
   start-stop-daemon --stop --pidfile $PIDFILE --retry 10  
   log_end_msg $?  
 }  
 case "$1" in  
   start|stop)  
     do_${1}  
     ;;  
  log_daemon_msg "Starting system $DAEMON_NAME daemon"  
   start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --$  
   log_end_msg $?  
 }  
 do_stop () {  
   log_daemon_msg "Stopping system $DAEMON_NAME daemon"  
   start-stop-daemon --stop --pidfile $PIDFILE --retry 10  
   log_end_msg $?  
 }  
 case "$1" in  
   start|stop)  
     do_${1}  
     ;;  
   restart|reload|force-reload)  
     do_stop  
     do_start  
     ;;  
   status)  
     status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?  
     ;;  
   *)  
     echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"  
     exit 1  
     ;;  
 esac  
 exit 0  

Modify this part to your configuration :
DIR=/myScriptPython (set your own path here )
DAEMON=$DIR/Alarme.py (set the name of your python file to run)
DAEMON_NAME=alarme (set the name of the service Daemon) 

As you can see the daemon start a python file, here "Alarme.py". It's the main part of the alarm.

File "Alarme.py" :

Here a sample of code you write. The code  use 3 functions :
  • sendAlarme(message) (which contains SendSMS,SendMail).
  • def SelectHourPlanning():
  • def StartAlarmeRF433():
We will focus for the moment on the StartAlarmeRF433's function.

 #!/usr/bin/env python  
 # coding: utf-8  
 import time  
 from datetime import datetime,timedelta  
 from SendSms import SendSMS  
 from SendMail import Send  
 from ReceiveRF433 import Receive  
 from DBAlarmeState import Select,Update  
 from PlanningDB import GetPlanningDB  
 """ DATA RECEIVE """  
 def sendAlarme(message):  
     SendSMS(message)  
     Send("TOTO@gmail.com",message)  
 def SelectHourPlanning():  
     #get planing from base  
     planning=GetPlanningDB()  
     heure=time.localtime().tm_hour+2  
     mydate=datetime.now()  
     jour=mydate.weekday()  
     #print "Planning hour %s" %heure  
     #print "Planning set to %s" %planning[jour*24+heure]  
     return planning[jour*24+heure]  
 def StartAlarmeRF433():  
     #gestion du timer  
     period=timedelta(minutes=1)  
     next_time = datetime.now() + period  
     #Initialise la liaison RF433 pin 2      
     R=Receive()  
     R.init()  
     while True:  
         try:  
             if R.available():  
                 data= R.getReceivedValue()  
                 if data==57464 :  
                     #Motion sensor  
                     #print Select()  
                     if next_time<datetime.now() and SelectHourPlanning()=="1" and Select()==1 :  
                         sendAlarme("Alarm Motion")  
                         next_time=2*period+datetime.now()  
                 if data==3855 :  
                     #Door  
                     #print Select()  
                     if next_time<datetime.now() and SelectHourPlanning()=="1" and Select()==1 :  
                         sendAlarme("Alarm door")  
                         next_time=2*period+datetime.now()  
                 #print "Code : %d" % data  
                 #efface les donnees recues  
                 R.resetAvailable()  
                 continue  
         except KeyboardInterrupt:  
             break 
StartAlarmeRF433() 

Tips : i recommand you to use Dos2unix if you import file from windows (end of line). execute : "Dos2unix *.py" to convert your python's file for RaspBerry.

what does StartAlarmeRF433 ?
it's a infinity loop, waiting a detection of sensors. When a sensor is activated, the code of sensor is received ( if data==3855 :) .

Before send alarm, the code check  delay between  the previous alarm( 2 minuts minimum between each alarm). then code check   if activation of the alarm is made by user and finally send message by mail and sms.

Next part  "Send Alarm".