Amazon Dash Button as openHAB Trigger

The problem I have is as follows. The remotes for my garage door openers do not work. My first HA project was to wifi enable my garage door opener which I did with a Raspberry Pi wired to a relay and WebIOPi. Over time this setup became more sophisticated but there is still one problem, on my wife’s iPhone it takes several screen clicks to trigger the garage:

  1. unlock the phone
  2. swipe to the screen with openHAB (or IFTTT Do)
  3. open the app
  4. wait for it to connect and load the sitemap
  5. press the button to trigger the opener

This is awkward and annoying to say the least. On Android with Tasker it is easier because I can detect when I’m nearing home and bring up a button to press automatically.

I want a solution that works for my wife that is as simple as the original remote, push one button.

Solution: Amazon Dash

Amazon Dash is a small hardware device that is designed to automatically order a product from Amazon at the push of a button. But these devices have three features that allow us to use them in openHAB:

  1. They only cost $5, far cheaper than the cheapest DIY solution I’ve seen
  2. If you abort their configuration after setting up the wifi settings but before selecting a product you can press the button and it will join the network but not order anything
  3. When it joins the network it generates an ARP request which can be sniffed on the network

So, based on this tutorial I wrote a new class for my already existing sensor reporting script that uses scapy to sniff the network for ARP packet from the dash button’s MAC address. When such a packet is detected it publishes “Pressed” to an MQTT topic and openHAB has an Item listening on that topic and triggers the garage when a message is published.

It seems to work pretty well, though from button press to the garage starting to go up it takes 10-20 seconds.

Python Code:
The full script is available at the link above. This script also supports GPIO pins and scanning for Bluetooth devices. The Dash button specific code is as follows:

"""
 Script: dash.py
 Author: Rich Koshak
 Date:   October 22, 2015
 Purpose: Checks the state of the given GPIO pin and publishes any changes
"""

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

import sys
import traceback
from scapy.all import *

class dash:
    """Represents a sensor connected to a GPIO pin"""

    def __init__(self, devices, publish, logger, poll):
        """Sets the sensor pin to pull up and publishes its current state"""

        self.logger = logger

        self.logger.info("----------Configuring dash: ")
        for addr in devices:
            self.logger.info("Address: " + addr + " Topic: " + devices[addr])
        self.devices = devices
        self.publish = publish
        self.poll = poll

    def checkState(self):
        """Detects when the Dash button issues an ARP packet and publishes the fact to the topic"""

        try:

            def arp_display(pkt):
                if ARP in pkt:
                    if pkt[ARP].op == 1: #who-has (request)
                        if pkt[ARP].psrc == '0.0.0.0': # ARP Probe
                            if self.devices[pkt[ARP].hwsrc] != None:
                                self.logger.info("Dash button pressed: " + pkt[ARP].hwsrc)
                                self.publish("Pressed", self.devices[pkt[ARP].hwsrc])
                            else:
                                self.logger.info("Received an ARP packet from an unknown mac: " + pkt[ARP].hwsrc)

            self.logger.info("Dash: kicking off ARP sniffing")
            print sniff(prn=arp_display, filter="arp", store=0, count=0)
            # Never returns
            self.logger.info("Dash: you should never see this")
        except:
            self.logger.error("Unexpected error in dash: %s", sys.exc_info()[0])
            traceback.print_exc(file=sys.stdout)

    def publishState(self):
        """Publishes the current state"""

openHAB Items:

Switch  T_D_Garage1     "Garage Door 1"        <garagedoor> // goes on the sitemap for "manual" trigger
String  T_D_Dash_Tide   "Tide Dash Button"     { mqtt="<[mosquitto:actuators/tide:state:default]" }
String  T_D_Dash_Bounty "Bounty Dash Button"   { mqtt="<[mosquitto:actuators/bounty:state:default]" }

openHAB Rule:

rule "Trigger Garage Door Opener 1"
when
        Item T_D_Garage1 received command or
        Item T_D_Dash_Tide received update or
        Item T_D_Dash_Bounty received update
then
    logInfo("Garage Controller", "The garage door 1 has been triggered")
    sendHttpPostRequest("http://192.168.1.201:8000/GPIO/17/sequence/500,01") // calls WebIOPi REST API
end

It might be possible to do this from a binding if I can figure out how to do the packet sniffing from Java. Despite being so slow I can think of a number of use cases where having a physical button to trigger something would come in handy.

If I figure out a way to remove or nicely cover the logo on the button I’ll post that here as a follow up.

Rich

Is there an equivalent of RFID tags that work with iOS? I bought a set of 10 tags and stick them in various places (window by the front door, night stand, etc.), and hold my (unlocked) Android phone up to them instead of navigating to a button to click. The Android openHAB app lets you long press a switch item to tie it to an RFID tag. If there were something similar for iOS, couldn’t you or your wife just hold your phones up to an RFID tag stuck to the sun visor to achieve the same as a button press on a physical device?

