PROWAREtech








Raspberry PI: Garage Door Opener
Required for this project is a Raspberry Pi Zero W or Raspberry Pi 3 Model B+ (other models, like the Raspberry Pi 3 Model A+, may also work), compatible power supply, button, 5 volt relay switch, solder and soldering gun, cables/wires, circuit board, a basic understanding of the HTTP (Hypertext Transfer Protocol), the Python programming language and the Linux operating system.
This tutorial assumes the use of Windows 10.
Setup the Raspberry Pi
If the Raspberry Pi's Raspbian OS is already installed and configured, skip this section.
- Download and install SD Card Formatter for Windows; download from sdcard.org.
 - Quick format the Raspberry Pi's micro SD card.
 - Download and install Win32 Disk Imager; download from sourceforge.net.
 - Download Raspbian Lite from raspberrypi.org.
 - Install Raspbian Lite image using Win32 Disk Imager.
 - Install micro SD card and boot Raspberry Pi device.
 - Login as: pi, password: raspberry
 - 
		Configure Raspbian by issuing a 
sudo raspi-configcommand from the command line prompt.- Under 
Network Options, setup wireless networking. - Under 
Interface Options, enable SSH. - Under 
Localization Options, configure the keyboard. - Under 
Advanced Options, expand filesystem. - Reboot.
 - Login.
 
 - Under 
 - Issue a 
sudo apt-get update && sudo apt-get upgradecommand to update the system. - 
		To access the Raspberry Pi file system over the network from a Windows machine, install Samba.
		
- Issue a 
sudo apt-get install samba samba-common-bincommand at the command line. - 
				Issue a 
sudo nano /etc/samba/smb.confcommand to edit the samba configuration.- 
						Go to the end of the file and enter this text on new lines:
[user_pi] comment=User Pi path=/home/pi browseable=yes writeable=yes only guest=no create mask=0777 directory mask=0777 public=yes guest ok=yes
 - Hit CTRL+X to exit.
 - Save the file when prompted.
 
 - 
						Go to the end of the file and enter this text on new lines:
 - Issue a 
sudo chmod 0777 /home/picommand at the command line. - Reboot.
 - Login.
 
 - Issue a 
 - Type 
pythonat the command prompt. Python version 2.x should be in use. 
Program the Raspberry Pi
All 5 volt relays for this application should look like this. For this project, pin number 7 is connected to IN on the relay while pin number 2, which is 5 volts, is connected to VCC. Finally, pin number 6, which is ground, is connected to GND.
Circuit Diagram
Python Coding
Run this code by issuing a sudo python garagedoor.py command at the command line. Then open a browser with access to the same network and enter the computer's IP address using port 8000 (something like http://192.168.1.5:8000/). The host name can also be used instead of the IP address (something like http://hostname:8000/).
import os
import RPi.GPIO as GPIO
from time import sleep
import SimpleHTTPServer
import SocketServer
import urlparse
def build_html_page(head_child):
	C = float(os.popen("vcgencmd measure_temp").readline().replace("temp=","").replace("'C","").replace("\n","")) # get cpu temp
	if(C >= 70.0):
		color = "#f00"
	else:
		color = "#00f"
	F = 1.8 * C + 32 # convert C to F
	return str("""<!DOCTYPE html>
	<html>
		<head>
			<style>
				label {
					margin:7px;
				}
				fieldset {
					border:1px solid #ccc;
				}
			</style>
			<title>Garage Door</title>
			<meta name="viewport" content="width=device-width" />
			""" + head_child + """
		</head>
		<body>
			<div style='margin-top:25px;text-align:center;'>
				<div style='text-align:left;margin:auto;border:1px solid #ccc;width:220px;padding:5px;'>
					<form method=POST action='/'>
					<fieldset><legend>garage door</legend><input type=password name=pin placeholder='Enter PIN' style='width:185px;' maxlength=25 /></fieldset>
					</form>
				</div>
			</div>
			<div style='text-align:center;color:""" + color + """;margin-top:20px;'>CPU temp: """ + str(F) + """'F</div>
	</body></html>""");
def http_trigger_door():
	GPIO.setup(7,GPIO.OUT) # use pin number 7 for the relay IN connection
	sleep(.33)
	GPIO.setup(7,GPIO.IN) # notice that just GPIO.setup is used, not GPIO.output which could damage the Raspberry Pi
def button_trigger_door(ev=None):
	http_trigger_door()
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
	def __init__(self,req,client_addr,server):
		SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self,req,client_addr,server)
		
	def do_POST(self):
		post_body = self.rfile.read(int(self.headers['Content-Length']));
		qs = dict(urlparse.parse_qs(post_body)) # returns a dictionary
		if(qs.get("pin") != None):
			with open('GARAGE_DOOR_PIN.txt', 'r') as pin_file: # GARAGE_DOOR_PIN.txt must exist
				if(pin_file.read() == qs.get("pin")[0]):
					http_trigger_door()
		self.send_response(200)
		self.send_header("Content-type", "text/html")
		html = build_html_page("<meta http-equiv='refresh' content='0; url=/' />") # even if a browser does not support this, it will still work overall
		self.send_header("Content-length", len(html))
		self.end_headers()
		self.wfile.write(str.encode(html))
		
	def do_GET(self):
		self.send_response(200)
		self.send_header("Content-type", "text/html")
		self.send_header("Cache-control", "no-store")
		self.send_header("Pragma", "no-cache")
		html = build_html_page("")
		self.send_header("Content-length", len(html))
		self.end_headers()
		self.wfile.write(str.encode(html))
if __name__ == '__main__': # Program starts here
	GPIO.setmode(GPIO.BOARD) # set GPIO numbering mode
	GPIO.setup(8,GPIO.IN,pull_up_down=GPIO.PUD_UP) # Set the mode of 8 pin to input and pull up to high level (3.3v)
	GPIO.add_event_detect(8,GPIO.FALLING,callback=button_trigger_door,bouncetime=1000) # wait for falling and use bouncetime to prevent multiple calls to callback function
	try:
		port = 8000
		httpd = SocketServer.TCPServer(("0.0.0.0", port), Handler)
		httpd.serve_forever()
	finally:
		GPIO.cleanup()
GARAGE_DOOR_PIN.txt
1234
Additional Configuration for the Raspberry Pi
Now, configure the Raspberry Pi to automatically run the above script at startup so that the device is more autonomous.
- Issue a 
sudo nano /etc/rc.localcommand. - Go to the bottom of the page, before the 
exit 0line. - Enter a new line of text reading 
cd /home/pi. Substitute/home/piwith the actual directory to the script file. - Enter another new line of text reading 
sudo python garagedoor.py &. Substitutegaragedoor.pywith the name of the actual script file name. Do not forget the ampersand at the end so that execution will return and not wait for the Python script to finish. - Hit CTRL+X to exit.
 - Save the file when prompted.
 - Issue a 
sudo crontab -ecommand. - Enter (at the end of the file, preferably) 
0 12 * * * sudo reboot. This is to make the system restart every 24 hours to, as of the writing of this, fix a bug that causes the Python HTTP server to hang after some hours of use.