dimanche 26 avril 2015

Wireless alarm with a Raspberry Pi with python

Part1 Presentation and materials


I always wanted to build an alarm for my house,it's done. i offer you to share my project. I let you see the snapshot of the web interface.


When alarm is fired, i receive a sms and mail with the name of the sensor. I can enable/disable the alarm from a smartphone or any device connect to internet. In order to be more usefull, i can schedule the alarm with a template week (see snapshot). It's written in python, php and mysql.
And then why not add a temperature sensor to optimize the rasp (under construction).

Sensors and electronic's components

At start, i was looking for a sample to develop my project. i found this excellent article from Hackspark'site (a french electronic store) : Connect wireless sensor. Then i bought alarm's sensor contactor and  motion detector RF433
and a simple RF433 link kit .

To resume, we need :
- Raspberry connect to internet
- sensor contactor, motion detector
- RF433 Kit (receiver, send)

Part 2 Communication

Wireless alarm with a Raspberry Pi with python

Part 2 : Communication RF 433

Raspberry configuration :
  • wheezy-raspbian
  • mysql
  • php
  • apache2
  • python
  • iptables
A tutorial: install apache php and mysql.I think you are happy when you have installed it all.

Now we will focus on the communication part, the aim of this tutorial is to create a library c++ calling by python


  • At first we need to install WiringPi, we have just to follow the instructions in this post Controlling 433MHz RF outlets.

  • Next install RPi_utils from post RPi_utils. After compiled library ninjablocks/rc-switch ( make All ) copy files "cp rc-switch/* RPi_utils -r"

Now we have something like that (see screenshot):

It's time to make an external library calling by python , create the file "Receipe.cpp" in this directory :

 /*  
  RF_Sniffer  
  Hacked from http://code.google.com/p/rc-switch/  
  by @justy to provide a handy RF code sniffer  
 */  
 #include "RCSwitch.h"  
 #include <stdlib.h>  
 #include <stdio.h>  
 class Wrapper{  
  private :  
       RCSwitch mySwitch;  
  public:  
       void init(){  
              // This pin is not the first pin on the RPi GPIO header!  
              // Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/  
            // for more information.  
           int PIN=2;  
           if(wiringPiSetup() == -1)  
           return;  
           mySwitch=RCSwitch();  
           mySwitch.enableReceive(PIN); // Receiver on inerrupt 0 => that is pin #2  
       }  
      bool available(){  
         return mySwitch.available();  
      }  
      int getReceivedValue(){  
               return mySwitch.getReceivedValue();  
      }  
      void resetAvailable(){  
           mySwitch.resetAvailable();  
      }  
 };  
 extern "C"  
 {  
  Wrapper* newReceiver(){       
   return new Wrapper();  
  }  
  void Receiver_init(Wrapper* wrapper){  
   wrapper->init();  
  }  
  bool available(Wrapper* wrapper){  
   return wrapper->available();  
  }  
  int getReceivedValue(Wrapper* wrapper){    
      return wrapper->getReceivedValue();  
  }  
  void resetAvailable(Wrapper* wrapper){  
     wrapper->resetAvailable();    
  }  
  }  

Now we need to compile the lib to get  "libReceive.so"  !

 g++ -c -Wall -fPIC Receive.cpp -o Recieve.o -lwiringPi  -DRPI
 g++ -shared -Wl,-soname,libReceive.so -o libRecieve.so Receive.o RCSwitch.o -lwiringPi  

But there is a small problem, the lib is written in c, and i want all my code in python. How use libReceive.so, i need to use a wrapper (c/python). 
I didn't find it on internet, so i decided to write it ! Just create a file ReceiveRF433.py :
 from ctypes import cdll  
 lib = cdll.LoadLibrary('/ScriptPython/libRecieve.so')  
 class Receive(object):  
  def __init__(self):  
      self.obj =lib.newReceiver()  
  def init(self):  
      lib.Receiver_init(self.obj)  
  def available(self):  
      return lib.available(self.obj)  
  def getReceivedValue(self):  
      return lib.getReceivedValue(self.obj)  
  def resetAvailable(self):  
      lib.resetAvailable(self.obj)  

 Great now , we are ready to test the connexion, we have to connect the receiver kit to RaspberryPi, and switch on the a sensor.

Connect Receiver RF433 to PI

by default  the  Receiver pin is  GPIO2. The 7th pin from the left.


test communication (test.py) :

 #!/usr/bin/env python  
 # coding: utf-8  
 import time  
 from datetime import datetime,timedelta  
 from ReceiveRF433 import Receive  
 """ DATA RECEIVE """  
 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==5578064 :  
                       #Open Window  
                          print "window open"  
                          #print Select()  
                          if next_time<datetime.now() and Select()==1 :                                
                               next_time=2*period+datetime.now()  
                               print "window open code %d" %data  
                     if data==53196 :  
                          #sensor detect  
                           print "opened"  
                          #print Select()  
                          if next_time<datetime.now() and Select()==1 :                                
                               next_time=2*period+datetime.now()  
                               print "sensor code %d" % data  
                     print "Code : %d" % data  
                     #erase receive data  
                     R.resetAvailable()  
                     continue  
           except KeyboardInterrupt:  
                break          
 StartAlarmeRF433()  

the sensor send "3855" when the windows is open.

The next step is to create a deamon to run the script when the raspberry is switch on.

Next Daemon service