Another option with the Amazon dash buttons would be to “trick” DNS so the buttons attempt their comms to a web server on your private network instead of Amazon, and your web server reacts by sending the /CMD?item=state GET request (or proper REST API call) to openHAB.

Does your wifi network reach to the garage? If it does, then you could set openhab to only require authentication from external addresses, and simply create a desktop bookmark on the iphone home screen which turns the relevant openhab device on. So only one click required once the phone is unlocked.

These are all great ideas and considerations everyone. Unfortunately for me I tried most of them before settling on this latest attempt with the Dash buttons.

@watou, the her older iPhone (5s) doesn’t support NFC and Apple restricts NFC to only work for payment so a tag is yet another one of the things that is technically feasible but Apple forbids.

I used to use an NFC tag in my car to trigger the garage from my Android but I dock my phone while I’m driving an removing the phone from the dock to touch the tag was awkward. I never could get it to read the tag from the front either.

That would work but it wouldn’t really save me anything in terms of the amount of time from button press to action. The buttons stay in an off position until you press the button and all of that time spent from pressing the button until detecting and acting on it is the button joining the wifi network. For my purposes it was far easier to just bail out of the last setup step on the button setup and listen for the ARP packets. It turns out to be pretty light weight. I’ve seen no performance impact at all, though I am running it on my laptop/server, not on a RasPi.

@dan12345 , Trying to turn off authentication for internal addresses and using a desktop bookmark was my first approach way back when I started. The problem is that my wife’s phone hesitates to connect to the wifi just long enough that a third of the time it connects before she presses the button, a third of the time it is still connected to the cellular data network, and a third of the time it is in an inbetween state, not connected to anything. So it really only worked on the first press a third of the time. But my wife is impatient so she would press it repeatedly and the requests queued up so when the connection was finally made the door went up and down and up and down.

For others who don’t have such a finicky iPhone, try @dan12345 's approach first. If you are on Android, NFC tags and/or AutoLocation with Tasker are pretty awesome solutions. But if you are stuck like me, the Dash button seems to be an adequate, if not wholly satisfying solution.

what about one of those zwave keyrings?

I’ve not looked into those. My fear is that even though my WiFi makes it to the drive way I’m not sure the zwave does and at $30 a piece in hesitant to invest in something that doesn’t for sure work to fix what amounts to an annoyance. Plus I don’t know if the binding sorts them.

Another thought: one of those cheap keyring RF transmitters and relay receivers. £10 or so on eBay. Easy to hook up to a raspberry Pi.

One more thought is EnOcean devices which don’t need batteries and have decent range. Must be much faster to report in than any button that has to join the wi-fi network first. Of course, yet more expense…

Another option could be setting up an IFTTT DO button that triggers the garage door opener (which you have?), then add DO to the iOS notification panel. I find it takes about 5-10 seconds from unlocking my phone, pulling down the notification shade, waiting for the buttons to load (common IFTTT), and waiting for the signal to reach my server. No app launching/screen navigation necessary.

@hagenbuch The IFTTT Do button is my current solution for my wife. Unfortunately your experience is not ours. It can be sometimes 30 seconds to a minute before the garage triggers after pressing the Do button. Of course in that time she has pressed the button half a dozen times in frustration causing the door to receive lots of signals in sequence. Though in the best case I’ve seen it is at least 10 seconds from button press to door opening.

I didn’t know that you can put Do buttons in the notification panel though. That might ease the pain somewhat.

@watou and @dan12345 , those are both options worth pursuing in the future and I plan on looking into them soon.

I actually have a spare IR transmitter/relay (which openHAB and zwave rendered redundant). Worth nothing to me - if you live in the UK/Europe I’d be happy to post to you.

Dan

Thanks! Unfortunately I’m in Colorado, USA.

For the time being I’m no worse off than I was plus I learned a lot about how Amazon Dash buttons work plus some new Python coding techniques so I’m calling this project a success. :slight_smile:

@rlkoshak,

You may have figured out a good solution already, but I wanted to share mine for anyone looking for a quick way to send OpenHAB commands from iOS.

Instead of using the DO button (with iOS notification panel integration), I found a very flexible iOS app called Workflow that allows you to make custom “workflows” (like graphical scripts) that can be tied to buttons on the notification panel.
Workflows are designed by dragging and dropping pre-defined blocks into a sequence, where the output of one block feeds the input of the next block.

I built a workflow that calls the my.openhab.org REST API directly, which circumvents the IFTTT routing. All-in-all, this is much faster than the DO button because the Workflow buttons are immediately available in the panel (whereas I find the DO buttons take 2-3 seconds to load), and the web call is more direct.

