Raspberry Pi PLC/Domotica testcase

Here’s a quick tutorial on how to build a hardware on/off switch which sends this signals to a RESTful web API using Raspberry PI with Raspbian. This is in fact a small PLC testcase (proof of concept). The possibilities are in fact endless!
I’m planning to use this to monitor certain events around my house. E.g. is a door open/closed? Is a device on/off?

Download & install Raspberry

Download the latest version of Raspbian onto your Raspberry PI SD card:
http://www.raspberrypi.org/downloads

Updates & depencies

Do some updates + install extra depencies:

apt-get update
apt-get install python, py-pycurl

Setup the hardware

In order to know the GPIO’s pins you’ll have to find the input/output pins. Here’s a map:

raspberry-gpio
Connect your Raspberry’s GPIO (the big black serial thing) to some switch or toggle. Here’s how I did it (testcase):

raspberry-pi-gpio-switch

We actually need 3 pins. One for I/O, one for power, and one for grounding (safety first!). Make sure you solder the right cable to the right GPIO pin (see map above).

Now you might experience the naming of these pins are confusing. That’s because there’s 3 type’s of naming conventions used here..

Pin Numbers RPi.GPIO Raspberry Pi Name BCM2835
P1_01 1 3V3
P1_02 2 5V0
P1_03 3 SDA0 GPIO0
P1_04 4 DNC
P1_05 5 SCL0 GPIO1
P1_06 6 GND
P1_07 7 GPIO7 GPIO4
P1_08 8 TXD GPIO14
P1_09 9 DNC
P1_10 10 RXD GPIO15
P1_11 11 GPIO0 GPIO17
P1_12 12 GPIO1 GPIO18
P1_13 13 GPIO2 GPIO21
P1_14 14 DNC
P1_15 15 GPIO3 GPIO22
P1_16 16 GPIO4 GPIO23
P1_17 17 DNC
P1_18 18 GPIO5 GPIO24
P1_19 19 SPI_MOSI GPIO10
P1_20 20 DNC
P1_21 21 SPI_MISO GPIO9
P1_22 22 GPIO6 GPIO25
P1_23 23 SPI_SCLK GPIO11
P1_24 24 SPI_CE0_N GPIO8
P1_25 25 DNC
P1_26 26 SPI_CE1_N GPIO7

Anyway, let’s move on and try & catch the GPIO’s input using python.

Read GPIO signals using Python

plc.py (daemon script)

import RPi.GPIO as GPIO
import time
import os
 
buttonPin = 07
GPIO.setmode(GPIO.BOARD)
GPIO.setup(buttonPin,GPIO.IN)
 
while True:
  if (GPIO.input(buttonPin)):
    os.system("sudo python /home/pi/plc_handle.py")
    #print "button called"

plc_handle.py

import time
import RPi.GPIO as GPIO
import datetime
import pycurl, json
 
buttonPin = 07
GPIO.setmode(GPIO.BOARD)
GPIO.setup(buttonPin,GPIO.IN)
 
# reset state
last_state = -1
 
while True:
  input = GPIO.input(buttonPin)
  now = datetime.datetime.now()
 
  # check if value changed
  if (input != last_state) :
    	print "Button state is changed:",input, " @ ",now
	api_url = "webserver.com/api/input.php"
	data = "location_id=1&status=%s" % input
	c = pycurl.Curl()
	c.setopt(pycurl.URL, api_url)
	c.setopt(pycurl.POST, 1)
	c.setopt(pycurl.POSTFIELDS, data)
	c.perform()
 
  # update previous input
  last_state = input
 
  # slight pause to debounce
  time.sleep(1)

You can run this script doing this:

sudo python /home/pi/plc.py

Or add it to /etc/rc.local (so it runs after each reboot)

python /home/pi/plc.py
exit 0

Web API

Here’s a quick (and unsafe) ‘API’ script for receiving the Raspberry signals:
input.php

<?
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
 
$dbh = new PDO('mysql:host=localhost; dbname=database', 'username', 'password');
 
$response = array(
    'status'    => 'nok'
);
 
if(!Empty($_POST['location_id']))
{
    $status = $_POST['status'];
    $location_id = $_POST['location_id'];
 
    // create log
    $sql = "INSERT INTO status_log (location_id, status, created_at, updated_at) VALUES (:location_id, :status, NOW(), NOW())";
    $q = $dbh->prepare($sql);
    $q->execute(array(':location_id' => $location_id,
                      ':status'      => $status));
 
    // update location  
    $sql = "UPDATE location SET status=:status, updated_at=NOW() WHERE id=:location_id";
    $q = $dbh->prepare($sql);
    $q->execute(array(':location_id' => $location_id,
                      ':status'      => $status));
 
    // output
    $response = array(
        'status'    => 'ok'
    ); 
}
 
echo json_encode($response);
?>

 
Now I’m very curious what sort of applications you guys are building with this Raspberry Pi “plc implementation”. Feel free to post them in the comments section.

Usefull links