Home-Automation using 433Mhz RC-Sockets

Control the power sockets using python

Depending on the distance and thickness of walls between your transmitter and power sockets, it might be necessary to send the same signal several times in a row until the socket responds. For this purpose I wrote a short python script which does that job. The script accepts two command line parameters. Usage is as simple as “rcswi <A|B|C|D|E> <ON|OFF>”. Chance the DEVICE_CODE and TIME variable to your requirements. To increase the range, you should solder an approx. 17 cm-long antenna, made from 0.8 mm copper wire to your transmitter.

import sys
import os
def usage():
 print "Usage: rcswi <A|B|C|D|E> <ON|OFF>"
def main(argv):
 if len(argv) < 2:
 usage()
 return 1
# How many times to send the signal
 TIMES = 10
# System Code, 3 ON 4 ON
 DEVICE_CODE = "00110 "
# location of the send command
 SENDCMD = "sudo /usr/local/bin/send "
# translate command line arguments
 if (sys.argv[1] == "A"):
 SOCKET = "10000 "
 elif (sys.argv[1] == "B"):
 SOCKET = "01000 "
 elif (sys.argv[1] == "C"):
 SOCKET = "00100 "
 elif (sys.argv[1] == "D"):
 SOCKET = "00010 "
 elif (sys.argv[1] == "E"):
 SOCKET = "00001 "
 else:
 usage()
if (sys.argv[2] == "ON"):
 MODE = "1"
 elif (sys.argv[2] == "OFF"):
 MODE = "0"
 else:
 usage()
# send the command five times in a row
 for i in range(TIMES):
 os.system(SENDCMD + DEVICE_CODE + SOCKET + MODE)
if __name__ == "__main__":
 sys.exit(main(sys.argv))

To switch the fish tank light light ON and OFF, I placed these two lines into my crontab:

0 23 * * * /usr/bin/sudo /usr/local/bin/rcswi A OFF
0 9  * * * /usr/bin/sudo /usr/local/bin/rcswi A ON

Web interface

For convenience, I programmed a simple web interface with few lines of php code and an “old school” table to control my sockets with a browser:

pi@raspi1 /var/www/rcswitch-pi $ more index.php
<?php
if (empty ($_POST['SWITCH']) == TRUE and (empty ($_POST['MODE']) == TRUE)) {
echo '
<form action="http://rpiserver/rcswitch-pi/index.php" method="POST">
 <h3>Welcome RasPi Control@Home!</h3>
 <p>Please select SOCKET and MODE, then press "Execute"!</p>
 <table border=0>
 <tr><td><input type="Radio" checked name="SWITCH" value="A ">&nbsp;SOCKET A&nbsp;&nbsp;&nbsp;</input></td>
 <td><input type="Radio" name="SWITCH" value="B ">&nbsp;SOCKET B&nbsp;&nbsp;&nbsp;</input></td></tr>
 <tr><td><input type="Radio" name="SWITCH" value="C ">&nbsp;SOCKET C&nbsp;&nbsp;&nbsp;</input></td>
 <td><input type="Radio" name="SWITCH" value="D ">&nbsp;SOCKET D</input></td></tr>
 <tr><td><input type="Radio" checked name="MODE" value="ON">&nbsp;ON</input></td>
 <td><input type="Radio" name="MODE" value="OFF">&nbsp;OFF</input></td><tr>
 <tr></tr>
 <tr><td><input type=submit value="Execute"></td></tr>
 </table>
</form>
';
}
elseif (empty ($_POST['SWITCH']) == FALSE and (empty ($_POST['MODE']) == FALSE)) {
 exec("/var/www/cgi-bin/rcswitch-pi " . $_POST['SWITCH'] . $_POST['MODE']);
 echo '<p>Command sent!</p>';
}
?>

In order run system commands using the php5 exec() and/or system() functions, it is necessary to add the username (owner of the /var/www/cgi-bin directory) to /etc/sudoers.

Note, that you must edit this file using visudo! For the above script, add an entry for the user www-data:

