Tuesday, 24 February 2015

Augmenting Nest's Auto Away


Nest Thermostat in the hallway
In hindsight, the placement of my Nest thermostat is less than ideal.  It's in the hallway on the ground floor, pretty much the middle of my house.  The Nest sees me walk past it when I wake up, when I get home from work, and when I have to go and wave at it to turn the heating on.  You see, we spend most of our time between the kitchen, the office and the TV room, all of which are below ground floor, and so can't been seen by the Nest.  The Nest will go into auto away mode while we are home, something we only notice when things get a little chilly.

I wanted to improve the situation with technology, so I needed a proxy for my presence in the house.  I always carry my iPhone with me when I leave the house, so I set out to detect the presence of the phone on my wifi network, and use this to set the away status of the thermostat.  Unfortunately the iPhone’s behaviour on the wifi network is unpredictable - the phone sleeps (does not respond to a ping) for long periods of time.  Other projects use knowledge about devices on the network gleaned from their particular brand of wifi router, but I wanted a router agnostic approach.

I also wanted the system to be easy to configure - I wanted to show a list of devices seen on the network to the user and have them pick their phone.  To this end, I began by not targeting a single MAC address, but all devices on the network.  I initially started monitoring the arp table on my Raspberry Pi for the presence of my phone’s MAC address using the ‘arp -a’ command.  Unfortunately, entries seem to hang around in the arp cache for a very long time - and trying to understand the linux arp cache was difficult.  

I switched to using the command from above stackoverflow answer (‘ip -s neighbor list’) to expose the freshness of entries in the cache, but even this again wasn’t a good enough signal, as the iPhone never really spoke to the Raspberry Pi.  I had to start pinging stale entries in the list - this worked well, but eventually the iPhone MAC address would drop out of the list.  To fix this I added a periodic broadcast ping to the entire subnet.  I combined this with some simple timeout logic produce a less noisy signal, but since then I’ve migrated to using a more sophisticated failure detector.

UI tiles show presence of phones
This system is reasonably effective - it can detect when I am home and hold the heating on.  A background cron job periodically polls the Nest API and sets the away status correctly, just in case it goes into away mode.

Since initially building this I’ve added motion sensors in the aforementioned rooms - used to control the lighting.  I plan to incorporate this signal into the logic for controlling the Nest, improving the responsiveness of the system.  What's more, I’ve begun experimenting with an iPhone app for geofencing and iBeacons.  Hopefully this will allow me to know who is in a room, not just that the room is occupied.  But that’s a topic for another post...

No comments:

Post a Comment