The term IoT has seemingly sprung up out of nowhere recently. It stands for Internet of Things, and from everything I hear it is going to be big - both in the enterprise and for individuals / households. In the last year I've been drawn into this as a hobby, exploring how I can improve my home to (possibly) improve my life. Now that I have an understanding and have completed a few projects, I thought I would blog about them to detail my experiences.
In short, I've been doing a bit of electronics and a lot of coding, and now my house is smarter than it was. The thing is, once you start linking parts of your house together, you start thinking of even more things you can do.....if only you did a little more coding or wiring! :-) So, this blog post covers where I am right now, and I'll also try to cover some of the ideas I have for future projects (when time permits).
I must warn you - this is a long post! I decided against splitting it up into multiple posts, instead deciding to rely on you, the reader, to bite off chunks of the post as your precious time permits :-)
I think the project that really tempted me into home automation / IoT is the openHAB project. I was at Devoxx in Antwerp, Belgium in 2012 and attended a session presented by Kai and Thomas on the openHAB project, and could instantly see the value of their work. In short, openHAB is an event bus over which home automation events are sent. These events are created by items around the home. To link these items into openHAB you use bindings, and as of now openHAB ships with well in excess of 40 bindings, for all kinds of things (like Philips Hue light bulbs, XBMC, KNX, ZWave, Tivo, etc, etc, etc). In other words, lots of things! Bindings are relatively trivial to write (assuming the hardware they talk to exposes a means of communication), and there is a community of developers constantly improving and adding new bindings - I even developed two (one for the OpenSprinkler system, and another for Tivo devices).
The other nice thing about openHAB is that it has a rules system, so you can have openHAB respond to events by doing things or firing additional events based upon conditions being met. I have written a lot of rules, and will talk about some of them below! :-)
Initially, I explored using openHAB on a Raspberry Pi device, but even after fixing a few memory leaks in openHAB (thank goodness for open source!) I found it was just not responsive enough for my liking (especially when attempting to communicate with openHAB via its Android application). For people starting out with openHAB , if you have a Pi lying around, there is no harm starting there - it is trivial to move to another device at a later stage. What I moved to was a small, low-power PC I had lying around. This provided way more CPU and memory and openHAB was significantly more responsive.
First project: water tank filling
My house is not connected to a city water supply, which means all water comes via whatever is collected on the roof, and stored in an underground tank. Well, that is not entirely true: there are four taps scattered around my property that have very low-pressure water that comes from an external water source. In times of desperation (e.g. during the summer droughts) we have used this water supply to top up our water tank, and it has been a life saver (not to mention the savings to my bank balance - last year others around us had to bring in 5-10 truckloads of water to keep the water flowing over the summer dry spell)! Not wanting to be wasteful of this wonderful resource we have, we were always conscious to turn the tap off as soon as we thought the tank was full, but we could never be certain, and almost certainly we occasionally wasted water by leaving it running over night one too many nights in a row.
My idea was simple: run a water pipe under ground from the nearest tap and into the water tank. I could use a 24VAC solenoid water valve to remotely open and close the flow of water into the tank, and I could mount an ultrasonic sensor at the top of the water tank to measure how full it was. My current progress on this project is that I have done the first half (underground hose into tank with water valve), but the ultrasonic sensor is still a work in progress (I need to find time to get back under my house and run another cable).
To achieve this, I purchased the previously-mentioned OpenSprinkler Pi, and run a cable from my Pi (in my server closet) to a water valve (located under my house and near to the water tank). I also drilled a hole into the side of the tank (above the max water level, obviously!) and run a pipe from the valve into the tank. I then wrote the OpenSprinkler binding (there is a video I made that demonstrates this binding in action - beware of the Kiwi accent!) for openHAB, and configured my openHAB instance to make use of this binding. This allows me to open and close the water valve from my phone, which is good, but isn't much better than what we had previously (except I guess the plumbing is now entirely hidden under ground and under the house).
This will improve, however, once the ultrasonic sensor is mounted at the top of my water tank. Once that goes in I can trivially write rules to open the valve when the tank level reaches 50%, and to stop filling once it reaches 80% (or whatever criteria I want - my main goal is to minimise wear and tear on the valve related to switching state). This means that the tank will remain full all year round without ever needing intervention from me! It will also warn me when someone forgets to turn a hose off and uses up all the water (this has happened once or twice when we were painting the house last summer - it was not a good thing!) :-)
In writing the OpenSprinkler binding for openHAB, I enabled it to run in two different modes. The first mode I wrote was specifically for the use case where openHAB was running on a Raspberry Pi with the OpenSprinkler Pi attached directly to it. This implementation therefore directly talked over the GPIO pins to OpenSprinkler and toggled the shift register bits to turn watering valves on and off. As noted above, I started with openHAB on a Pi, but switched. Fortunately I had also implemented my OpenSprinkler binding to communicate with the OpenSprinkler via HTTP, and this is the implementation I use today.
Another project I have in the works is to add in a water flow meter (I have one sitting here on my desk) just on the other side of the water valve, so that I can be sure that when the valve is open that water is in fact flowing (with this particular water supply you can never be sure of that!). I was originally planning to use Pinoccio boards to do this (as well as the garage door / gate control later), but given their frequent delays I've instead decided I'll implement this using the same Raspberry Pi that is hooked up to the OpenSprinkler system.
Second project: garden irrigation
Now that I had the OpenSprinkler Pi and openHAB hooked up, it was trivial for me to run some garden irrigation pipe through separate water valves to irrigate other areas of my property. All I needed to do was run a cable from the OpenSprinkler Pi to each valve, and to update openHAB to know about them.
There are two nice things about my garden irrigation implementation:
- I specify when the irrigation is run via a Google Calendar that openHAB can access. All I do is create appointments in Google Calendar for the specified time and duration, and in the description field I can input rules that openHAB can interpret. In this case the rules simply turn the irrigation valves on and off, as appropriate.
- With openHAB I can write rules like "when the irrigation is running, start filling the water tank". This just saves me from thinking and worrying (although in the longer term - once the ultrasonic sensor is in place - I will probably remove this rule in lieu of deferring to that).
This project has a high wife acceptance factor as it helps to keep her garden alive during the hot and dry summer.
One project I would like to do here is to download weather information relating to rainfall and to have this guide whether irrigation should be run. I've written code to download the information from weather stations around the region, but the data is not real-time and a little 'lumpy' for my liking - so I'll probably have to find a better source of the data.
Third project: home media / telecommunications
My house has two Raspberry Pi devices being used as media centers (both running Raspbmc). One is located under our primary TV in the lounge and the other hooked into our surround sound receiver and projector in the sunroom. Both Pis connect to a NAS where they can access our music, movies, photos, etc. We can already control both Pis using our phones / tablets (using the excellent Yatse Android client), but there was so much more I wanted to do. Here's a summary of what I've achieved so far:
Our AV receiver fortunately already had a binding written for it (it is an Onkyo receiver). We can therefore do things like turn the receiver on / off, change the volume, mute, change the source inputs, etc from openHAB. Even better, because there is a proper protocol that the Onkyo receiver can talk, we can also receive the state of the receiver (i.e. if it is on or off, what the volumn is, etc).
One thing the wife and I would occasionally do is stop playing music but forget to turn the receiver off. Now that the house knows immediately when the receiver turns on, I have written an openHAB rule that checks if the receiver is on every three hours (after it was first turned on), and if it is, sends me an XMPP message to my phone / computer letting me know that it is still on, and once it is turned off again it stops checking. This is good piece of mind so we aren't unnecessarily wasting power.
My home router also fortunately had a binding written for it (it is a Fritz!box VDSL router). Because our phone line comes in through this router, openHAB can be informed of when the phone is ringing and what the caller number is. When a call comes in, openHAB can do a number of useful things (which I'll mention elsewhere in this post). One example is that I have openHAB configured to send me an XMPP message (which is received on my phone). This is useful because most people I know don't bother to leave messages, and I can call them back whilst I'm away from home.
The second binding I have written for openHAB is a Tivo binding that emulates a remote control for a Tivo over a network socket connection (unfortunately that is all that the Tivo offers - it is not possible for me to read the state of the Tivo - for example, if it is playing or paused). The wife and I primarily watch TV via our Tivo device. My primary use case is to pause playback when the phone rings - and this is very handy as it saves us from having to find the remote and pause the TV whenever the phone rings! :-)
If we are watching media on our XBMC clients, a popup message appears in the lower-right corner of the screen informing us of the callers number. Whilst the XBMC binding doesn't support it quite yet, my intention is to do the same as the Tivo binding and pause playback whilst the call is underway.
With our standardisation on XBMC, I've also been able to get rid of one other thing that always used to annoy me - having to turn the receiver on when I started playing music out of the XBMC machine. Now all I do is load up Yatse on my phone and start playing music - openHAB sees that XBMC is now playing music, and starts the receiver up. If I stop playing music, it turns the receiver off again. Handy! :-)
Fourth project: home lighting
Of all my projects, being able to control lights in my house was the least likely to be beneficial, but I wanted to explore the technology a little, and I thought if I did it right, I could at least get some security benefits. My main criteria was that I didn't want to replace the light switches in my house (as I had just replaced all the switches last year when I renovated), and I didn't want to have to do any major rewiring. Fortunately, I stumbled upon Z-wave in-wall micro relays sold by companies like Fibaro. After a bunch of research into Z-wave (and a lot of cringing at the relatively high price for Z-wave devices), I ended up buying one Z-stick (to broadcast the Z-Wave signal from my openHAB machine), and two Fibaro 2x1.5KW relays. These devices go in the wall behind the light switch, and each one can control two light switches (meaning I was able to control four light switches in my house).
I decided to control the lights both inside and outside my front door (controlled by two separate switches), and my main kitchen and dining room lights (again, controlled by two separate switches). My ideas:
- Automatically turn on some of the inside lights some time before the sun sets.
- Because I live in the country and our house is visible from the road, I worry that having outside lights on at night just advertises the fact that no one is home. My idea was to allow me to set rules about when we go out of the house - for example, have the outside lights all off and the inside lights randomly alternating every few hours. As noted later on, I also have ideas around turning lights on automatically when the house is informed that we are returning home.
At present I have implemented the first idea - it was relatively trivial - I simply added code to openHAB to download the time of day that the sun sets, and to turn the relevant light on an hour before this. This is quite cool - it's always nice to see the house thinking for itself :-) I have not yet had the time to do the second idea, but it is high on my list when time permits.
Fifth project: garage door / gate control
Having done the Z-wave, I wanted to basically build my own version of the Fibaro relay device.....so I did. I used a Raspberry Pi, a magnetic reed switch, a cheap 4-relay board I purchased from Amazon a year or so back, and a small breadboard to wire it all together. I decided that I would use this contraption to control my garage door opener (using the relay and some cabling running up to the back of the garage door opener), and of course I placed one half of the magnetic reed switch on the garage door and the other on the frame to allow me to determine whether the garage door is open or not.
For me, the wiring took a short while to work out (I'm generally anti magic smoke), but I threw together the control software quite quickly. I built a Java-based server based on Jetty and Jersey. This allowed for me to have nice URLs that when accessed caused code on the Pi to do smart stuff out the GPIO pins - all written in Java (making use of the Pi4J project). In this case, I created REST endpoints for toggling the garage door, and reading whether it is open or not.
As with the water tank stuff, I had originally planned to do this with Pinoccio boards, but now that I was thinking with Pi, I realised that there was another benefit I could bring out of this Pi, given its location at the very end of my garage (and the fact there is no wifi reception from the house out there - but I do have a network cable going to it). The idea is simple: with my son on his way (and having been born on December 25th 2013), a few months ago I decided to renovate the back of my garage into a home office / sleep out. This would provide the necessary quiet zone to get work done. The downside is, as mentioned, I didn't have wifi out there, only wired connections. I was going to put in a spare wifi router and have it act as an access point, but given the Pi is right through the wall in my garage, I decided to buy a cheap USB wifi adapter and have my Raspberry Pi act as a wireless bridge to broadcast out the wired network over the wifi adapter. This works really well! Soon as I get to my office my phone switches to the new wireless network! A good win - although it was finicky to get the Pi to bridge the network connection without losing its ability to be remotely accessed over SSH.
Around this time I got a few NFC stickers, and so far I'm using just one of them - I stuck it to the side of piece of furniture by our back door so that when I wave my phone past it the garage door opens. Handy :-)
Sixth project: location awareness
I'm only just starting to explore this aspect of home automation. The obvious use case is for the house to know whether its regular occupants are home or away. My current thinking is to use software called Mqttitude (basically a decentralised Google Latitude), which is basically an app that runs on iOS and Android and can report the devices current location to an MQTT broker (which I talk about more later on). Mqttitude is being actively developed and just recently added support for geofences, so you can specify important locations. I've been testing this out recently, and it works quite well. The next thing I'm yet to do is wire this into openHAB (no surprises there are MQTT and Mqttitude bindings for openHAB!). I'll be sure to blog about this more in the future, but my current use cases include:
- Turning on the house lights at night when we drive up to the house.
- Open the driveway gate as we approach (and possibly close it when we leave).
This blog post turned out to be a mission to write, as I could write a whole heap more, and it turned out to be a bit of a brain dump! For those of you still reading, feel free to ask questions and I will try to respond directly or via a follow-up blog post. Before I finish this post, I thought I'd go into a bit more detail about some of my work and current thinking on how things will proceed, as well as ideas I have for software that should be written.
I've found the Jetty+Jersey architecture I created for the GaragePi to be really useful. In fact, I developed additional REST endpoints to give openHAB more data so that openHAB could do more intelligent reporting for me. For example, I brought in some of my other side projects like my stock market tracker and foreign exchange code so that they can be easily accessed from a URL (rather as standalone desktop apps). Because openHAB has an HTTP binding, it can simply connect to these REST endpoints to download useful information that can be displayed and graphed inside openHAB. I'm thinking that I'll eventually open source the architecture (although there is actually no special sauce there, just a bit of tedious setup).
Another thing I've been thinking of doing is improving this software to make it possible to request that updates get fired automatically to MQTT topics, to essentially switch the server from being pull-based to push-based. This would be opt-in, but would be nicer than having to frequently poll the server as we do now. The only way this would be beneficial (presently) is if I am able to register callbacks (or just poll) the GPIO pins on the Raspberry Pi - which I am sure would be lower overhead than doing frequent HTTP queries followed by GPIO queries that I do currently. I haven't had a chance to look into Pi4J to see if this callback approach is supported, but I imagine it should be (and in fact, I just looked - it is possible).
In general MQTT intrigues me - but I feel like I still need to investigate it further. I have a feeling I will almost make it a duplicate event bus that runs in parallel to openHAB (and in fact, I see no reason why openHAB should have its own event bus when it could just use MQTT). By doing this, I can very easily interact with events happening inside openHAB (by seeing them on the MQTT 'bus'), and also be able to interact with openHAB (by publishing on to the MQTT bus).
One piece of software I would dearly love to have (and I've been tempted to write in JavaFX) is basically an MQTT communicator. Imagine it like an email client - you can subscribe to topics (or just all topics), and receive notifications when they arrive. You could have rules to respond to different topics in different ways (for example, popup notifications, or have different actions fire on the computer, etc). With this software you could also easily push messages onto the MQTT bus, both on a whim and in reaction to incoming events. The only thing holding me back from starting on this is that there aren't more hours in the day!
I'm having a blast playing with home automation. I realise that sometimes it can seem trivial and pointless, but from a mental exercise perspective it is a great challenge. I also realise that home automation would be a lot easier if I was willing to pay thousands of dollars for turnkey systems (like what Fibaro and others offer), but the beauty of the approach I'm taking is that it is cheap and I am intimately aware of the software stack from Linux up. It's a point of pride in how little my home automation has cost in terms of money (and of course, assuming my time is free!) :-)
If you are interested in exploring this domain, I highly recommend looking into openHAB - they have a good mailing list, and an active community.
Finally - I hoped you enjoyed some original content on my blog for once! :-)