Raspberry Pi Home Automation Project: Remote Power Plug Socket Control

From hacking dash buttons it is a small step towards further home automation. Home automation in the sense of remotely controlling power plug sockets. This way a dash button can be used as an additional light switch.
The ingredients for such a project are

Raspberry Pi (Zero W)
Amazon Dash Button
433 MHz receiver and transmitter
Remote controlled power plug sockets (ideally with DIP switches)

Software

On the Raspberry Pi the following libraries are required at least:

sudo pip3 install rpi-rf     # https://github.com/milaq/rpi-rf
sudo pip3 install scapy-python3   # https://github.com/phaethon/scapy

Setup

433MHz Receiver

Pi (Zero W) 433 MHz Receiver
GND GND
3,3 V 3,3 V
GPIO 27 Data

433MHz Transmitter

Pi (Zero W) 433 MHz Transmitter
GND GND
3,3 V 3,3 V
GPIO 17 Data

Power Plug Sockets

To set up the power plug sockets see their manual. The ones with DIP switches should be preferred over those without. DIP switches allow to precisely select the addresses of the power plug sockets.

Preparations

First the codes to toggle the power plug sockets are required. These can be read using the example script from  the rpi-rf library.

sudo python3 rcv.py

Make a note of the codes for turning the power on and for turning the power off for each power plug socket. The codes have to be adapted in the python script below. Required is also the MAC adress of the Dash Button to be used as an additional light switch.

from scapy.all import *
import http.client, urllib
from rpi_rf import RFDevice

from time import sleep

#A on : 1234567 A off: 9876543

fileLRL="/home/pi/state.txt"

rfdevice = RFDevice(17)
rfdevice.enable_tx()
protocol = 1
pulselength = 350

def readFile(fileName):
  state=0
  try:
    target = open(fileName, 'r')
    state = target.read()
    target.close()
    print("Read toggle state: " + str(state))
  except FileNotFoundError:
    writeFile(fileName, state)
  return state

def writeFile(fileName, state):
  print("Store toggle state: " + str(state))
  target = open(fileName, 'w')
  target.write(str(state))
  target.close()
  return True

def toggleLight():
  state = readFile(fileLRL)
  print("LRL state " + str(state))
  if state == str(0):
    print ("light is currently off, turn it on")
    rfdevice.tx_code(1234567, protocol, pulselength)
    writeFile(fileLRL, 1)
  else:
    print ("light is currently on, turn it off")
    rfdevice.tx_code(9876543, protocol, pulselength)
    writeFile(fileLRL, 0)

def arp_detect(pkt):
  if pkt[ARP].op == 1: # network request
    mac = pkt[ARP].hwsrc
    mac = mac.lower()
    ip = pkt[ARP].psrc

  if mac == 'xx:xx:yy:xx:yy:xx': # dash button
    toggleLight()
    sleep(5)
    return "dash button detected\n"

try:
  print( sniff(prn=arp_detect, filter="arp", store=0))
except KeyboardInterrupt:
  rfdevice.cleanup()
  exit()

This way the dash button can be used as an additional remote control in parallel to the original remote control of the power plug sockets. Although this solution cannot keep up with the original remote control regarding the response time. There are several steps in between which take their time…

Raspberry Pi Zero, dash button, remote power plug socket
Raspberry Pi Zero, dash button, remote power plug socket
Advertisements

Dash Button Hacks

Quite some time ago Amazon launched the dash buttons. Amazon intends them to be used for ordering everyday products. Without even knowing the price before automatically finalizing the order! This way I don’t want to use such a button.
In the end a dash button is a relatively cheap WiFi button. Quickly the first users found out how to hack them and use them in different contexts. A dash button can be a doorbell, a phone finder, a tool for doing statistics (work started/stopped, …)  or it could simply switch the light on.
Here is a short description on how to set up a dash button for alternative uses.

Hardware

Raspberry Pi (Zero)
Amazon Dash Button

Dash Button Setup

    • Follow the setup descriptions as described here. The trick is to leave the Amazon app directly after having copied the WiFi credentials to the button.
    • Find out the dash button’s IP and MAC, e.g. by looking at the active devices in your router’s setup.
    • The button will constantly nag in the amazon app about being setup uncompletely. Block the button’s internet access using the setup of the router.

Software

A small Python script on a Raspberry Pi „sniffs“ the local network for packets of all the devices within the network. If the MAC of a dash button is found certain actions can be triggered.

Additionally required packets:

sudo pip install scapy # http://www.secdev.org/projects/scapy/
sudo apt-get install tcpdump
#!/usr/bin/python
from scapy.all import *
import httplib, urllib

def doWhatIWant():
  print "TODO"

def arp_detect(pkt):
  #pkt.show() # debug info
  if pkt[ARP].op == 1: # network request
    mac = pkt[ARP].hwsrc
    mac = mac.lower()
    ip = pkt[ARP].psrc
    print "IP: " + str(ip) + ", MAC: " + str(mac)

  if mac == 'xx:xx:xx:xx:xx:xx': # dash button
    doWhatIWant()
    sleep(5)
    return "dash button detected\n"
  else:
    print "Unknown: " + str(ip) + ", " + str(mac)
    return "Unknown MAC: " + pkt[ARP].hwsrc

try:
  print sniff(prn=arp_detect, filter="arp", store=0)
except KeyboardInterrupt:
  exit()

To run the script automatically after boot simply add a line to /etc/rc.local:

sudo python /home/pi/sniff.py&

Now the dash button is ready to be used for anything else.

To make it a doorbell or a phone finder one could use pushover. The app is installed on a smartphone. That way it is possible to send notifications to this smartphone using the pushover API  using an API and a user key.

Example code

def sendNotification(message):
  conn = httplib.HTTPSConnection("api.pushover.net:443")
  conn.request("POST", "/1/messages.json",
  urllib.urlencode({
  "token": "APItoken",
  "user": "usertoken",
  "message": str(message),
 "sound": "intermission"
 }), { "Content-type": "application/x-www-form-urlencoded" })
 conn.getresponse()