AWS IoT Button - updateFri, Apr 29, 2016
A while ago I posted about the AWS IoT button that I picked up at re:Invent in 2015. You can read that post in full but in short I wanted to use the button to turn off my Sonos system when I left the house, but could not get it to work reliably - multiple invocations were firing off, as if the button press was registering multiple times, so the Sonos system would turn off and on again.
With help from Harry Eakins from Lab126 (the Amazon division handling the IoT button, Dash buttons etc) I did get to the root cause of the issue but forgot to update my post until I was reminded by Jinesh Varia, the Head of Mobile and IoT Developer Programs at AWS.
The issue boiled down to two things.
- A fault in my code.
- The behaviour of Lambda when errors occur.
I’ll deal with these in reverse order.
When Lambda calls fail they can, under some circumstances, retry. I wasn’t aware of this - if I had been aware it would have been an easier diagnosis. I did Google for retry behaviour when debugging this and could only find references to retrying when handling DynamoDB and Kinesis streams - which this function does not use. Even searching now I’m struggling to find it but thanks to Harry for pointing me to the definitive source here.
In my code - I was not explicitly calling context.succeed() or context.fail() to terminate my function. I didn’t dig into it in depth but it looks like not exiting the function via one of those methods means Lambda considers the request to have failed, and so it retries. I updated my code to exit cleanly and it worked. I’ve updated my Gist to include those context. methods.
[Note that the context.* methods are for the Node 0.10 version of Lambda only which is now deprecated. You can see how to transition to Node 4.3 Lambda here.]
I do find the 30 - 60 second wifi association time for the IoT button makes this not the best fit for this purpose - I’m often in a hurry to leave the house and want close to instant feedback to my request to turn off Sonos. Because of this I now use a voice command with my Echo - ‘Alexis, turn off Sonos’ - which uses a project that provides an emulation of a Hue bridge interfacing with the echo-sonos endpoint. This is a complete in-house-network solution (the Echo detects the Hue bridge emulator as a home automation device) so latency is very low. I’ll post more details about this another time.
Thanks again to Harry for helping with IoT setup and logging and to Jinesh for prompting me to post an update.