Pi Zero Network Controlled Relay

From spiderprojects
Jump to: navigation, search

The Story

I've been looking at Raspberry Pis for a while. They seem like a super easy to use little development board making them the perfect thing to start experimenting with home automation on. When the Pi Zero went on sale at Microcenter for $0.99 I had to buy one. With a few extra components and the right software I was able to set up a web controlled relay that could be connected to any number of physical devices.

What You'll Need ~$30

NOTE: Since writing this the Pi Zero W has been released. This comes with on board wireless capabilities and and would reduce the accessories costs. All you would need from this category would be the the micro SD card and the GPIO header pins.

Setting up the Hardware

Relay Interface

I pulled 5V and ground power connections for the Relay Board from the GPIO pins. I read that this just passes whatever power is left from your usb power supply that isn't used for running the Pi itself. I found this awesome Design With Descriptions Posted to Google Docs by Michael Thomas.

Relay Interface

I used 2 of these circuits on a small prototype board between the Pi Zero and the 2 Channel Relay Board I'm using.

Relay Interface Circuits

The Whole Package

I put everything in a plastic box I had sitting around. I had to drill a couple holes in the top to make room for the transistors on my relay interface board. I also drilled 3 holes in one side of the box. 2 for Input/Output cables and 1 for the power cable.

Circuit Inside Enclosure

Setting Up Raspbian with PiBakery

David Ferguson has made an amazing program over at www.pibakery.org. You can use it to easily set up your SD card to run a Raspberry Pi headless (without a keyboard, mouse, or monitor). Just add the simple building blocks, modify some settings, and you're ready to plug it in and connect remotely. I set my pi up to automatically connect to my network and install Apache, PHP, and MySQL. The last setting added to my Pi Bakery recipe is to set the Pi to boot into Console mode. This just disables the graphic display to save some processor power since we won't be plugging in a monitor.

Pi Bakery Setup

Once your recipe is complete just click Write, select your micro SD card, and choose Rasbian Full as your operating system.

Setting Up Your Web Interface

Pi Setup and Permissions

Now plug in your OTG adapter and USB Wifi, connect the power supply, and give it about 5 minutes or so to boot up. You want to be sure to give it enough time to run through your Pi Bakery script on the first boot.

Once the Pi is up and running you need to ssh into it to create the Web pages and code to control the GPIO pins. I recommend using your router to assign a static IP address to your Pi. I prefer the application Putty to make my ssh connection, but use whatever you know and are comfortable with. Run the following command and give the Pi time to update and reboot again.

sudo apt-get update && sudo apt-get -y upgrade && sudo reboot

In order for the software to be able to control the GPIO pins you have to do one of 2 things. There are special software packages that can allow a kind of layered access to the GPIO pins from what I understand. The other option, which I have used is to allow "wwww-data" (apache) user to have root access through sudo. Enter this command:

sudo visudo

Then add the following line to the end of the file:

www-data ALL=(root) NOPASSWD:ALL

You'll also want to make sure that your Apache installation is setup to load index.php files by default.

sudo nano /etc/apache2/apache2.conf

Add the following line to the <Directory /var/www> section.

DirectoryIndex index.php

The final block should look like this.

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
	DirectoryIndex index.php

GPIO Pin Control and Python

Next we'll create the python file to actually control the GPIO pins. I set pins 11 and 13 as output to control 2 relay switches and pins 7 and 15 as inputs to possibly read the state of our output switches. Run the following command to open the new file in the default pi account home folder:

sudo nano /home/pi/Switch.py

And here is the code I wrote to check the input pins and control the outputs. For now it just reads the inputs and turns the selected output pin on for a couple seconds, then back off.

#!/usr/bin/env python
import RPi.GPIO as GPIO
import time
import sys

#Set the Pi to reference the physical pin numbers

#Read in which switch was passed by command line arguement
SwNum = str(sys.argv[1])

#Setup our IO Pins
#Control Switch 1
GPIO.setup(11, GPIO.OUT)
#Control Switch 2
GPIO.setup(13, GPIO.OUT)
#Sense Pin 1
GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
#Sense Pin 2
GPIO.setup(15, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

#Read our Inputs

#Check which switch has been passed to trigger
if SwNum == "1":
elif SwNum == "2":

#Turn our switch on for 2 seconds, then back off
GPIO.output(OPin, GPIO.HIGH)
GPIO.output(OPin, GPIO.LOW)

Now make this file executable with the following command

sudo chmod +x /home/pi/Switch*

Web Interface

Next we'll need a couple php files to create the actual interface. Run the following command to open the new file in the default Web Server folder:

sudo nano /var/www/html/index.php

The following code will create a page with two buttons that send commands through AJAX to another PHP file. This way the whole page doesn't reload every time you click one of the buttons.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

<button type="button" name="s1">Trigger One</button>
<button type="button" name="s2">Trigger Two</button>
<script type="text/javascript">
				//alert($(this).text());  //Testing
				switch ($(this).text()) {
						case "Trigger One" :
				type: 'POST',
				url: 'Trigger.php',
				data: {switch:"1"},
				success: function(data) {

						case "Trigger Two" :
				type: 'POST',
				url: 'Trigger.php',
				data: {switch:"2"},
				success: function(data) {


Finally create the PHP script that will call the command to run the Python script.

sudo nano /var/www/html/Trigger.php

And add the code to appropriately call the Python script.

	//This lets us run this php through the buttons or by calling the address directly
        $switch = $_POST['switch'];
        if($switch == "") {
                $door = $_GET['switch'];

        $command = escapeshellcmd('sudo python /home/pi/Switch.py '.$switch);
		$output = shell_exec($command);
		echo $output;


I'm not a security expert, but if you are going to make this web interface available to the internet (So you can control your buttons from anywhere with an internet connection) you'll need to add some security. I followed Justin Ellingwood's Tutorial on DigitalOcean.com using an .htaccess file. I'll cover the steps I used here too.

Install Necessary Utilities

sudo apt-get update && sudo apt-get install apache2-utils

Create a Password File

sudo htpasswd -c /etc/apache2/.htpasswd Username

This will ask you to enter and confirm a password. If you want to add more users run the command again without "-c"

sudo htpasswd /etc/apache2/.htpasswd NextUsername

Protect Specific Directories

sudo nano /etc/apache2/apache2.conf

Change the <Directory /var/www/> section from AllowOverride None to AllowOverride All.

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride All
	Require all granted
	DirectoryIndex index.php

Now create your .htaccess file.

sudo nano /var/www/html/.htaccess

And add the appropriate lines to point to your .htpasswd file previously created.

AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

Restart Apache

sudo service apache2 restart

Bonus: Alexa Integration with IFTTT


Enjoy and feel free to report any problems or suggestions to longet@spider.dnsdojo.net.