www-data localhost=NOPASSWD: /var/www/cgi-bin/rcswi #, next command

Furthermore, add the user www-data to the group sudo with:

sudo useradd -G sudo www-data

Desktop App with Tkinter

In order to control the RC sockets without a browser, I created a simple Tkinter-App which is permanently displayed as a “Desktop-Gadget”.

screenshot_20161029_122840

In order to use the code, you have to adjust both, the send_cmd and device_code variable.

#!/usr/bin/python
# -*- coding: utf-8 -*-
from Tkinter import *
import os
# global settings
device_code = "00110 "
# path to send command
send_cmd = "ssh pi@raspberry sudo /usr/local/bin/send "
# socket codes
sockets = { "A" : "10000 ", "B" : "01000 ", "C" : "00100 ", "D" : "00010 ", "E" : "00001 "}
# generate gui
class App:
 def __init__(self, master):
 frame = Frame(master)
 frame.grid()
 
 #---------------------------------------------------------------------------------------
 Label(frame, text="A", bg="blue", fg="white", padx=10, pady=4).grid(row=0, column=0)
 
 self.button = Button(frame, 
 text="ON", bg="green",
 command = lambda: self.my_switch("A", "1")
 )
 self.button.grid(row=0, column=1)
 
 self.button = Button(frame,
 text="OFF", bg="red",
 command = lambda: self.my_switch("A", "0") # please note that passing arguments to button function is not possible without lambda:
 )
 self.button.grid(row=0, column=2)
 # ---------------------------------------------------------------------------------------
 Label(frame, text="B", bg="blue", fg="white", padx=10, pady=4).grid(row=1, column=0)
 
 self.button = Button(frame, 
 text="ON", bg="green",
 command = lambda: self.my_switch("B", "1")
 )
 self.button.grid(row=1,column=1)
 
 self.button = Button(frame,
 text="OFF", bg="red",
 command = lambda: self.my_switch("B", "0")
 )
 self.button.grid(row=1,column=2)
 # ----------------------------------------------------------------------------------------
 Label(frame, text="C", bg="blue", fg="white", padx=10, pady=4).grid(row=2, column=0)
 
 self.button = Button(frame, 
 text="ON", bg="green",
 command = lambda: self.my_switch("C", "1")
 )
 self.button.grid(row=2,column=1)
 
 self.button = Button(frame,
 text="OFF", bg="red",
 command = lambda: self.my_switch("C", "0")
 )
 self.button.grid(row=2,column=2)
 # -----------------------------------------------------------------------------------------
 Label(frame, text="D", bg="blue", fg="white", padx=10, pady=4).grid(row=3, column=0)
 
 self.button = Button(frame, 
 text="ON", bg="green",
 command = lambda: self.my_switch("D", "1")
 )
 self.button.grid(row=3,column=1)
 
 self.button = Button(frame,
 text="OFF", bg="red",
 command = lambda: self.my_switch("D", "0")
 )
 self.button.grid(row=3,column=2)
 # ------------------------------------------------------------------------------------------
 Label(frame, text="E", bg="blue", fg="white", padx=10, pady=4).grid(row=4, column=0)
 
 self.button = Button(frame, 
 text="ON", bg="green",
 command = lambda: self.my_switch("E", "1")
 )
 self.button.grid(row=4,column=1)
 
 self.button = Button(frame,
 text="OFF", bg="red",
 command = lambda: self.my_switch("E", "0")
 )
 self.button.grid(row=4,column=2)
# function for transmission of socket codes
 def my_switch(self, socket, mode):
 os.system(send_cmd + device_code + sockets[socket] + mode)
 #print send_cmd + device_code + sockets[socket] + mode # uncomment to debug send command
root = Tk()
root.wm_title("Sockets")
# do not display titlebar
#root.overrideredirect(True)
app = App(root)
root.mainloop()

[2014-12-18] Update

If your are not satisfied with the range of the 433 Mhz transmitter, use the official Rasspberry USB power supply with 2.5 A.