-
- Posts: 15
- Joined: Fri Apr 15, 2016 9:22 pm
Issue #57 Hack a Dash Button
Has anybody got this project to work? The code for trigger.py doesn't even pass a syntax check (missing colon, missing indents ....). Once those are corrected, I get various runtime errors.
- DougieLawson
- Posts: 42155
- Joined: Sun Jun 16, 2013 11:19 pm
- Location: A small cave in deepest darkest Basingstoke, UK
Re: Issue #57 Hack a Dash Button
What happens if you pull the code from https://github.com/themagpimag/magpi-is ... DashButton with
cd /home/pi
git clone https://github.com/themagpimag/magpi-issue57
cd magpi-issue57/Dashbutton
python2 ./trigger.py
Edit: you're right the code is completely wrong and has three syntax errors in it.has a better chance of working because I've fixed the indents and missing colon.
cd /home/pi
git clone https://github.com/themagpimag/magpi-issue57
cd magpi-issue57/Dashbutton
python2 ./trigger.py
Edit: you're right the code is completely wrong and has three syntax errors in it.
Code: Select all
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)
Languages using left-hand whitespace for syntax are ridiculous
DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.
The use of crystal balls and mind reading is prohibited.
DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.
The use of crystal balls and mind reading is prohibited.
-
- Posts: 15
- Joined: Fri Apr 15, 2016 9:22 pm
Re: Issue #57 Hack a Dash Button
I got that far, and fixed the code like you did. When I run it I get a runtime error.
The function that is defined in trigger.py is "arp_detect()" but the following line calls "arp_display()", which is not defined.
print sniff(prn=arp_display, filter="arp", store=0)
When I fix that, I get another runtime error which suggests that it needs to be run as root. When I run it as root, it sits there and (when I press the Dash button) it does not appear to detect the MAC address that I put in the code (which I have verified by other means). I read a comment somewhere that scapy expects the MAC address in lower case, so I tried that too. Given the high number of errors in such a short piece of code I don't have a lot of confidence that this project has been tested properly.
The function that is defined in trigger.py is "arp_detect()" but the following line calls "arp_display()", which is not defined.
print sniff(prn=arp_display, filter="arp", store=0)
When I fix that, I get another runtime error which suggests that it needs to be run as root. When I run it as root, it sits there and (when I press the Dash button) it does not appear to detect the MAC address that I put in the code (which I have verified by other means). I read a comment somewhere that scapy expects the MAC address in lower case, so I tried that too. Given the high number of errors in such a short piece of code I don't have a lot of confidence that this project has been tested properly.
Re: Issue #57 Hack a Dash Button
This forum thread might be a suitable location for your feedback -> viewtopic.php?f=106&t=109621#p753241
Re: Issue #57 Hack a Dash Button
Personally I think this whole post is better feedback than lost in an ever continuing thread.
I was looking at ordering a few to have a go, just can't decide which logo I want on the button
I was looking at ordering a few to have a go, just can't decide which logo I want on the button

