Raspberry Pi Home Automation

This page details how I've managed to use a Raspberry Pi to control my home power sockets (including lighting), heating controls and alarm system. Also included is detail on how I've wired up a light sensor (LDR) to the Pi, in order than I can tell remotely if the lights really have turned on or off.

The back-end binaries are written in C and the (secure) web interface in PHP.

The Mains Sockets

I have some previous experience with 433 MHz remote control systems, so I decided that the best way to remotely turn sockets on and off would be to buy some remote controlled mains sockets, sniff the data sent by the remote that comes with the sockets, then simply use the Pi to replay this data, hopefully triggering the socket to turn on or off.

After a bit of gooogling, I found that Geoff Johnson had already done pretty much exactly that, with some 'Status' remote control sockets. This was the same brand of remote controlled socket that I already had, so I decided to use Geoff's code as a base for mine. No point in reinventing the wheel.

I used an oscilloscope to sniff the code transmitted by the Status remote control and broke the code down into its consituant parts - Pre/Post Amble, Device Code, On/Off and Channel. These are described below:

  • Pre/Post Amble: A series of high/low pulses used to get the Auto Gain Control (AGC) in the receiver up and running.
  • Device Code: An important code that is unique to each remote control. If the manufacturer were lazy and simply shipped each remote with the same unique device code then you'd run into all kinds of problems, especially if your neighbour had the same sockets! As it is, the socket knows to only listen to the remote used to 'teach' it, and no other remote.
  • On/Off: Self explanatory - a bit that signifies whether or not the socket should turn on or off.
  • Channel: The channel (1-4) to be switched.
  • Originally, I was using the Raspberry Pi built-in PLL in order to transmit to the sockets transmitting on the third subharmonic of 433.92MHz and simply soldering a wire to the PLL pin (similar set-up here), but I eventually switched to using a demo board of a dedicated Microchip rfPIC with a nicely tuned loop antenna, which gave a far superior range result. I throughly recommend Microchip's rfPICs, by the way. They are simply small 12F PICs, with a completely independant RF transmitter built on the same silicon. Very useful indeed!

    Once I'd worked out all of the above, it was fairly trivial to combine it all together and make an executable (in C) to switch my (mains controlled) lounge lights on and off.

    Scroll down to the bottom of the page to find the C code written to interface with the Microchip board and transmit to the sockets. Hopefully it's fairly self explanatory - switch.c is the relevant C file here.

    The Light Sensor

    One drawback of the remote-controlled mains sockets, is that you are never quite 100% sure if your lounge lights really have turned on or not!

    A simple way round this is to wire up a Light Dependant Resistor (LDR) to one of the GPIO pins, and give the light level feedback to the remote user via the web interface.

    The obvious problem with this idea is that the Pi doesn't have any analogue inputs, only digital. This doesn't really cause us too much of a drama though - we can cheat by using the LDR to charge a capacitor, then using the digital input in order to time how long the capacitor takes to charge. The longer it takes, the darker it is.

    There's a horrible paint drawing of the circuit I ended up with below:

    Told you it was horrible.

    The C file relevant to the light sensor is light.c. It should be fairly self explanatory - it simply sets GPIO as a low-level output in order to fully discharge the capacitor, the sets the pin as a high-impedance input and counts how long it takes for the pin to register a '1'. The longer it takes, the darker the room is. It is surprisingly very accurate indeed. Even when you turn on a tiny lamp in the corner of a room, the Pi will register a massive ambient light level change in the other corner of the room.

    The Home Alarm System

    My house currently has a BT Home Monitor VP1000 alarm system installed. It's a bit old hat these days, but it makes a loud noise when burglers smash their way through your front door, so it's probably as good as any other.

    The system also has a nifty feature whereby it'll dial up (using an 0870 number, scallies) to a central server and let it know when you're being robbed. The server will then call your mobile and send you texts and emails so that when you're sunning yourself on holiday 10,000 miles away, you can still panic about being burgled, just as if you were in the house at the time. I keep trying to disable that feature (I'd rather not know), but despite not paying the £5/month subscription for 18 months, they still insist on sending me updates. I suspect the company running it may be on their last legs.

    Anyway... The system comes with a remote keyfob that can be used to enable and disable the alarm. Unfortunately this time I couldn't simply sniff the code being sent from the fob and use the Pi to spoof the transmission because the system uses the Keeloq code rolling system. See my other site for more detail on how that sort of system works.

    In order to have the Pi control the alarm, I resorted to simply buying an additional keyfob for the alarm (the Visonic MCT-234 fob works perfectly with the BT Home Monitor system incase anyone was wondering) and manually wiring the pins on the transmitter IC inside the fob directly to the GPIO pins on the Pi. I then simply take the Pi GPIO pin high and the IC in the keyfob transmits the code just as if somebody were pressing a button on the fob. You can see the fob in the image at the top of this page, blu-tacked to the LAN header(!)

    The Central Heating

    Surely a central heating wireless thermostat wouldn't use a code rolling system?

    Luckily, mine doesn't. It's a Worcester Digistat Optimiser, as below:

    When sniffing the codes for the remote controlled mains sockets, I used an oscilloscope. However, inspired by Geoff Johnson I decided to use Audacity to sniff the codes used by my wireless thermostat. This is the 433MHz ASK receiver I've been using to receive and decode the signals, by the way.

    I fed the receiver output into my sound card (via a large resistor) and used the interface to zoom into the thermostat transmission.

    After that, it's simply a case of setting the Pi GPIO pin to go high and low for the correct amount of time (as measured in audacity), in order to drive the Microchip ASK transmitter and spoof the thermostat transmission. Now I can turn the central heating on and off directly from the Raspberry Pi.

    Now that we have binaries written in C to control the lights, alarm and central heating, we just need a web interface in order to control it all.

    The Web Interface

    This is probably the easiest part of the whole system, although hopefully as I've shown the rest isn't really too tricky.

    The web interface is simply a few PHP scripts running on an Apache server on the Pi. The PHP scripts generate the simple front-end menu system and the executables to turn the lights on etc. are called from directly within the scripts themselves, using the 'exec' command in php.

    One problem that I did run into is that the binaries I had written in C required root access to run, because they interfaced directly with /dev/mem. I could have given apache and php root access to the Raspberry Pi system, but that is a bit of a silly idea. Instead, what I did was to grant the user 'www-data' sudo access to the specific binaries that I had written. See here for a guide on how to do that.


    The web interface has a fairly sophisticated authentication scheme, which probably isn't really necessary, but I decided to be a bit elaborate and write it anyway! There is also a feature whereby a cookie can be set on a PC to save the user from having to log in on that PC. Access logs are also kept which log whenever anybody logs into the interface. These can be used to detect rogue access attempts to your central heating!


    Hopefully, the code should be fairly self explanatory. As previously mentioned, the web interface is very over-complex. You only really need about 10 lines of php code in order to achieve the same thing, but it won't have as many cool and exciting bells and whistles! Anybody with any kind of grasp of php will be able to see what's going on in the code.

    The C code should also be self explanatory, and contains the following files:

  • alarm.c: Code to interface with the Visonic MCT-234 alarm keyfob to enable and disable my home alarm system.
  • heating.c: Code to interface with my Worcester Digistat Wireless Thermostat via a Microchip 433MHz Tx module in order to control my central heating system.
  • light.c: Reads the current ambient light level and prints it to STDOUT.
  • switch.c: Interfaces with Status radio controlled mains sockets.
  • (plus a few includes used across all the above C files)

    Download a package including all source files and the web interface, here.

    Please feel free to contact me at andy@burningimage.net if you have any questions at all.

    Thanks for reading. :)