The Workflow app costs like $5, but IMO it’s worthwhile. I did run across a couple gotcha’s though.

First, I had to make 2 separate web calls to my.openhab in order to authenticate, then send the command. Someone more savvy with HTTP may be able to find a way to do this in one call. Second, you need to encode your username/password in the URL, which means converting illegal characters such as “.” and “@” to “%2E” and “%40” respectively.

My Workflow looks like this, where the items in brackets need to be replaced with your information and be URL encoded:

Text block - https://[username]:[password]@my.openhab.org
Get Contents of URL block
Text block - https://[username]:[password]@my.openhab.org/CMD?[item_name]=[value]
Get Contents of URL block

What you end up with is a list of Workflow’s in the iOS notification panel, each of which can represent a command or sequence of commands to your my.openhab account. These can also be added as home screen icons.

1 Like

I looked at Workflow but didn’t want to spend the $5 on it if it, like everything else in iOS, wouldn’t allow me to embed the username and password in the URL. I may look into that but a higher priority for me right now is the fact that I will have a house sitter soon who doesn’t have a smart phone so I need to come up with something Dash like to get this working.Or just break down and get a new garage door opener. :smile:

For your use case a real garage door opener is probably the way to go… but I admire your dedication to home automation :stuck_out_tongue:

Rich,

What is the best way to contact you directly? I had exactly the same situation as you, and wanted to use a Dash button as a garage door opener that was controlled from openHAB. I just set up your script this evening, and after some Python issues started to get some errors. However, I’ve worked through them and found that the GitHub code wasn’t quite complete … I’ve added some error handling and some functionality, and I want to get them to you somehow. I’m not very familiar with GitHub though, so I’d like to contact you directly to make sure I am doing things the right way for you to see them.

Thanks!

You can git clone https://github.com/rkoshak/sensorReporter.git, make your changes, then back on the github site create a pull request (green button in the upper left).

In stead of or in addition to that you can post your updated code here which might make it easier for future readers of this thread to know of and include your changes.

If you want to contact me privately you can PM me through this forum. Click on my icon on this post and choose “Message”.

I’m not surprised the GitHub code has some errors. I had it working once then tried some stuff to see if I could get it working better, failed, and never fixed it. I’ve since moved on to the Aeon Minimotes which seem to be working reasonably well. I’d love to hear about your experiences with the Dash. I still have my two sitting around. I still think the range may be too short to work for me as a garage door opener but I might be able to use them as lamp switches, if they are responsive enough.

FWIW, I have a Dash button mounted to the back of my bed’s headboard. Before going to sleep, I hit the button and it triggers rules which put the house into a sort of “sleep” mode. Things like turning off the lights, making sure the garage is closed (and closing it if not), lowering the thermostat temperature. It’s been very convenient and high SAF.

Also, I integrated my Dash button a bit differently than you did. Instead of using Python I run a bash script (configured to execute when my server boots). It’s very simple, no error handling or anything fancy:

#!/bin/bash


while read -r line; 
do 
    curl http://localhost:8080/CMD?vSleep=ON; 
done < <(tcpdump -i eth0 arp and ether host a0:02:dc:42:4f:c0 -l)

Where the MAC address is that of my Dash button.

2 Likes

I like that use case. It wouldn’t work for me as well as my current setup. With a toddler in the house our lives have become exceptionally predictable so timer and presence is all I need to drive that sheet of thing.

And I went with the Python script mainly because I already wrote about 95% of the code already getting the GPIO and Bluetooth detection working. It ended up being a handful of new lines to add Dash support. Though apparently I’ve broken it along the way.

But if all you need is Dash, I don’t think one could beat your script for simplicity.

After Dash Button starts in Germany i try to use that script to get it running on my system but with no luck.

I installed the complete git hub sensorReporter, startet the install script and run as service. I can not get getMac.py running, no really got error message here.

WARNING: No route found for IPv6 destination :: (no default route?)
Traceback (most recent call last):
  File "getMac.py", line 10, in <module>
    print sniff(prn=arp_display, filter="arp", store=0, count=30)
  File "/usr/lib/python2.7/dist-packages/scapy/sendrecv.py", line 586, in sniff
    r = prn(p)
  File "getMac.py", line 6, in arp_display
    if pkt[ARP].op == 1: #who-has (request)
  File "/usr/lib/python2.7/dist-packages/scapy/packet.py", line 770, in __getitem__
    raise IndexError("Layer [%s] not found" % lname)
IndexError: Layer [ARP] not found

No idea what is wrong or missing.

Also i can not understand with your items how do you know wich button is pressed?

String T_D_Dash_Tide "Tide Dash Button" { mqtt="<[mosquitto:actuators/tide:state:default]" }

I can not see any mac address here or in script and not in rule. So how do you know wich one has been pressed?

Thx for any help or tipps