-
- Posts: 1009
- Joined: Mon Oct 31, 2016 10:05 am
Re: Issue #57 Hack a Dash Button
I have several comments on this thread:
1) I don't think this is a MagPi problem per se, so I don't think the Erratta thread has anything relevance to the discussion.
2) This code is not original to the MagPi. I know nothing about the MagPi, have never seen an issue or had any desire to, but I've seen this code. When I was first interested in doing something with the Dash, I googled and found this code on one of the "hack" sites (I think it was "hackaday.com") and there it was.
3) I could never get it to work. I think it just fundamentally doesn't work - it is never a good sign when posted code has syntax errors in it, and I think every one of us has had that experience with this code. It either just fundamentally doesn't work - OR it only works with a very specific version of Python and a very specific version of the scapi library - OR there is something the original author is just not telling us (this last is more common than you might think).
4) In frustration at the original code being a dud, I developed my own solution, which is based on exactly the same operational concept as the posted code, but has the benefits of a) Actually working and b) being simpler. See below for details.
5) Note that the basic operational concept is that you have a process that sits around and waits for the Dash to come online. This works - and is rather clever - but be aware that it is not real-time responsive. I.e., several seconds go by between the time the button is pressed and when the program wakes up. If you can live with this (as in the prototypical "doorbell" application), then you're good to go.
My method is basically:
1) Get the Dash registered with your router - note its IP address (once assigned, this should not change - unless you let a very long period of time go by without hitting the button).
2) Run the following command (this command runs "forever"):
ping the.ip.address.OfTheDash | gawk ...
My GAWK script takes input from the ping command (which only comes when the Dash is online) and does appropriate things when it sees that the Dash is online.
It all works quite well.
1) I don't think this is a MagPi problem per se, so I don't think the Erratta thread has anything relevance to the discussion.
2) This code is not original to the MagPi. I know nothing about the MagPi, have never seen an issue or had any desire to, but I've seen this code. When I was first interested in doing something with the Dash, I googled and found this code on one of the "hack" sites (I think it was "hackaday.com") and there it was.
3) I could never get it to work. I think it just fundamentally doesn't work - it is never a good sign when posted code has syntax errors in it, and I think every one of us has had that experience with this code. It either just fundamentally doesn't work - OR it only works with a very specific version of Python and a very specific version of the scapi library - OR there is something the original author is just not telling us (this last is more common than you might think).
4) In frustration at the original code being a dud, I developed my own solution, which is based on exactly the same operational concept as the posted code, but has the benefits of a) Actually working and b) being simpler. See below for details.
5) Note that the basic operational concept is that you have a process that sits around and waits for the Dash to come online. This works - and is rather clever - but be aware that it is not real-time responsive. I.e., several seconds go by between the time the button is pressed and when the program wakes up. If you can live with this (as in the prototypical "doorbell" application), then you're good to go.
My method is basically:
1) Get the Dash registered with your router - note its IP address (once assigned, this should not change - unless you let a very long period of time go by without hitting the button).
2) Run the following command (this command runs "forever"):
ping the.ip.address.OfTheDash | gawk ...
My GAWK script takes input from the ping command (which only comes when the Dash is online) and does appropriate things when it sees that the Dash is online.
It all works quite well.
If this post appears in the wrong forums category, my apologies.
-
- Posts: 15
- Joined: Fri Apr 15, 2016 9:22 pm
Re: Issue #57 Hack a Dash Button
Thanks for the replies. I'll give your suggestion a try, Martin.
I have to say that I'm very disappointed with this article in MagPi. Given the readership profile of the magazine and the fact that it costs money to buy (not withstanding the excellent free Voice HAT this month), it is reasonable to expect that the code and instructions have been tested. For a short piece of published code to have three syntax errors is very shoddy. Clearly, no testing has taken place.
I am hoping for a response from either MagPi or the author.
I have to say that I'm very disappointed with this article in MagPi. Given the readership profile of the magazine and the fact that it costs money to buy (not withstanding the excellent free Voice HAT this month), it is reasonable to expect that the code and instructions have been tested. For a short piece of published code to have three syntax errors is very shoddy. Clearly, no testing has taken place.
I am hoping for a response from either MagPi or the author.
- DougieLawson
- Posts: 42155
- Joined: Sun Jun 16, 2013 11:19 pm
- Location: A small cave in deepest darkest Basingstoke, UK
Re: Issue #57 Hack a Dash Button
Before the MagPi magazine became a commercial venture and was created by a group of enthusiastic amateurs (including me) we would go through the code in the articles and get it working. There was at least one article where the code supplied with the article got completely replaced with stuff I wrote.SteveSmythe wrote:I have to say that I'm very disappointed with this article in MagPi. Given the readership profile of the magazine and the fact that it costs money to buy (not withstanding the excellent free Voice HAT this month), it is reasonable to expect that the code and instructions have been tested. For a short piece of published code to have three syntax errors is very shoddy. Clearly, no testing has taken place.
Since March 2015 that testing piece has been abandoned and there's too much code in the magazine that's complete junk like this stuff.
Languages using left-hand whitespace for syntax are ridiculous
DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.
The use of crystal balls and mind reading is prohibited.
DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.
The use of crystal balls and mind reading is prohibited.
-
- Posts: 15
- Joined: Fri Apr 15, 2016 9:22 pm
Re: Issue #57 Hack a Dash Button
A bit more testing revealed that the current Amazon Dash buttons don't even use the "arp" protocol when joining a network. They use "udp". So that whole bit of scapy code would never work, even if it wasn't full of syntax errors!
I have now got the button to trigger actions (in IFTTT, although many other actions are possible) using https://github.com/maddox/dasher.
However, that wasn't straightforward either as dasher is written in node.js and getting that to work on a Pi Zero was a bit of a pain.
I have now got the button to trigger actions (in IFTTT, although many other actions are possible) using https://github.com/maddox/dasher.
However, that wasn't straightforward either as dasher is written in node.js and getting that to work on a Pi Zero was a bit of a pain.
-
- Posts: 22
- Joined: Wed May 10, 2017 8:01 am
Re: Issue #57 Hack a Dash Button
I have the method in the Magpi article working on my home server (not Raspberry Pi), I typed things in manually as the code was not up on github at the time, and corrected syntax errors as I went, and prodded code so that I could first use it as a mac address sniffer (it appears I have far too many devices on my network
, and then constructed a list of mac addresses I was interested in .
I will post my code when I get home.

I will post my code when I get home.
-
- Posts: 22
- Joined: Wed May 10, 2017 8:01 am
Re: Issue #57 Hack a Dash Button
Code: Select all
from scapy.all import sniff
from scapy.all import ARP
IGNORES = {"11:22:aa:bb:cc:dd":"some-server",
"ab:cd:ef:12:34:56":"a phone",
}
BUTTONS = {
"12:34:56:78:9a:bc":"Dash button1",
}
def arp_detect(pkt):
if pkt[ARP].op == 1: #network request
if pkt[ARP].hwsrc in BUTTONS:
return "Button {} pressed".format(BUTTONS[pkt[ARP].hwsrc])
elif pkt[ARP].hwsrc in IGNORES:
print IGNORES[pkt[ARP].hwsrc]
else:
print "Unknown device {}".format(pkt[ARP].hwsrc)
print sniff(prn=arp_detect, filter="arp", store=0)
-
- Posts: 1009
- Joined: Mon Oct 31, 2016 10:05 am
Re: Issue #57 Hack a Dash Button
I'll try that when I get a chance, but I have to ask:
Is it any better (in terms of performance) than the "ping" method I outlined earlier (and which I have been using, quite successfully, for some time now) ?
Note that I am not saying that it isn't; I'm genuinely interested in what you have to say on the subject.
Is it any better (in terms of performance) than the "ping" method I outlined earlier (and which I have been using, quite successfully, for some time now) ?
Note that I am not saying that it isn't; I'm genuinely interested in what you have to say on the subject.
If this post appears in the wrong forums category, my apologies.
-
- Posts: 22
- Joined: Wed May 10, 2017 8:01 am
Re: Issue #57 Hack a Dash Button
I think that this method should be better performance.
Looking at the documentation for Scapy http://www.secdev.org/projects/scapy/doc/usage.html if you scroll down to the bit on ARP packet sniffing it mentions that the filtering is done in the kernel, and the only additional work is the callback function.
With the ping method you are sending packets constantly as well as parsing the stdout from the ping command, (which you have to do regardless of if you receive a ping or not!).
If you are happy with your solution then stick with it, I am a fan of using my own code so that when if something goes wrong I know where to start looking!
Looking at the documentation for Scapy http://www.secdev.org/projects/scapy/doc/usage.html if you scroll down to the bit on ARP packet sniffing it mentions that the filtering is done in the kernel, and the only additional work is the callback function.
With the ping method you are sending packets constantly as well as parsing the stdout from the ping command, (which you have to do regardless of if you receive a ping or not!).
If you are happy with your solution then stick with it, I am a fan of using my own code so that when if something goes wrong I know where to start looking!

-
- Posts: 1009
- Joined: Mon Oct 31, 2016 10:05 am
Re: Issue #57 Hack a Dash Button
It sounds like its pretty much the same, for practical purposes.
Keep in mind that the words "performance" and "efficiency" are not synonyms (even though most people use them as if they were).
Keep in mind that the words "performance" and "efficiency" are not synonyms (even though most people use them as if they were).
If this post appears in the wrong forums category, my apologies.
-
- Posts: 15
- Joined: Fri Apr 15, 2016 9:22 pm
Re: Issue #57 Hack a Dash Button
In case anyone is interested, I've written a blog post detailing how I got the Dash button to work reliably on wireless (Pi Zero W). This includes triggering IFTTT applets and controlling the GPIO pins. It runs very nicely in the background and the Raspberry Pi is still very usable (even via VNC). I found the scapy approach very unreliable and it didn't like me using VNC.
Re: Issue #57 Hack a Dash Button
Hello,
I have been using the dash button successfully..but when I upgraded to 4.9.24+ 993 scapy 2.3.3 I only get my mac address on the pi zero back .. the dash button OR my esp8266 mac address do not appear .. if I fall back to older image it works: the code i used to test is below:
other differences:
on the new failed run after the update to jessie I no longer get
WARNING: No route found for IP)v6 destination :: (no default route?)
I am using the ESP8266 as well because in the long run the dash might stop working ... I thought it would stop when I changed the battery but that was ok... just had to reconnect it to amazon with the iphone app..
Any ideas on how to diagnose this would be appreciated ...
It works fine @ 4.4.50 + 970 scapy 2.2.0
It appears that the python did not change across maintenance:
Python 2.7.9 (default, Sep 17 2016, 20:26:04)
[GCC 4.9.2] on linux2
I got this code from:
https://phaethon.github.io/scapy/api/us ... one-liners
works on older jessie .. fails on scapy 2.3.3
4.9.24+ #993 Wed Apr 26 17:56:54 BST 2017 armv6l GNU/Linux
thanks
I have been using the dash button successfully..but when I upgraded to 4.9.24+ 993 scapy 2.3.3 I only get my mac address on the pi zero back .. the dash button OR my esp8266 mac address do not appear .. if I fall back to older image it works: the code i used to test is below:
Code: Select all
from scapy.all import *
import datetime
#
print "finddash started @: ", datetime.datetime.now()
def arp_display(pkt):
if pkt.haslayer(ARP):
if pkt[ARP].op == 1: #who-has (request)
print( "ARP Probe from: " + pkt[ARP].hwsrc)
print (sniff(iface="wlan0", prn=arp_display, filter="arp", store=0, count=0))
on the new failed run after the update to jessie I no longer get
WARNING: No route found for IP)v6 destination :: (no default route?)
I am using the ESP8266 as well because in the long run the dash might stop working ... I thought it would stop when I changed the battery but that was ok... just had to reconnect it to amazon with the iphone app..
Any ideas on how to diagnose this would be appreciated ...
It works fine @ 4.4.50 + 970 scapy 2.2.0
It appears that the python did not change across maintenance:
Python 2.7.9 (default, Sep 17 2016, 20:26:04)
[GCC 4.9.2] on linux2
I got this code from:
https://phaethon.github.io/scapy/api/us ... one-liners
Code: Select all
#! /usr/bin/env python
from scapy.all import *
def arp_monitor_callback(pkt):
if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at
return pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")
sniff(prn=arp_monitor_callback, filter="arp", store=0)
4.9.24+ #993 Wed Apr 26 17:56:54 BST 2017 armv6l GNU/Linux
thanks
Re: Issue #57 Hack a Dash Button
So far I have not been successful getting my RPI to detect the ARP from the Dash button press. I know it is being sent onmy local network, because I can capture it on WireShark, running on my Windows 10 PC, and it looks reasonable (packet source says "Amazon...", reasonable IP address, etc.)
I have tried running a corrected version of the original suggested code in Issue 57 of MagPI (using scapy and sniff). I have also tried the code proposed by Bob Steinbeiser, which uses raw rawSocket.recvfrom(2048). In both cases, some ARP messages are detected on my RPI, but not the one that originates from the Dash button.
Any suggestions on why the Windows 10 PC sees the Amazon ARP packets, but the RPI does not detect them?
Below is the code I used from Bob Steinbeiser: (revised with some added prints and my dash's MAC address)
I have tried running a corrected version of the original suggested code in Issue 57 of MagPI (using scapy and sniff). I have also tried the code proposed by Bob Steinbeiser, which uses raw rawSocket.recvfrom(2048). In both cases, some ARP messages are detected on my RPI, but not the one that originates from the Dash button.
Any suggestions on why the Windows 10 PC sees the Amazon ARP packets, but the RPI does not detect them?
Below is the code I used from Bob Steinbeiser: (revised with some added prints and my dash's MAC address)
Code: Select all
import socket
import struct
import binascii
# Written by Bob Steinbeiser (https://medium.com/@xtalker)
rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
socket.htons(0x0003))
MAC = '6837E9306A83'
while True:
packet = rawSocket.recvfrom(2048)
ethernet_header = packet[0][0:14]
ethernet_detailed = struct.unpack('!6s6s2s', ethernet_header)
print ("rcvd ethernet pkt") # RDT
arp_header = packet[0][14:42]
arp_detailed = struct.unpack('2s2s1s1s2s6s4s6s4s', arp_header)
# skip non-ARP packets
ethertype = ethernet_detailed[2]
if ethertype != '\x08\x06':
continue
source_mac = binascii.hexlify(arp_detailed[5])
dest_ip = socket.inet_ntoa(arp_detailed[8])
print ("got ARP packet from mac " + source_mac + "dest-IP " + dest_ip) # RDT
if source_mac == MAC:
print ("Dash button pressed!, IP = " + dest_ip)
Re: Issue #57 Hack a Dash Button
The ARPs weren't visible using wifi, but were visible using an Ethernet cable.
Thanks to Rexypoo for that tip in his blog! The code that worked for me is below (copied from others).
If someone knows how to get this to work via wifi, please explain.
Thanks to Rexypoo for that tip in his blog! The code that worked for me is below (copied from others).
If someone knows how to get this to work via wifi, please explain.
Code: Select all
from scapy.all import *
def arp_display(pkt):
if pkt[ARP].op == 1: #who-has (request)
print ("network request")
print "hwsrc=" + pkt[ARP].hwsrc + " psrc=" + pkt[ARP].psrc
print sniff(prn=arp_display, filter="arp", store=0, count=0)
print ("scan program done")
Re: Issue #57 Hack a Dash Button
scapy works on wi-fi with jessie 4.4.50-v7+ #970 Mon Feb 20 and fails with jessie 4.9.28+ #998 Mon May 15... I simply took the latest unmodified distro from the raspi-pi downloads .. full version or jessie-lite does not matter. Something changed between these two releases. It would be nice if someone could verify this . On the scapy that fails I can only see the router and my adapter.
Re: Issue #57 Hack a Dash Button
I just used the jessie 4.9.28-v7 with a tenda w311m wifi module and it worked fine .. this was on a rpi 2 .. so maybe it is just with the integrated wifi on the pi zero???
Re: Issue #57 Hack a Dash Button
I just observed this as well after I applied maintenance to bring it up to 4.9.35 #1014 - again works with pi2 and tenda and not with pizero and integrated wifi..
Re: Issue #57 Hack a Dash Button
it also fails with the pi3 B v1.2 with the integrated wifi .. It only returns the router and it's own mac .. someone else must have noticed this ..
Re: Issue #57 Hack a Dash Button
Just in case anyone finds this old thread - this code works on my Pi3B+ with Raspbian Stretch:
(6c:56:97:61:e3:ba is the mac address of my dash button model JK29LP)
Code: Select all
#!/usr/bin/env python
from scapy.all import *
def arp_detect(pkt):
if pkt.haslayer(ARP):
#print(pkt[ARP].hwsrc,pkt[ARP].op)
if pkt[ARP].op == 1: #network request
if pkt[ARP].hwsrc == '6c:56:97:61:e3:ba':
return "Button detected!"
print(sniff(prn=arp_detect, filter="arp", store=0, count=0))
-
- Posts: 196
- Joined: Wed Oct 05, 2016 6:06 pm
Re: Issue #57 Hack a Dash Button
Thanks! This does help. Maybe I can finally get that Dash Button to work in Python after the code in the Magpi article was shockingly bad!
Re: Issue #57 Hack a Dash Button
Thank you rpiMike ! This works (much better) on my Pi Zero W running Raspbian Stretch. There does seem to be an issue where the first press of a button after a long interval (couple of minutes) doesn't seem to be detected, but subsequent presses are.
I modified the code to scan for any of multiple buttons (occasionally on sale from Amazon for only $0.99) as follows:
I have also recently been having pretty good results with https://github.com/Nekmo/amazon-dash (although it also misses some button presses).
I modified the code to scan for any of multiple buttons (occasionally on sale from Amazon for only $0.99) as follows:
Code: Select all
#!/usr/bin/env python
# Adapted from 27Jul2018 post by rpiMike.
# https://www.raspberrypi.org/forums/viewtopic.php?p=1345420#p1345420
from scapy.all import *
buttons = ["78:e1:03:e5:b0:d0", \
"78:e1:03:17:41:c4", \
"fc:65:de:f4:45:cd", \
"18:74:2e:1a:75:7b"]
def arp_detect(pkt):
if pkt.haslayer(ARP):
if pkt[ARP].op == 1: #network request
for b in range(len(buttons)):
if pkt[ARP].hwsrc == buttons[b]:
return "Button " + str(b+1) + " detected!"
print(sniff(prn=arp_detect, filter="arp", store=0, count=0))