Controlling LightwaveRF panels with a Raspbery Pi

I hate waking up in winter with an alarm when everything is still dark and gloomy, and would much prefer to wake up more naturally with light.  You can buy various “daylight alarms”, but they are just more clutter to have in the room, and it felt unnecessary to buy something  when the room already has a perfectly good light hanging from the ceiling.  I just needed a way to control it.

There are various WiFi enabled light bulbs around, but they all have the same basic flaw, that if the wall switch is turned off, no wifi in the world is going to turn the bulb on again.  This means you would need to always use a phone/remote to control the light, rather than being able to use a normal switch as well.

Eventually I came across “LightwaveRF” units, which replace the switch with a dimmer, and then you use a normal dimmable bulb.  The switches are about £30, but to connect it to a network you also need their wifi link, which is £50.  This would push the price up to £80, which isn’t too crazy compared to the price of some wifi bulbs, but I wanted to do it cheaper than this, and learn something about using the GPIO pins on the Pi as well.

 

Fortunately the RF signal the panels use is a standard 433Mhz, and you can get transmitters for this frequency for the huge cost of £1.

rf

All I needed now was to find out exactly what signal to transmit to control the panels from the Pi.  Fortunately all the hard work has been done by someone else: https://github.com/roberttidey/LightwaveRF  This github project provides C libraries for the Arduino and Pi to transmit and receive using the LightwaveRF protocol.  It also provides python bindings which is perfect.

Hardware

Obviously first replace your existing light switch with the Lightwave one.  This was a bit of hassle because it’s deeper than a normal panel, so you might need to excavate the wall a bit to get it to fit.

Then connect the 5v (vcc), data and ground pins to the Pi, noting which pin on the Pi you connect the data to.  If you’re not sure which pins on the Pi are which, refer to this website.

Pigpio

LightwaveRF has a dependency on “pigpio” which is a C library used to control the GPIO pins on the Pi. Follow the pigpio instructions to download and install this.  If you get errors when running ‘make’ to build this, check you have the necessary python packages:

sudo apt-get install build-essential

You should be able to install any other missing packages using ‘apt’ as well.

This will install the pigpio C libraries, a daemon – ‘pigpiod’ – that runs in the background, and a python library that can be ‘import’ed into scripts.

Once installed, start the daemon by running: ‘pigpiod’.  If it starts OK it will just silently return.

LighwaveRF

Create a location somewhere on your pi, and copy the ‘lwrf.py‘ file from the github project into it.

Then create a test file with the below contents in the same location:

import sys
import pigpio
import lightwaverf.lwrf

# This is a simple test class for the lwrf and pigpiod programs.

# The GPIO pin on the Pi you've connected the transmitter to.
# You probably need to change this!
gpio_pin = 7

# How often to repeat the signal, 3 seems to be OK.
repeat = 3

# An ID that must be unique for each dimmer. 
id = 1

pi = pigpio.pi() # Connect to GPIO daemon.
tx = lightwaverf.lwrf.tx(pi, gpio_pin)

# this should be between 0 and 32
value = int(sys.argv[1])

if (value == 0):
  tx_val = 64 # according to the LightwaveRF docs, when turning off, this should be 64.
  c = 0 # "command" setting i.e. on/off
else:
  tx_val = value + 128
  c = 1

a = tx_val >> 4 # first 4 bits
b = tx_val % 16 # last 4 bits
data = [a, b, 0, c, 15, id, 0, 0, 0, 0]
tx.put(data, repeat)
print("Sent " + str(value))
tx.cancel();
pi.stop();

Edit the file with the ‘gpio_pin’ you connected the transmitter to, the other values can be left as they are.

Test this runs OK this with python, supplying an example brightness:

python test.py 10
Sent 10

If you get errors, check that that the pigpiod daemon is running.

Before it will actually do anything, you need to pair the transmitter with the panel.  LightwaveRF panels don’t have their own unique addresses, instead they need to be given an ID to respond to.  Each panel can remember up to 6 IDs and they will then respond to any signals transmitted with that ID.

To put the panels into “learning” mode, press and hold both panel buttons until the orange and blue lights start flashing alternately.  This “learning” mode lasts for about 15sec, so when the lights are still flashing, run the script above again.  The blue light only should then flash to indicate it has paired successfully. Refer to the LightwaveRF dimmer manual for more details.

Now running the python script again (with an argument between 0 and 32) should actually control the light!

Of course having to boot a laptop, ssh into a Pi and run some python is somewhat inconvenient just to turn a light on. I’ve written a very simple website that can be used to control the light.

Advertisements

Energy monitoring with a Raspberry Pi

A lot of energy companies have given away free electricity meters.  These have a clamp you put round the house supply, and a wireless link to a display.  They are generally branded by the energy company, but a lot of them are Current Cost EnviR meters.  If you look on the back, there is what appears to be an ethernet port, but is actually a serial connection in disguise.  You can get a usb data cable that connects to the Pi, and enables you to read an XML string from the meter, with the current power and temperature.  You’ll need to hunt around the interwebs for this, search  “Current Cost Data Cable” to try and find one on amazon or ebay.

Once you have the cable and it’s connected up, you can use a few lines of python to read the data.

import serial
serialObj = serial.Serial("/dev/ttyUSB0", 57600, timeout=6)
xml = serialObj.readline()
print(xml)

Running this should output something like:

<msg><src>CC128-v1.29</src><dsb>00484</dsb><time>20:16:49</time><tmpr>17.8</tmpr><sensor>0</sensor><id>00077</id><type>1</type><ch1><watts>00270</watts></ch1></msg>

You can then use a regular expression, or XML library to extract the data and do something useful with it. The example below sends it to a Graphite instance that is running on the Pi.

e.g.

import serial
import re
import urllib2
import time
import socket

serialObj = serial.Serial("/dev/ttyUSB0", 57600, timeout=30)
xml = serialObj.readline()
print "xml: " + xml
m = re.search('(.*)',xml)
power = m.group(1)
print 'Power: ' + power

# This conditional exists because occasionally the energy monitor returns an incorrectly low number.
if (int(power) &amp;gt; 10):
# Send the data to graphite
sock = socket.socket()
sock.connect( ("localhost", 2003) )
sock.send("house.power %d %d \n" % (int(power), time.time()))
sock.close()

See the next blog post for details on how to configure Graphite on a Raspberry Pi

If it all works, you’ll be able to end up with graphs like this: