“Are Gigi and Pop Pop awake yet?” -My 3 year old, every 5 minutes, all morning
We have a shore house that is next door to that of my in-laws (who are called Gigi and Pop Pop by my preschooler). This is wonderful for a myriad of reasons, and from the moment the kiddo wakes up she has exactly one thing on her mind: “when can I go next door to Gigi and Pop Pop’s?”
A simple solution for answering this question would be some sort of visual signal, like opening the blinds or a little flag or something. Unfortunately we don’t have any windows on the side of the houses that face each other, so I decided to rig up the most technologically complicated solution possible.
Before we continue: if you’d like to emulate this solution but aren’t particularly technical, don’t have a fancy router, or just don’t want to spend a day+ dicking around with things, I suggest just buying a LIFX wifi bulb and a flic button. You can use IFTTT to link them, for a total of $75 and an hour of your time. If you want to spend the better part of a day cursing at things just because you can, or you’re just looking for something to do with your RaspberryPi, read on!
Hardware used: LIFX color bulb, RaspberryPi (and mine is old so I needed a wifi dongle to go with it), DD-WRT capable router, Amazon Dash button.
Setting up a local server
Amazon’s Dash button is meant for you to reorder toilet paper. At $5 it’s also an extremely cheap wifi button. Of course, pressing it does just one thing, and that thing costs you money, but with a little bit of effort we can hijack those requests for our own devious purposes. Sorry Amazon. I might feel bad if I didn’t already spend thousands of dollars a year with you.
Most of the work was already done for me in this reddit thread. The first step is to set up a server to handle traffic from the button. I’m using a RaspberryPi running Raspbian (which I already had). Python was already installed with the OS, but I had to add a few more tools to get where I want.
First, I installed pip to make installing the other python libraries brain-dead.
Then I installed lifxlan, a library for controlling LIFX lightbulbs locally, and scapy, a packet sniffing library.
pip install lifxlan
pip install scapy
I gave the pi a static IP so things don’t break later. I wrote it down because I am forgetful.
Setting up the Dash Button
I set up the Dash using the Amazon app, giving it my network credentials, and then closed the app when it asked me to pick an item to purchase. It complained that my progress wouldn’t be saved, which was fine.
When you press the button the Dash will connect to your LAN. If you’re quick you can probably find its MAC address in the client list on your router (Status > LAN > Active Clients on DD-WRT). I’m not so I used Ted Benson’s python script to find the MAC address.
Of course when the button is pressed it also phones home to Amazon, and then Amazon sends a notification to my phone reminding me to pick something to buy. While this doesn’t trigger a purchase, it’s still annoying. At first I just blocked the button from WAN access using a MAC address filter on my router. But then it stayed on longer, draining the battery. In order to save the non-replaceable battery life I set up a DNS entry on my router that redirects all of the requests to the button’s home server (parker-gateway-na.amazon.com) to my RaspberryPi. The easiest way to do this in DD-WRT is to add the following lines to the startup script (under Administration > Console)
echo ‘192.168.1.148 parker-gateway-na.amazon.com’ >> /etc/hosts
Now the Dash button connects to the LAN, sends a request to my RaspberryPi (which is ignored), and then shuts down.
Tying it all together
Using more of Ted Benson’s code we listen for the ARP packet the button sends when it connects and use that to trigger a LIFX event. In my case I have a specific light bulb I want to turn blue so I figured out that bulb’s MAC address and then filter the list of bulbs against that. The lifxlan library in its current form doesn’t let you select a single bulb very easily, and if I can brush up on my python I may look into forking/extending it to do so.
I also have my script set to leave the bulb on/blue when it’s done, because I want it to stay that way until I manually reset it, but obviously you might want to read the initial bulb settings and reset them when you’re done blinking.
Making a cute label
I whipped up a really quick sticker to cover the button, printed it on sticker paper and and cut it out with an xacto knife.
Download it here if you’re so inclined.