The Official Raspberry Pi Projects Book - Projects_Book_v4

(singke) #1

Tutorial


raspberrypi.org/magpi The Official Raspberry Pi Projects Book 141


HACK AN AMAZON DASH BUTTON


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)

trigger.py


Language
>PYTHON

DOWNLOAD:
magpi.cc/
DashButtonCode

Let there be Lite
We used Raspbian 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.


Button whole
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 (magpi.cc/2mt3zmo). 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 (magpi.cc/2msVvC5).
We’d also thank Ted Benson for being one of the first
Dash hackers (magpi.cc/2msUzhh), although updated
Amazon firmware is incompatible with his code.

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')
second_arp = False

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")

if second_arp == False:
sniff(prn =arp_detect, filter="arp", store=0)
second_arp = True
else:
second_arp = False

lights.py


BASIC CODE


EXAMPLE CODE

Free download pdf