Hacking the Amazon Dash Button to Make a Simple, Cheap, IoT Place-Anywhere Networked Button
I got two of Amazon’s newly-available dash buttons with the intention of playing with them to see what they were capable of. They’re a $5 button that when pressed, wakes up, connects to your Wi-Fi, and then turns off. I got the Olay buttons since it’s easy to Sharpie out the logo. Amazon seems to only let you buy two buttons per brand right now, so if you want more black buttons, try Gatorade or look through the selection.
The Button Itself:
- The CPU is a STM32F205RG6 processor which is an ARM Cortex-M3 that can run up to 120mhz and has 128 kilobytes of RAM and 1 megabyte of flash memory for program storage.
- The WiFi module is a BCM943362 module which in combination with the CPU make it a platform for Broadcom’s WICED SDK.
- There’s a 16 megabit SPI flash ROM which is typically used in conjunction with the WICED SDK for storing application data.
- An ADMP441 microphone is connected to the CPU and used by the Dash iOS application to configure the device using the speaker on a phone/tablet.
- There’s a single RGB LED and a button.
Setup:
Setup is extremely simple. You download the Amazon Shopping app on iOS or Android, go to Menu > Your Account and hold the button down on the Dash Button for 6 seconds to put it into a blue blinking “pairing” mode. From there, your phone can find it, and you can input your network credentials on your phone which will be sent to the button. After that, just close out of the Amazon app before you select anything for the button to purchase, and you’re ready to go. You will probably also want to disable notifications in the Amazon Shopping app settings, as it will prompt you on your phone to finish button setup every time you click it if you don’t.
Detecting Button Presses and Acting on Them:
For this tutorial, I used Python 3.5.1. We’re going to need to install a few libraries, all with “pip install [name]”
Make sure when you type “python” at a command prompt, it shows 3.5.1. After that, pip install the following:
- scapy-python3 (allows us to sniff for the ARP packets the buttons send.)
- requests (if we want to use the Maker Channel on IFTTT, which is an easy way to get things acting on the button presses.)
- phue (if we want to use the button to control Philips Hue lights.)
- We’ll also need to get and install the winpcap installer from: http://www.winpcap.org/install/default.htm
The Python Code:
This is relatively simple. This example triggers the “dashButton1” event on my IFTTT Maker Channel. It also turns all ten of my Hue bulbs off. You’re more than welcome to strip either of those bits of code from the example if you aren’t going to be using those features.
from phue import Bridge # for hue
import logging # for the following line
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) # suppress IPV6 warning on startup
from scapy.all import * # for sniffing for the ARP packets
import requests # for posting to the IFTTT Maker Channel
# setting up and connecting to Hue bridge
b = Bridge('192.168.1.243')
b.get_api()
# it takes a minute for the scapy sniffing to initialize, so I print this to know when it's actually ready to go
print('Init done.')
def arp_display(pkt):
if pkt[ARP].op == 1: #who-has (request)
if pkt[ARP].psrc == '0.0.0.0': # ARP Probes will match this
if pkt[ARP].hwsrc == '74:75:48:a5:33:be': # this is the first button MAC address
# [Black Button 1]
print("Pushed Black Button 1")
# trigger IFTTT Maker Channel Event "dashButton1"
requests.post("https://maker.ifttt.com/trigger/dashButton1/with/key/VnQ2CMKQEU")
b.set_light([1,2,3,4,5,6,7,8,9,10],'on', False) # hue lights off
elif pkt[ARP].hwsrc == '10:ae:60:64:04:95':
print("Pushed Black Button 2")
else:
print("ARP Probe from unknown device: " + pkt[ARP].hwsrc)
print(sniff(prn=arp_display, filter="arp", store=0))
This code sniffs your network for ARP packets which are sent by devices when they are trying to connect. The buttons will send one every time they are pressed, so we can listen for said packets and then check the MAC address sent by the device that’s trying to connect to see if it is a button that we want to act on. If we haven’t already put the MAC address into an if or elif, then it will fire the else at the bottom so we can copy and paste it into a new elif. You can see my requests.post that activates an event in my IFTTT Maker Channel, and you can put any Python code that you want to in here, it will run when that particular button is pressed.
Quick Demo:
Hopefully this helps you get your new, $5 networked button up and running and doing cool things! I’ve seen this used for everything from logging events (how often and when) to resetting a timer when pets are fed, to turning lights on and off. Let me know what you do with it in the comments!
Dash Button specs from: https://learn.adafruit.com/dash-hacking-bare-metal-stm32-programming/connections
Original Python code from: http://www.networkworld.com/article/2994131/internet-of-things/inside-the-amazon-dash-button-hack-and-how-to-make-it-useful.html
So will this only work with installing wincap on windows? Where do you run the python code?…also on windows?
I was able to get this to run on Mac OSX 10.11.5. Just do a bit of research on getting python/scapy to work on a mac and you will find the articles. This will also work similarly on Linux.
It appears you are not able to setup the buttons with the current IOS app.
Maybe it’s the newer buttons!
Everything goes along fine until it comes to picking a product.
If you close the app before picking a product,
the setup is canceled and the network credentials are not retained.
I’ve done this before the app update and it worked fine. Any work around?
You can do this on other operating systems, this guide was written because I felt that there wasn’t a good set of instructions for what to do on python 3.x on Windows.
Scapy should get you there on linux/osx
I blindly copied the code without editing the IP address — no idea how ARP/sniffing works, was hoping it would scan my whole local area network, but apparently it is just that IP, right? I eventually figured out which device was the right IP (lots of “Unknown” devices on my network), and plugged that in. Any way for it to scan across all IPs? Or is that network-intensive?
Thanks for the guide!
Mat, leave the line
if pkt[ARP].psrc == ‘0.0.0.0’: # ARP Probes will match this
as 0.0.0.0 as this means from all local network IPs and will match any device that tries to connect, so it should do what you want it to, but only if you leave it 0.0.0.0
If you mean the 192.168 ip, that’s my hue bridge, and if you have a hue bridge, you can change it to your bridge’s IP.
Awesome! Thank you for sharing! Are you on GitHub? I would like to see more of your projects if you have any.
Again, thanks for sharing!👍
Yep! PockyBum522 on github.
Pingback: Detecting the new Amazon Dash buttons | dustin.li
Pingback: Fantastic Internet of Things Devices and Projects - BestVPN.com
Is this still possible at the moment? Or did amazon put in some restrictions?
It seems that my button only ARP’d the first time.. It must have a newer firmware that doesn’t arp – it retains it’s IP and uses it again, so the code as written isn’t catching the button presses (I know it’s working, because I still get the alert for the ‘almost setup’ button on Amazon). Since presumably all the other traffic will be directed unicast, I’m not sure I’m going to be able to detect anything useful.. at least from my wired network. Has anyone else had this and/or know a solution?
Hi Steve Jones.
As for other solutions, you would need to capture a bit of traffic to see how they work. Presumably they contact Amazon, and they find the server to contract via DNS. You would just need to do some packet capture to see what it was trying to look up, and then add a DNS entry on your router to match that. Then you can direct the IP address to which the requests go, and could have a simple web server waiting for the button press which could trigger whatever you want.
Of course, another method would be to find a way to Reflash the ROM on those things.