I wrote about my use of Homebridge a while back (a long while, it appears), and since then, Homebridge has been there, just a swipe up on the iPhone, but it hasn't had a lot of use until iOS 10 came out last year.
With iOS 10, HomeKit got a LOT more useful - there is the Home app, for a start, which lets you setup room/spaces, scenes and automations if you have an AppleTV or iPad which lives on the home network. Plus a lot of the 3rd party apps got a lot better - even tho I have none of their devices, the Elgato Eve app is really useful for setting things up.
My setup looks somewhat like this now:
- Mac Mini running Node 7.101 and Homebridge, with the WeMo and Broadlink RM plugins
- AppleTV v4 running iOS10 latest, which acts as the always-on hub for the house
- 4 WeMo plugs which control the lights, coffee machine and a heater/dehumidifer which we move around
- A Broadlink RM3 Mini which I use to control the Heap Pump (AC for the 'murcans) in the lounge via IR. I have another one on order from AliExpress for the bedroom Heat Pump.
I was using the WeMo built in timers to control those devices, but with iOS 10, I've moved all of this to HomeKit. So:
- The coffee machine and heat pump come on at 0430 (we get up at 5)
- The coffee machine turns off, and the heat pump drops to 16deg when we leave (or midday on the weekends)
- About a hour before we come home, the heat pump goes to 18deg
- At sunset (variable) the outside lights come on, and go off around 2100
- The heat pump turns off at 2200
Aside from when I break it, this works great.
Enter Dash Buttons
Something I've wanted to play with for a while is a AWS IoT Button. This is one of the Amazon Dash Buttons, but somewhat programmable, and not branded with the product you are ordering. The downside, it's $20 USD, not $3, but I guess Amazon "makes it up on volume" on the other ones.
Dash Button, RM3 Mini and a plant.
Someone from work was going to the US, and a workmate sent the word out saying "anyone else want some dash buttons?" - thanks Tom!
So whats the idea here?
The idea is that you can setup the button, press it, and it fires an event in the AWS IoT environment, doing something you want it to - which, really, is anything that you can do in AWS:
- Send a message to an SQS queue
- Run a lambda (which pretty much means "do anything")
- Insert a row into a DynamoDB table
- And a load more. Some of them (eg lambda) mean you can easily tap into any other thing you want with a small amount of code - call an HTTP endpoint, send an SMS, whatever.
Better yet, all of this comes in under the AWS Free Tier, so unless you press the button around 3m times a month, it's free (the button only lasts 2000 presses before the soldered in battery dies)
Out of the box, the button comes with an app which makes it trivial to setup (once you have an AWS account - yay free tier!).
The setup process itself consists of setting up a public/private keypair (private lives on the device), and a "Device Shadow" profile for the device in the AWS IoT console. This allows things on AWS to query what the state of an IoT device is, without having to actually talk to the device.2
Once you have a device setup, you can set rules which fire things in AWS. The app will also optionally sets up a sample rule for you, and I picked the IFTTT "Maker" channel using Lambda, as I wanted the lambda part.
Really, the lambda is just a demo - you can make it do pretty much anything. I used this to setup the button, and make the sample lambda3.
Using the app, tho, is by far the quickest way to set up the button.
My use case
AKA OMG thats a first world problem if ever I saw one.
At night, I usually go and have a spa. Our spa is outside, away from the house, down a boardwalk which has lights next to it (you can see them in the top image here - the spa is not there in the picture, but it just past the trees on the left).
However, as we don't have any artificial light around other than the house, I like to have the lights out, as it's nice sitting the trees in the dark, especially if it's raining. But I want the lights on to get INTO the spa. Problem in need of an overkill response!
So, I want to connect up the Dash Button so that when I press it, it turns the outside lights on or off. As a side affect, if people are staying and sleeping the studio, they can take the button and turn the lights on if they want to get back into the house.
Getting the button to turn on the lights.
There are a couple of Dash Button Homebridge plugins, but they all rely on sniffing all network traffic with pcap, looking for the dash button's MAC address, as the button sends out a UDP packet when pressed (or an ARP request on the older buttons).
This is.... fine... but it means I have to run Homebridge as
root on the Mac, which I REALLY don't want to do4. It would be a lot quicker from press to action however.
Also, I spend 99% of my work time in AWS, so I wanted to start moving my personal stuff (eg this blog, Leonie's blog, various slack bots and other bits) from where they are now, to AWS.
So, my Rube Goldberg machine for making this work looks like this:
- Press the button, which fires the IoT setup which was setup using the Dash Button app.
- That fires a Lambda (setup by the button app), which I have customised to...
- ... send a message to an SQS queue which ....
- ... fires a Homebridge plugin on the Mac Mini. This is listening on the queue, and changes the HomeKit button state.
It's a bit of a long way around, and takes 2-5 seconds from pressing to the lights coming on, but it works pretty reliably now, if you don't use NodeJS v8.x.
The advantage of this is that I could trigger it from anything which can post a message to an SQS queue, without exposing anything internal on my network to the outside world.
/command? Sure, make it call an Api Gateway endpoint which runs a Lambda which pushes into SQS. Bot? CloudWatch alert? PagerDuty? Email even? All fairly easy.
There are a few bits I want to add to the platform:
- The Dash Button supports long press and double presses, so it should handle more than one endpoint (it does, just not very well)
- One queue listener would be more efficient than multiple, so make it look at the message which comes in, and fire different accessories based on that.
- What about other accessory types? The message might contain a temperature value, so set the Heat Pump setting based on this. Or turn something off if it's over a certain value.
It's very very flexible, and a load of fun to work with.
This is important. My code didn't work, at all, on Node 8.2.1. Not sure why. And The Broadlink plugin needed 7.6 or better. ↩
You can do this all manually, but... why? ↩
In hindsight, I could have the button press talk directly to SQS, which I might change later. ↩
Don't run as root, kids. Ever. Well, unless you really can't avoid it. And usually you can avoid it. Homebridge doesn't need to run as root or install with sudo, it appears. ↩