Amazon Dash hack with Raspberry Pi and Python

By Russell Barnes. Posted

Rescue Amazon’s £5 smart button from the monotony of ordering loo roll, and use it to do anything you like

Typically smart buttons cost £40, but the Amazon Dash Button costs a fiver. With a little tinkering and subversion, Amazon Dash can power anything from smart bulbs to alerts on your family’s smartphones to logging your billable hours.

The Internet of Things has two flaws: the name, and the need to get your phone out of your pocket, unlock it, swipe to the appropriate app, and wait for the app to load before you can do perform a basic task, such as turning on a light. Buttons are handy for a reason: they’re exactly where they need to be, and you can just press them. So if we’re going to have smart things, we need smart buttons.

Head over to Amazon to buy some Dash Buttons (you’ll need to be a Prime subscriber) and you’ll be baffled by the options: you can emergency-order raw virgin coconut oil (only £16.62 for 1.2kg), 20-sheet binding machines, or Nerf Darts with a Dash Button. The catch with these Dash Buttons is that you can only order certain products from certain firms. This matters, as Amazon will discount the price of a Dash Button from the first purchase made with it. Make sure you buy a button that lets you order something you’d buy anyway; that way, your Button is free.

 Hack an Amazon Dash using a Raspberry Pi and Python

Once the Dash Button arrives, use the Amazon app (Android and iOS only) to set it up and order that first item. There are decent instructions at Amazon.

Once you’ve ordered your product, go back into the Dash Devices and disable it. Then – bear with us – enable the Button again, but this time don’t select a product. Instead, just quit the app (don’t quit the process, close the whole app). This will have copied your WiFi credentials to the button without re-establishing the link to Amazon. It is now an unshackled smart button ready to be repurposed.

Use Jessie Lite to hack Amazon Dash

We used Jessie Lite on our Raspberry Pi Zero W, as it will be running as a headless server with no GUI required. Once in, follow the usual update procedure: sudo apt-get update && apt-get -y dist-upgrade. As your Dash Button has already accessed your router, its MAC address should be listed in your router’s logs or DHCP tables. The location differs according to manufacturer. The button will show up as ‘Internet Device’ or similar.

Now we’re ready to code. The idea behind this hack is to use the Pi as an interpreter. It constantly monitors your network for the appearance of the Dash Button, then uses that appearance as a trigger for some other action. We’re going to use Python to intercept those button presses, but this requires an extra module:

sudo apt-get install -y pip

sudo pip install scapy
Pip is a Python-specific installer, and Scapy is the module we’ll use to ‘sniff’ for the Dash Button’s MAC address (pkt[ARP].hwsrc) appearing on the network. As the Dash Button only powers up when you press its button, its MAC address will only appear after a button press.

Intercept Amazon Dash button

Now that we can intercept a button press, let’s do something with it. We’ve got a LIFX smart light, so we need the LifxLAN Python module: pip install lifxlan. Open the trigger script and add the LifxLAN module’s functions to the script with the line from lifxlan import *. Now we need to find the MAC and IP address of the smart bulb from our router, and to name the bulb in the Python script using the ‘Light’ object of the LifxLAN module: bedroom = Light('xx:xx:xx:xx:xx:xx', '192.168.1.xxx'). We need to find the current power level of the bulb in order to toggle it, which we do with the current_state = bedroom.get_power() variable and the bedroom.set_power() commands of our if, else statements. Annoyingly, the Dash Button sends two ARP packets every time it is pressed, so we need to ignore the second ARP packet by using the second_arp Boolean variable. Once done, save your script, make it executable (chmod +x lights.py) and add it as a cronjob (crontab -e) to make sure it runs every time your Pi boots: @reboot sudo python /home/pi/lights.py. Now we’ve got a smart button that we can stick to any wall, table, desk or bookcase to turn on our smart lights. And if a LIFX bulb sounds steep at £60 each, it would cost a lot more to install a new ‘dumb’ light switch once you’ve factored in gouging cable runs in the wall, hiring plasterers to make good and repainting a whole room or hallway. People have made Dash Buttons work with Philips Hue and Samsung SmartThings devices, too.

Shoot for the (Button) Moon

So, what else could you press your Dash Button to do? Hook your Python script into an online spreadsheet and you can log the time between button presses – useful for a musician logging practice sessions, or a freelance accountant logging billable hours. Tired of shouting up the stairs for your kids to come down for dinner? You could go the JavaScript route to connect an SMS messenger: press your Dash Button and they’ll receive a text message. Or use a service like Pushover (pushover.net) to make a smart doorbell, sending alerts to your smartphone or watch. Aaron Bell has detailed how to make a hacked Dash Button into an IFTTT trigger. We’d also thank Ted Benson for being one of the first Dash hackers, although updated Amazon firmware is incompatible with his code.
#!/usr/bin/env python

from scapy.all import *

def arp_detect(pkt):
    if pkt[ARP].op == 1: #network request
    if pkt[ARP].hwsrc == 'xx:xx:xx:xx:xx:xx'
        return "Button detected!"
        
print sniff(prn=arp_display, filter="arp", store=0)
#! /usr/bin/env python

from scapy.all import *
from lifxlan import *

#Buttons
andrex = 'xx:xx:xx:xx:xx:xx'

#Lights
bedroom = Light('xx:xx:xx:xx:xx:xx', '192.168.1.xxx')

def arp_detect(pkt):
        if pkt[ARP].op == 1: #network request
                if pkt[ARP].hwsrc == andrex:
                        current_state = bedroom.get_power()
                if current_state == 0:
                        bedroom.set_power("on")
                else:
                        bedroom.set_power("off")

sniff(prn=arp_detect, filter="arp", store=0)


 

 

From The MagPi store

Subscribe

Subscribe to the newsletter

Get every issue delivered directly to your inbox and keep up to date with the latest news, offers, events, and more.