Thursday, 5 January 2017

Use an Amazon dash button to trigger a relay for 30min

ere is a neat script I'm running on a Raspberry PI to close a contact for 30 min (to boost the shower fan for 30min) whenever I press an

Notes:
  • The script is made to start a timer of 30min every time the button is pressed.
  • If the button is pressed when the timer is already running, the countdown restarts
  • The relay for the ventilation is connected on GPIO 24
  • Write your mac address(es) below indicated in yellow (if you don't know them, just comment the line and run the script, you will see the mac displayed when you press the button).
  • You have to half configure the Dash button before the first use (but stop the process before assigning the button to a product).
  • There are a lot of scripts online (such as this one) but I find this solution more elegant as it does not use scapy... only standard stuff. Source of where of what Ibuilt this script on




Prerequisites:
sudo apt-get updatesudo apt-get install python-dev python-pipsudo pip install --upgrade distributesudo pip install ipythonsudo pip install --upgrade RPi.GPIO

The (python) script:

#!/usr/bin/env python
import socketimport structimport timeimport RPi.GPIO as GPIOimport binasciifrom subprocess import call

rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))GPIO.setwarnings(False)GPIO.setmode(GPIO.BCM)GPIO.setup(24, GPIO.OUT, initial=GPIO.HIGH)
noReentry = False
while True:    packet = rawSocket.recvfrom(2048)    ethernet_header = packet[0][0:14]    ethernet_detailed = struct.unpack("!6s6s2s", ethernet_header)    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])    source_ip = socket.inet_ntoa(arp_detailed[6])

    if source_mac in ("ac634e4c1e76", "44350d5a4ac5"):        print "Button pressed! MAC=" + source_mac + ", IP = " + source_ip#        call(["/root/relayON.sh", "-l"])        if noReentry:                print "No reentry please"        else:                noReentry = True                GPIO.output(24, GPIO.LOW)                time.sleep(15)                noReentry = False                GPIO.output(24, GPIO.HIGH)