Skip to Content

Using an Amazon Dash Button to Trigger Shell Commands

I recently bought a server to use for data analysis and web hosting. The server runs ESXi, a bare metal hypervisor used to create and manage virtual machines (VMs). Most of these VMs run Debian and are on 24/7, but I also wanted a Windows 10 VM for occasional gaming that I could switch on and off.

Since ESXi is software, the Windows machine I made doesn’t have a physical power button. Instead, I had to boot up my laptop and login to the ESXi web client each time I wanted to start the VM. This quickly became annoying, and I began looking for an easier way. I whipped up a quick python script to make an Amazon Dash button into a portable VM power button. The script runs as a daemon on a Raspberry Pi Zero W I had sitting around. It can be adapted to issue any shell command, not just the SSH used here.

Setup

The first thing you need to do is setup the Dash button via the Amazon shopping app. Go through all the initial steps of connecting the button to your home network, but cancel before actually selecting a product.

Next, you need to find the MAC address of your Dash button. You can do this by pressing the Dash button while looking at the connected clients section of your router’s web client. The Dash button should appear as a connected device (if only briefly).

Finally, change the gateway variable in the script below to the gateway of your router and the MAC address to that of your Dash button. You can test the script by running sudo /usr/bin/python3 scriptname.py. This script needs to run as sudo/root for socket access. It will print “Button Pressed!” in stdout if successful. Make sure you’ve installed Python 3 and the scapy module. If you plan to use it for ESXi, edit vm_name and $USERNAME to fit your needs.

import datetime
import subprocess
from scapy.all import *

# Change gateway, vm name, and dash button MAC address as needed
old_time = time.time()
gateway = '192.168.1.1'
dash_mac = 'xx:xx:xx:xx:xx'
vm_name = 'whatevername'

# Get the vm id of your named vm from esxi
all_vms = subprocess.check_output(
    ['ssh', '-i', '/home/$USERNAME/.ssh/id_ed25519',
     'root@192.168.1.161', 'vim-cmd',
     'vmsvc/getallvms', '|grep', vm_name])
vm_id = str(all_vms)[2]

# Power on the vm
# You can edit this section to issue your own command
# by the command in changing check_output()
def dash_pressed():
    print('Button pressed!')
    subprocess.check_output(
        ['ssh', '-i', '/home/$USERNAME/.ssh/id_ed25519',
         'root@192.168.1.161', 'vim-cmd',
         'vmsvc/power.on', str(vm_id)])

# ARP packet sniffing stuff
def arp_display(pkt):
    global old_time

    if pkt[ARP].op == 1:
        if pkt[ARP].hwsrc.upper() == dash_mac.upper() \
                and pkt[ARP].pdst != gateway:
            if time.time() - old_time > 10:
                dash_pressed()
                old_time = time.time()

Service

If you’re running Raspbian or some other Linux distro you can make this script into a service using systemd. Start by creating the following file, substituting $NAME for your own script name:

/lib/systemd/system/$NAME.service

Edit the script to include the following, changing the path to your own script:

[Unit]
Description=Whatever the function of your script is
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python3 /abs/path/to/script.py

[Install]
WantedBy=multi-user.target

Then run the following commands to enable and start your service:

sudo systemctl enable $NAME.service
sudo systemctl daemon-reload
sudo systemctl start $NAME.service

It will now run constantly in the background, even after a reboot. To disable it, simply use:

sudo systemctl stop $NAME.service
sudo systemctl disable $NAME.service

And then delete the .service file you made earlier.

And that’s it. This is a simple trick that will hopefully make Dash buttons useful for something other than accidentally buying fifty packs of gum.