So my favourite project of 2014 has definitely been a series of API’s to run on my home network.
This has allowed me to do things like issue voice commands through an Android app using the voice recognition APIs and have a system on my network action those commands (like “Download the latest game of thrones”) and have it automagically appear on my home media centre in the living room (running XBMC). This could be drastically extended though and that’s the purpose of this series of blog posts – planning how I’m going to create a smarter home, one that lets me monitor what’s going on inside (webcams, sensors), control the temperature, set up events to happen when I get home etc.
I want to move away from a set of disparate “hacks” and turn it into a standard piece of software that can run on commodity hardware, and has a nice user interface. Ideally it will run on a wide range of hardware, from a Raspberry Pi at the bottom end to a PC, MicroServer or blade.
Technical parts ahead!
By far the language I’m most comfortable programming in is C# and Mono runs on all of the target platforms providing support for .NET 4.5 at time of writing (with the exception of the ASP.NET Async pipeline which I’m not interested in). True it is a bit of an overhead on lower end hardware where something like Ruby or Python might be more appropriate but I’m more concerned with keeping a consistent environment and set of tools. Thanks to mono that doesn’t mean Windows (and its licensing costs) has to be part of the equation!
Nodes, Events & Commands
What I’m going to need to accomplish this is a series of nodes on my network that are responsible for different things (or the same things in different rooms). Each node running the software stack (a .NET service with WebAPI endpoints through Owin).
A node will register available commands (“WakeOnLandCommand”, “TurnOnLightsCommand”) and execute them upon a message being received on the service bus (probably RabbitMQ, although ZeroMQ looks interesting for peer to peer discovery, and is mono compatible).
A node will register a sequence of events (sometimes tied to sensors, discussed below) and upon the event triggering (“UserEntersHouseEvent”) will fire that event over the message bus to be consumed by anything configured to look for it (possibly itself if it’s the only node in the cluster).
An example would be a node could be configured to check the current time and light levels using an API similar to fLux and if the conditions are right, turn on the downstairs lights or un-suspend the home-office PC. It could possibly use text to speech to welcome you home. A very basic Jarvis from iron man, but without all the talk-back.
So the events list would look something like this:
DeviceEntersBluetoothRange , DeviceLeavesBluetoothRange [ sensorid , distance necessary? , device id ]
Used to determine when a device has made a bluetooth connection with one of the nodes. This could be used to determine when a user enters a certain room.
DeviceConnectsToWLan, DeviceDisconnectsFromWLan [ ssid , sensorid, device id ]
This event would trigger when a device connects to a wireless network. It could be used to determine when a user enters or exits the home.
TemperatureChange [ sensorid, temperature, time ]
This event would trigger when the temperature changes +/- 1 degree celsius. It could be used to monitor temperature and issue a warning (or control the thermostat) if it was outside of a given range for the time of the day.
DoorOpened, DoorClosed, WindowOpened, WindowClosed [ sensorid, time ]
This event would let the system know that the door/window has either opened or closed. It could be used to send an alarm (along with webcam footage) to the users smartphone if the door is opened during e.g. vacation or work time and nobody connects to the network within a given period of time.
TurnOnLightsCommand [ nodeid, brightness, color ], TurnOffLightsCommand
This command would be used to turn on or off a light bulb that is connected (or registered to) a particular node. This would usually be based on location, so you may have a living room node, a kitchen node, an office node.
DownloadCommand [ url ]
This command could be used to download a particular TV show or movie (category could be scraped from download location or service api) and put it on the NAS where it would be picked up by media devices.
TurnOnVpnCommand [ vpnid ]
This command could instruct the default gateway on the network (a node!) to open an openvpn connection to a configured provider config. So with one voice (or web) command you could make your internet connection look as though it’s in another region (useful for Netflix etc.) or make your internet connection private.
A sensor would be a piece of hardware like a bluetooth receiver, tied to a node which contains the code to emit the event onto the message bus for processing. Sensors can be virtual, that is entirely defined in software. I.e. a service that polls for light levels from the fLux api and emits an event when the condition is matched (no hardware required).
Sensor code would also be written for mobile devices, for things like GPS location of the home owner.
BluetoothSensor [ hardware ]
WLanSensor [ software ]
AudioSensor [ hardware ]
SpeechRecognitionSensor [ software ]
GpsSensor [ software ]
You could have services running that would attempt to determine things like returning
home (based on GPS location, speed and schedule tracking) that could then trigger a custom event (ReturningHomeEvent) and be picked up by nodes in the house to emit events (TurnOnLights)
The beauty of all of this is something present in the CQRS pattern. You can decouple and mix and match events, commands (and queries) into discreet processing classes, and therefore get massive reuse out of your codebase. The benefits of this system would be the sheer flexibility and feature base that could be built on top of it. As the cost of home appliances decreases and its functionality increases (programmable APIs) the level of control you could gain over the systems in your home makes for incredible potential.
Anyway, I hope that gives a flavour of what I’m going to be up to for my next home project. I’m going to be looking for people to work with me on this, and it could potentially turn into a commercial product if I get it right, but the main thing is to do it for me (and for other people that want similar homes). I’ve committed the code so far (containing some code from previous home automation projects) into a BitBucket account so if you’re reading this and interested in joining me, email or Skype me and let me know!