Introduction
In MagPi Magazine (issue 57) there was an article about how you can subvert an Amazon Dash button and use it as a Internet of Things ("IoT") button. However, the code in the article had several syntax errors. Once I fixed the syntax errors I still couldn't get it to work with my button. Then I found that a key ingredient, tcpdump (needed by scapy), was missing - so I installed that too. I ended up with some working code but it wasn't very reliable, especially using wireless on the Raspberry Pi Zero W. After doing a bit of research and experimentation, I got it working better by using "dasher", a node.js script.
Node.js is a server-based runtime environment for executing JavaScript code. It allows non-blocking multi-threading applications to be deployed. This is a fancy way of saying that you can leave it running in the background on your computer (Raspberry Pi in this case) and it will just sit there listening until something triggers it (without consuming lots of processing power).
A companion application, NPM, is a package manager for node.js scripts.
As in the MagPi article, dasher would allow the Dash button to toggle an IoT bulb such as the Lifx or Philips Hue. I don't have one of those so I'll use a simple LED and then move on to IFTTT. Rather than tie up a Raspberry Pi 3, I thought this would be a good use for the cheap-as-chips Raspberry Pi Zero W. Incidentally, although this works well on a Pi Zero W, it doesn't seem to be very reliable using a basic Pi Zero with a wireless dongle attached to the USB port. If you've only got a non-wireless Pi Zero, it does work well with a wired network connection (e.g. a USB hub with a network port) if you happen to have one lying around.
Before we install dasher, the Dash button needs to be configured following the Amazon instructions so that it stores the SSID and password of your home wireless network (but with the last step omitted - so that no product is associated with the button). Strangely, you need to use an Android or iOS mobile phone to do this - not a tablet. If, like me, you've only got a tablet, you can use a little-known Android app called Amazon Underground on an Android tablet. I forgot to say - if you order something with the button of your choice, you get the price of the button refunded, so it makes sense to get a button for something you use anyway, place one order then de-activate the button. Then go through the "add button" process again and quit the app before the final step.
How will we know if we have got our Dash button working? It makes sense to test it by controlling a GPIO pin first.
This should respond with v6.10.3. If so, node is installed and up to date so we can proceed with installing dasher.
N.B. ignore gyp warnings (doesn't seem to matter)
Go and make a cup of coffee - installation takes a long time
When that is finished, check that your button can be found (make a note of the MAC address if you haven't already done so)....
We can configure dasher to monitor the home network and run a shell script if it sees a "UDP" request from the MAC address of the Dash button to join the network (which it will do when the button is pressed). To do this, we need to modify the config.json file according to the example given in the dasher documentation. Mine looks like this:
A companion application, NPM, is a package manager for node.js scripts.
As in the MagPi article, dasher would allow the Dash button to toggle an IoT bulb such as the Lifx or Philips Hue. I don't have one of those so I'll use a simple LED and then move on to IFTTT. Rather than tie up a Raspberry Pi 3, I thought this would be a good use for the cheap-as-chips Raspberry Pi Zero W. Incidentally, although this works well on a Pi Zero W, it doesn't seem to be very reliable using a basic Pi Zero with a wireless dongle attached to the USB port. If you've only got a non-wireless Pi Zero, it does work well with a wired network connection (e.g. a USB hub with a network port) if you happen to have one lying around.
Before we install dasher, the Dash button needs to be configured following the Amazon instructions so that it stores the SSID and password of your home wireless network (but with the last step omitted - so that no product is associated with the button). Strangely, you need to use an Android or iOS mobile phone to do this - not a tablet. If, like me, you've only got a tablet, you can use a little-known Android app called Amazon Underground on an Android tablet. I forgot to say - if you order something with the button of your choice, you get the price of the button refunded, so it makes sense to get a button for something you use anyway, place one order then de-activate the button. Then go through the "add button" process again and quit the app before the final step.
Let's get started
I started by following the instructions on the dasher git-hub page. However, my initial attempt didn't work; also, the version of node.js that you end up with is v4.0, although the current (at the time of writing) version is 6.10.3. I thought I'd do it properly and install the latest version of node.js. First, I prepared my Raspberry Pi Zero W with a new image of Raspbian (date 10 April 2017). The current version of Raspbian comes with a very old version of node, and this has to be updated for dasher to work properly. After configuring the timezone and WiFi interface, I installed a couple of pre-requisites (libpcap-dev and npm).
- Open console and install node, libpcap-dev and npm
#Install node.js to remove nodejs legacy
sudo apt-get install node
sudo apt-get install libpcap-dev
sudo apt-get install npm
- Install newer version of Node.JS (I used ARM v6)
wget https://nodejs.org/dist/v6.10.3/node-v6.10.3-linux-armv6l.tar.gz
tar -xvf node-v6.10.3-linux-armv6l.tar.gz
cd node-v6.10.3-linux-armv6l
sudo cp -R * /usr/local/
sudo node --version
This should respond with v6.10.3. If so, node is installed and up to date so we can proceed with installing dasher.
- Install dasher
cd ..
sudo git clone https://github.com/maddox/dasher.git
cd dasher
sudo npm install
N.B. ignore gyp warnings (doesn't seem to matter)
Go and make a cup of coffee - installation takes a long time
When that is finished, check that your button can be found (make a note of the MAC address if you haven't already done so)....
sudo ./script/find_button
Toggle a GPIO pin using dasher
{"buttons":[
{
"name": "Command Exec Button",
"address": "[MY MAC ADDRESS]",
"cmd": "/home/pi/dash_button.sh"
}
]}
#!/bin/bash
GPIO=14
GPIODIR=/sys/class/gpio/gpio$GPIO
# i.e. GPIODIR = /sys/class/gpio/gpio14
# use $GPIODIR to save typing long folder trees
echo "Configuring GPIO $GPIO"
#check if gpio14 is already exported.
# If not, export gpio14 then set as output
if [ ! -e "$GPIODIR" ] #tests for the (not !) existence of gpio14 folder
then
echo "Exporting GPIO"
echo $GPIO > /sys/class/gpio/export
echo out > $GPIODIR/direction #set as output
else
echo "GPIO already exported"
fi
#now that gpio14 is configured, toggle on/off depending on state
read state < $GPIODIR/value
sleep 1
echo $(( ! state )) > $GPIODIR/value
Before you can run this shell script, you need to make it executable and add it to your path:
sudo chmod -u+x dash_button.sh
sudo cp dash_button.sh /usr/local/bin
sudo npm run start
IFTTT
Now that we have got the button working with GPIO pins, we can use it to set up a trigger action using IFTTT instead (you can't do both with the same button, unfortunately). IFTTT allows you to connect web-enabled "services" together so that, IF something happens on one service (a "THIS" trigger), THEN an action will occur on another service (a "THAT" action).Assuming you have a Gmail account, a good one for testing purposes is to add a row to a Google Sheet each time the button is pressed.
In this case, the "dasher" script will monitor the home network and trigger an HTTP request if it sees a "UDP" request from the MAC address of the Dash button to join the network (which it will do when the button is pressed).
The next step is to configure the IFTTT "Maker Webhooks" service to "watch" for the HTTP request that the dasher script will generate when it sees the Dash button join the network. Assuming you have set up an account on IFTTT, you will need to activate the Maker Webhooks service which will generate your own private key (you will need this later).
Now, in IFTTT you can build your applet. Click on the "+" in the applet builder and choose the Maker Webhooks service (Receive a web request) as the trigger. Give it a name (in my case "trigger_dash"). Now click on the "+" to add an action. Choose the "Google Drive" service, then "Add row to spreadsheet". You can leave all the defaults as they are and just press "Create action", then (on the next page that appears) "Finish". If you click on the down arrow below your IFTTT user name on the main IFTTT page (top right) and choose Services, then choose the Maker Webhooks service you will be able to click on the Documentation button for that service (top right again) you will see the full URL that you need to generate (in dasher) in order to trigger the applet. This takes the format
https://maker.ifttt.com/trigger/[EVENT NAME]/with/key/[YOUR KEY]
Next make your own config.json file containing the mac address of your button and Maker Webhooks key. I recommend that you first rename or copy the config.json file you made to toggle a GPIO pin to config2.json or something else, so that you can always revert back to it if you need to test things are working.
sudo nano /config/config.json
Mine looks like this (note that "trigger_dash" is the name I used in Maker Webhooks when setting up the IFTTT applet):
{"buttons":[
{
"name": "trigger_dash",
"protocol": "udp",
"address": "[YOUR MAC ADDRESS]",
"url": "https://maker.ifttt.com/trigger/trigger_dash/with/key/[YOUR KEY]",
"method": "POST"
}
]}
I have kept it simple for testing purposes. Once you get it working you can add more buttons, or pass more information to IFTTT.
sudo npm run start
With any luck, you should see dasher start running and confirm that the button has been added. Now, we can configure it so that it runs automatically, every time that you start up the Raspberry Pi.
Run from startup
Just follow the instructions here. These instructions also show you how to check that your Dash button is being detected. Now, you should be able to reboot your Raspberry Pi then, every time the Dash button is pressed, Google will add a new line to a spreadsheet. If it doesn't work, open a console and type:
That should show you if dasher detected the button press, and what it did. I have found that the IFTTT Google service doesn't always work. Good luck!
tail -f /var/log/dasher.log
That should show you if dasher detected the button press, and what it did. I have found that the IFTTT Google service doesn't always work. Good luck!