Using Amazon Dash button as user-friendly Cheerlights changer

I’d heard about hacking Amazon Dash buttons to control stuff via a Pi but never bothered with them.

Then I saw that they were on special offer for £1-99 (and it  turns outs you get £4-99 credit on order if you use one so they are fiscally neutral at the minimum ) so I ordered the Duracell one (as always using batteries)

Setting up the Dash

I won’t repeat details here on how you register them and then disable them again – just google and follow the 10’s of articles on it.

You end up a WiFi device that is setup with your WiFi credentials but is unable to place any orders.  When you press the button, it quickly powers up- trys to connect – fails – flashes the LED – and shutsdown again.

So, the aim at this point is to notice when the device is trying to connect.

You can do this with a little python program which just needs a couple of things installing

sudo pip install scapy

sudo apt-get install tcpdump

then create a prog called trigger.py

from scapy.all import *
def arp_detect(pkt):
    if pkt[ARP].op == 1: #network request
        if pkt[ARP].hwsrc == '60:01:94:15:f7:cf':
            return "Dash detected!"

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

But we need to change the MAC address before we run it.

My router has a status page with all connected devices so I just displayed that and pressed the button and refreshed the page and it was obvious what the button’s address was – probably just as easy to do using the Android Fing app as well

So, once you’ve found your MAC address – change it in trigger.py and

sudo python trigger.py

Press the button and you should see a message appearing

Sending an MQTT message to my broker

So intead of printing a message on the screen, I added a bit of code and created dash_mqtt.py

#!/usr/bin/python
from scapy.all import *
import paho.mqtt.client as mqtt
import time

def arp_detect(pkt):
    if pkt[ARP].op == 1: #network request
        if pkt[ARP].hwsrc == 'b4:7c:9c:f9:1b:8e':
            publish("dash","pressed")
            return "Button detected!"

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

def publish(topic,payload):
    client.publish(topic,payload)
    print("sending: " +topic + " " + str(payload))

client = mqtt.Client()
client.on_connect = on_connect
client.connect("192.168.0.23")
client.loop_start()

try:
    print sniff(prn=arp_detect, filter="arp", store=0)
except KeyboardInterrupt:
    print
pass

which simply just publishes a message on topic dash, to my LAN mosquitto broker (but you could use a public broker if you don’t have your own one)

Node-RED flow to take action on the MQTT message

Final link in the chain is to use Node-RED to listen out for the MQTT message and then do something when it arrives.

The “something” could all be done inside 1 python program but all my house IoT is handled by ScratchGPIO and Node-RED so that’s what I’ve done

 

I decided that I wanted the Dash to change the global Cheerlights colour.

This is because when people notice the neopixel ring in my water feature, I tell them they can change it by tweeting a colour and including #Cheerlights in the tweet – a lot of them don’t use twitter!

So I’m going to leave the button outside (on a table in my covered BBQ sitting area) so that they can press it and get the Cheerlights to change to a random colour.

The flow looks likes this

The top half listens for the MQTT message, adds in the current time and mixes in a random colour generated by the bottom half of the flow and sends a tweet out.

The bottom half of the flow determines what the colour will be – it basically generates a random number 1 – 8, looks up a colour based on that number, checks to make sure its not the current col – if it is – i tries again.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *