Building a home automation system – The broker and sensors (Part 2)

Every now and then (when I have time..) I do a bit of work on what’s going to become my home automation system. At the moment it’s pretty basic, it’s simply events going over a message broker that small stubs of code react to. Most of it runs on my raspberry pi and a few jeenodes (atmega328 + hoperf rfm12b radio) as wireless sensors.

Everything connects to a simple message broker built on ZeroMQ – and I love it! ZeroMQ is so great to work with, it takes most of the hassle of network socket programming away leaving you to concentrate on what really matters. There is no daemons to deal with (as with most other message buses), it’s lightning fast, but doesn’t really handle persistant messaging.

At the core of the system I have this running on my raspberry pi:

-gist-

It’s very simple – just two ZeroMQ sockets – one running in a push/pull configuration, another running in a pub/sub configuration. A relay for my sensor nodes will connect to it and push it JSON formated data from the different sensors located in my apartment.

{
"nodeid": 2,
"temperature": 2.19,
"voltage": 335,
"counter": 1215,
"event": "sensor",
"timestamp": "2012-09-24T15:49:28.369Z",
"location": "refrigerator"
},
{
"nodeid": 3,
"temperature": 23.5,
"voltage": 369,
"counter": 20,
"event": "sensor",
"timestamp": "2012-09-24T15:52:08.450Z",
"location": "livingroom-bookshelf"
}

The broker will relay events such as these, the two examples are wireless sensor nodes located in my refrigerator (currently holding 2.19C and battery voltage of 3.35v) and the other one in my livingroom bookshelf (2.19C and 3.69v). The broker will receive these (and others), and send them out to subscribers of sensor events. It makes it really easy to make something that reacts to the temperature, you can connect to the broker and subscribe to sensor events in 2-3 lines of code in most languages. Example:

-gist-

As you can see, it would be very simple to expand this and create something that let me know if a battery of a sensor was running low. Or something that would PID adjust a heating source in the living room. Or something that would warn me if temperature in the fridge was running high.. or.. or.. or.. Beauty of it is that you don’t have to think about network stuff like disconnects..

I’ve made a small program in C# running on my HTPC that registers a few global hotkeys. If I press ctrl-alt-o then a small event will be sent out from the C# program, to the message bus, to everyone that subscribes to “receiver” events. There is a small program that does this and relays the message to a microcontroller, which in turn talks to my Pioneer VSX-2016av surround receiver via the SR bus I talked about in an earlier post. For example, sending events like these to the broker will toggle the power of the surround receiver and turn the volume up 5 steps.

{
"event": "receiver",
"action": "power"
},
{
"event": "receiver",
"action": "volumeup",
"count": 5
}

Quick example above, sorry for the camera shake.

It’s getting there, now I have sensor data and control over the surround receiver. The next steps will be to expand the available sensor data – I wish to add a DHT22 Humidity sensor and also a light sensor (LDR?) to the sensor nodes soon. And also maybe PIR (passive ir). I also need to add control over power soon (lighting and heating).

At the moment they are only using a DS18B20 temp sensor. When I have all the components in place I’ll make a small PCB with room for all the components, the radio and a smaller atmel microcontroller. Currently they take up a bit more space than needed.

Building a home automation system – Part 1 (intro)

Ever since i bought my own apartment 1.5 years ago I’ve been thinking about adding a bit of home automation. Given an API to sensors, lighting, heating and other electronic devices there are so many smart things you could do. 

Using temperature sensors and control over heating you could PID-control (see my sous-vide cooker) indoor temperatures way better than any regular termostat could. And it would be easy to add day and night temperatures. You could make it fully automatic (integrated with your calendar), or control it yourself (turn up heating remotely a cold winter day when you’re on your way home).

Given access to lighting sensors (I already have a few LDRs running, logging lighting level to cosm) and lighting controls (dimmer) you could do lots of fun stuff. For example gradually increase lighting in the bedroom minutes before the alarm goes off in the morning. You could gradually increase lighting as the sun sets in the evening. You could automatically dim the lights when starting a movie in XBMC and revert to previous level on pause/stop. Given motion detectors (passive IR) you could turn off lights in empty rooms, or even have a “last-man-out” button next to your door that turns everything off.

I want automatic blinds (sun really strong and I’m not home? turn down the blinds..).. etc.. etc.. I want the coffee-maker to automatically disconnect 45 minutes after making a brew – and I want to start it from bed. There are so many possibilites.

Some time back I bought a small collection of jeenodes, they are small boards with atmega328s (arduino compatible) and a HopeRF 868 mhz radio (RFM12B). The design is open source, so you can make them yourself or buy them from jeelabs: http://jeelabs.com/products/jeenode

I’m using a couple of them with DS18B20 temperature sensors and LDR (lighting sensor) to collect and graph temperature/lighting data via cosm.com. They have performed really well, and the 868 mhz spectrum seems mostly clean here were I live. I made a quick spectrum analyzer last year to have a look:

RFM12b+Jeenode based 868 Mhz spectrum analyzer from Stian Eikeland on Vimeo.

For a home automation system there is lots of choices to be made, both for hardware and for software. I’ll try to make a series of this describing the solution I go for. One of the first steps will be to find a suitable (wireless) hardware power control solution (on/off + dimming for lights and power sockets). I want it all to be event-driven, and need some way of passing events from component to component – a message bus of some sort. In the next posts in this series I’ll look at that.