Garage Raspi Overview
Smart garages are the next big thing in home automation, and with the help of a Raspberry Pi, Home-Assistant and Room-Assistant, you can easily convert your garage into a smart garage that provides full control of your garage door, temperature and door status monitoring, and advanced automations.
In this post, we’ll be covering the complete guide to building a smart garage control system using a Raspberry Pi and Room-Assistant, including the wiring, hardware, and network and power requirements.
We’ll also be discussing the various garage functions that you can add, such as relay for garage door opener, reed switch for manual doors open/closed status, PIR motion for occupancy sensor, and DHT11 temperature and humidity sensor.
This garage controller was one of the first devices I built and integrated into Home Assistant. Using the Raspberry pi I already had on hand and some amazon sensors and relays I’ve successfully converted my garage into a Smart Garage!
Garage Functions
The main goal to the automation was to get full control of the garage door opener as the 2 that came with the rental home never worked. Could we have asked the homeowners to fix or replace the units, sure but where the innovation in that?
On top of the door control, I also added some devices to allow some advanced automatons to happen through Home Assistant.
- Relay for Garage door opener (5v relay)
- Relay for 120v outlet control (5v relay)
- Reed Switch for Man doors open/closed status
- PIR Motion for Occupancy sensor
- DHT11 Temp/Humid sensor
Wiring
Everything wires to the GPIO pins of the Raspberry Pi as seen in the photo below. Nothing too complex going on here, just don’t forget the resistor for the LED.
Undocumented Change! I ended up needing to add a capacitor to the PIR motion sensor as the power was not consistent at the device. Small little 4.7UF capacitor did the trick! (Change not shown in diagram below)
Hardware
Using on old Raspberry Pi Model B v1 that was a dumpster find, I built the controller with (2) 5v relay boards, PIR motion senor, Reed Switches for the doors, and a DHT11 temp sensor mounted to the top of the controller.
- Raspberry Pi Model B v1
- (2) 5v relay boards
- DHT11 Temperature and Humidity Sensor
- PIR Motion Sensor
- (3) Reed Switches
- Case LED (5v blue)
Network and Power
I have a network switch in the garage for devices like this that is within 20’ of the controller. Easy cable run for hardwired connectivity.
Power is fed from the outlet that also feeds the garage door opener. It’s conveniently located directly next to the opener in the ceiling.
Garage Door Controls
Using the N/O (normally open) relay contacts I’ve wired the wall switch in parallel. This gives both automated functionality through the home assistant app, it also allows the wall switch to function as intended.
This has an issue where the door controller is looking for a momentary switch, press the wall switch to initiate and release once door moves. As I have a latching relay with this setup, some trickery was needed.
In home assistant I’ve created an automation that watches for state change on the relay switch, and if seen turns it back off. Less than 1 sec of delay between initiation and deactivation.
This works like a charm for this application, turning the relay into a momentary switch.
Automation excerpt:
automation:
# If the garage latching relay has been activated,
# turn the garage relay off immediately, creating a momentary relay
- alias: "Turn off garage door relay"
trigger:
platform: state
entity_id: switch.garage_door
to: 'on'
action:
service: switch.turn_off
entity_id: switch.garage_door
Room-Assistant config excerpt:
switches:
# Relay 1 - Garage door open/close
- name: Garage Door
pin: 17
icon: mdi:garage-variant
Electrical Outlet Control
Using the other relay to control an outlet in the garage for things like fans and lights. Setup the relay in Room-Assistant and then automate things in Home Assistant to control the outlet.
Room-Assistant config excerpt
# Relay 2 - FAN
- name: Garage Fan
pin: 18
icon: mdi:fan
Door Status
Door status is attained using some reed switches mounted to the door frames, magnets mounted adjacent on the doors with wires running back to the controller.
Room-Assistant config excerpt:
gpio:
binarySensors:
# Garage Back Door position reed switch
- name: Garage Back Door
pin: 15
deviceClass: door
# Garage House Door position reed switch
- name: Garage House Door
pin: 4
deviceClass: door
Temperature
Using the DHT11 sensor and a script to report the temp every min (cron job through room-assistant script.
I’m using the old depreciated Adafruit_Python_DHT library due to issues with the new circuit python version and already having this working.
The sensor is mounted to the controller which is up in the unfinished rafters of the garage. This gives a skewed reading as the air up there is way hotter than below at head height.
Room-Assistant config excerpt:
shell:
sensors:
# DHT11 Sensor reporting the temp °F result
- name: Garage Temperature
command: 'python3.7 /home/pi/room-assistant/script/myDHT.py'
regex: '(-?[0-9.]+)F'
cron: '*/2 * * * *'
icon: mdi:temperature-fahrenheit
unitOfMeasurement: '°F'
deviceClass: temperature
# DHT11 Sensor reporting the humid % result
- name: Garage Humidity
command: 'python3.7 /home/pi/room-assistant/script/myDHT.py'
regex: '(-?[0-9.]+)%'
cron: '*/5 * * * *'
icon: mdi:water-percent
unitOfMeasurement: '%'
deviceClass: humidity
Motion
PIR sensor connected to the controller and mounted using a few standoffs to give it *better placement. The controller is mounted upside down putting the sensor on the ceiling next to the garage door opener. It is blocked by some obstructions but overall covers the doors.
No additional scripting was required as this is supported in room-assistant. Just give the pin number and name the sensor.
Room-Assistant config excerpt:
gpio:
binarySensors:
# PIR motion sensor
- name: Garage Motion 1
pin: 14
deviceClass: motion
Additional debounce configuration added for motion sensor using the Room-assistant entities configuration. This clears up any bouncy input from the device, giving a stable reading to the front end.
entities:
behaviors:
garage_motion_sensor:
debounce:
wait: 0.75
maxWait: 2
Software
Everything is controlled and mapped to the home assistant dashboard over MQTT via the room-assistant system.
Room Assistant Config
This config file is the meat and potatoes of the program. Find it in the /home/$USER/room-assistant/config/local.yml
# ########################
# Raspi Config
# hass-raspi6
# Garage Ceiling
# Garage control and monitoring
# 10.10.10.73
# ########################
# ############
# GPIO Pin-Out
# ############
#
# Inputs:
# Pin: {GPIO NUMBER} Use: {Pin function} ConnectPin: {DB9 PIN}
# Pin: 04 Use: Garage door CLOSED position sensor (reed sw) ConnectPin: 1
# Pin: 23 Use: Garage door partial OPEN position sensor (reed sw) ConnectPin: 2
# Pin: 24 Use: Garage door OPEN position sensor (reed sw) ConnectPin: 3
# Pin: 25 Use: Garage Back Door Sensor (reed sw) ConnectPin: 4
# Pin: 15 Use: Garage House Door Sensor (reed sw) ConnectPin: 5
# Pin: 14 Use: Garage Motion Sensor (PIR) ConnectPin: 6
#
# Outputs:
# Pin: 17 Use: Garage door control (relay 1)
# Pin: 18 Use: Garage Fan Control (relay 2)
# Pin: 22 Use: Garage CPU Case LED (blue)
# Pin: 27 Use: humidity/temp DHT11 sensor using the shell functions below
# #######################
# Global Config settings
# #######################
global:
instanceName: garage
integrations:
- homeAssistant
- gpio
- shell
# #######################
# Cluster settings
# #######################
# Config options for clustering multiple Room-Assistant
# Give leader more weight
cluster:
weight: 1
networkInterface: eth0
port: 6425
timeout: 60
peerAddresses:
# raspi1 patio
- 10.10.10.70:6425
# raspi2 office
- 10.10.10.71:6425
# raspi3 sprinkler
- 10.10.10.72:6425
#raspi4 kitchen
- 192.168.1.75:6425
#raspi5 crawlspace
- 10.0.0.74:6425
# raspi6 garage <-- this cpu
# - 10.10.10.73:6425
# #######################
# home assistant settings
# #######################
homeAssistant:
mqttUrl: mqtt://10.10.10.21:1883
mqttOptions:
username: homeassistant
password: {LONG_RANDOM_STRING}
# #######################
# GPIO settings
# #######################
gpio:
binarySensors:
##########################
# NON-FUNCTIONING
#
# Connection issue at controller requiring tinkering
#######################################################
# Closed garage door position switch
# GPIO-23:DB9-2?
- name: Garage Door Closed
pin: 23
deviceClass: garage_door
# Partial open garage door position switch
# GPIO-25:DB9-?
- name: Garage Door Partial Open
pin: 25
deviceClass: garage_door
# Full open garage door position switch
# GPIO-24:DB9-?
- name: Garage Door Open
pin: 24
deviceClass: garage_door
########################################################
# Garage Back Door position reed switch
# GPIO-15:DB9-5
- name: Garage Back Door
pin: 15
deviceClass: door
# Garage House Door position reed switch
# GPIO-4:DB9-1
- name: Garage House Door
pin: 4
deviceClass: door
# PIR motion sensor
- name: Garage Motion 1
pin: 14
deviceClass: motion
# #######################
# Switches settings
# #######################
switches:
# Relay 1 - Garage door open/close
- name: Garage Door
pin: 17
icon: mdi:garage-variant
# Relay 2 - FAN
- name: Garage Fan
pin: 18
icon: mdi:fan
# blue RasPi case LED
- name: Garage LED
pin: 22
icon: mdi:led-on
# #######################
# Shell settings
# #######################
shell:
sensors:
# DHT11 Sensor reporting the temp °F result
- name: Garage Temperature
command: 'python3.7 /home/pi/room-assistant/script/myDHT.py'
regex: '(-?[0-9.]+)F'
cron: '*/2 * * * *'
icon: mdi:temperature-fahrenheit
unitOfMeasurement: '°F'
deviceClass: temperature
# DHT11 Sensor reporting the humid % result
- name: Garage Humidity
command: 'python3.7 /home/pi/room-assistant/script/myDHT.py'
regex: '(-?[0-9.]+)%'
cron: '*/5 * * * *'
icon: mdi:water-percent
unitOfMeasurement: '%'
deviceClass: humidity
# - name: Garage CPU Temp
# command: '/home/pi/room-assistant/script/cpuTemp.sh'
# cron: '*/1 * * * *'
# unitOfMeasurement: '°F'
# deviceClass: temperature
# icon: mdi:thermometer-lines
# Script to check onboard temp sensor reading
- name: Garage CPU Temp
command: '/home/pi/room-assistant/script/cpuTemp.sh'
cron: '*/2 * * * *'
unitOfMeasurement: '°F'
deviceClass: temperature
# Script to check voltage and return boolean if no errors seen.
# See the script for more
- name: Garage CPU Voltage
command: '/home/pi/room-assistant/script/cpuVolt.sh'
cron: '1 */1 * * *'
deviceClass: power
# Report CPU uptime in sec
- name: Garage CPU Up Time
command: '/home/pi/room-assistant/script/cpuUp.sh'
cron: '* * * * *'
unitOfMeasurement: 's'
# Free memory `free -h` results
- name: Garage CPU Free Memory
command: '/home/pi/room-assistant/script/freeMem.sh'
cron: '*/10 * * * *'
unitOfMeasurement: 'MB'
# - name: Garage Wifi Strength
# command: 'iwconfig wlan0 | grep -i quality'
# regex: 'Signal level=(-?[0-9]+) dBm'
# cron: '*/30 * * * *'
# icon: mdi:wifi
# unitOfMeasurement: dBm
# deviceClass: signal_strength
# - name: Garage CPU Free Storage
# command: '/home/pi/room-assistant/script/cpuStorage.sh'
# cron: '1 * */1 * *'
# unitOfMeasurement: 'GB'
# deviceClass: timestamp
# #######################
# Entity settings
# #######################
entities:
behaviors:
garage_motion_sensor:
debounce:
wait: 0.75
maxWait: 2
Scripts
Some additional helper scripts were also developed to return some info on the device for integrations and status’s over in home assistant.
Add these to room assistant using the shell.sensors
function like this:
shell:
sensors:
# DHT11 Sensor reporting the temp °F result
- name: Garage Temperature
command: 'python3.7 /home/pi/room-assistant/script/myDHT.py'
regex: '(-?[0-9.]+)F'
cron: '*/2 * * * *'
icon: mdi:temperature-fahrenheit
unitOfMeasurement: '°F'
deviceClass: temperature
cpuUp.sh
return the uptime in seconds formatted as int
#!/bin/bash
echo `cat /proc/uptime |awk '{print $1}' |cut -d '.' -f1`
cpuTemp.sh
return the CPU reported temp
#!/bin/bash
cpuTemp=`vcgencmd measure_temp |cut -d "=" -f2 |cut -d "'" -f1 | awk '{print ($1 *9/5) + 32}'`
echo $cpuTemp
freeMem.sh
returns the remaining RAM on the pi
#!/bin/bash
memfree=`cat /proc/meminfo | grep MemFree | awk '{print $2}'`;
memtotal=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'`;
awk '/MemFree/{free=$2} /MemTotal/{total=$2} END{print (free*100)/total}' /proc/meminfo
#echo $(($memfree * 100 / $memtotal))
myDHT.py
adapted DHT11 temp sensor reading temp and humid
import Adafruit_DHT
import time
DHT_SENSOR = Adafruit_DHT.DHT11
DHT_PIN = 27
while True:
humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
if humidity is not None and temperature is not None:
temperature_f = temperature * (9 / 5) + 32
print("Temp={0:0.1f}F Humidity={1:0.1f}%".format(temperature_f, humidity))
exit()
else:
time.sleep(.05);
temperature_sensor_code.py
read DS18B20 sensor, report value in F
# Temp DS180b20 reading into F result on raspi
#
# https://pimylifeup.com/raspberry-pi-temperature-sensor/
# Modified from
# - git clone https://github.com/pimylifeup/temperature_sensor.git
import os
import glob
import time
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
def read_temp_raw():
lines = []
i = 0
# try to read the file 20 times, return the result
while not lines and (i < 19):
try:
f = open(device_file, 'r')
lines = f.readlines()
i += 1
except NameError:
time.sleep(1)
else:
if not lines:
f.close()
else:
f.close()
return lines
def read_temp():
lines = read_temp_raw()
if lines[0].strip()[-3:] != 'YES':
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_f
# print to reduced decimal place
print('{0:06.3f}'.format(read_temp()))
cpuVolt.sh
return boolean if no issues with voltage (power supply failure)
#!/bin/bash
THROTTLED=`/opt/vc/bin/vcgencmd get_throttled |cut -d "=" -f2`
RESULTS=0
if [[ "$THROTTLED" != *"0x0"* ]];then
RESULTS=1
fi
echo $RESULTS