GaragePi - Garage Opener using Raspberry Pi

Convert your dumb garage opener to a smart one using Raspberry Pi & Home Assistant

My new home had two garage doors with wall-mounted switches. I wanted a solution that is accessible from my smartphone, secure, reliable, and cheap. I looked around on Amazon and other online storefronts . There's products like Nexx , with costs you about $75 / door, and there are products like MyQ, which in addition to the cost of the hardware, forces you to pay a monthly subscription. Above all, I wasn't comfortable with the security of any of these solutions since giving out control of my garage doors is pretty much the same as giving out the house keys.

After researching online, I decided that the best way to use a raspberry pi + relay is to control the garage opener. The garage wall switch is an open-close switch, and all you need to activate the garage door is to emulate the open-close behavior using a relay.

The next challenge is how the user communicates with the Pi (GaragePi) and the user interface. The answer was quite obvious since I already use Home Assistant. If you are into home automation, you should check out Home Assistant — I have been using it for more than two years, and I love it! If you want to get started with Home Assistant, check out this link

So far, we have a Garage Door, Relay, Raspberry pi, and Home Assistant; the question now is how does the Raspberry Pi communicate with the home assistant? Fortunately, there's MQTT . MQTT is a lightweight Message Queuing Protocol designed for IoT applications. Home Assistant has a built-in MQTT broker using Mosquitto, which is convenient. To install the broker, go to the Supervisor tab, click on the Add-ons tab and select MQTT. You can set up the MQTT with SSL and or username/password, which the clients will connect.

GaragePi talk to Home Assistant using MQTT 

Pi

Raspberry Pi comes in many forms; since this is a lightweight application, I choose a Raspberry Pi Zero W instead of a regular Pi. I also select Pi Zero against Node MCU (ESP4266), given that I was not concerned about power consumption since there was a socket available next to the garage opener. I also liked the convenience of running Linux as opposed to a limited Microcontroller environment. In addition, Pi Zero W offers both 2.4/5 GHz WiFi connection support, and ESP 4266 only supports 2.4 GHz. Instead of writing custom code to expose the GPIO ports, I used a library to expose GPIO ports through a configuration file. Using a configuration file gave me the flexibility to extend the solution quickly to other use cases. As a side note, If you want an ESP-based garage door opener using Shelly switches check out Rob's article on TheHookUp.

Relay

The wall switch on the garage is an open-close switch, and I planned to mimic that behavior using a relay. I used a four channel relay module ( 2 for current use and two for future expansion. The relay gets attached to the garage opener in parallel to the wall switch connection. The relay you use is optically isolated and can be triggered by Raspberry Pi GPIO.

Raspberry Pi Zero W wired to Relay . 

Open Close Sensor

Magnetic Reed Sensor on the door to detect if the Garage is open or closed

Now we need a sensor to detect if the door is closed or open. Using a different state detector had three advantages 1) I do not have to track the state of the switch 2) I can continue to use the wall switch 3) if the switch fails or the garage does not open/close, I would know - this is especially important if you have to open the garage when you are away.

Home Assistant

Home assistant configuration is pretty straightforward—Home Assistant support native MQTT integration. Even if you do not use Home Assistant- most of the DIY home automation platforms support MQTT.
With that high-level context out of the way , the following are the steps to build a simple MQTT-controlled relay and sensor using the Pi.

Step-1

Install Raspberry Pi OS Lite from the raspberrypi.org

Step-2

Enable SSH Login, mount the image you created from Step-1, and run the following commands (If you have installed the lite version- this is the only way for you to connect to the pi)

cd /Volumes/boot
touch ssh
Create an ssh file to enable SSH to the Pi

Step-3

Configure Wifi Connectivity

cd Volumes/boot
vi wpa_supplicant.conf
Create/Edit Wifi Config file

Update the wpa_supplicant.conf with bellow , change the WiFi network name and password to yours .

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=US

network={
    ssid="YourWifiNetworkName"
    scan_ssid=1
    psk="yourpassword"
    key_mgmt=WPA-PSK
}
wpa_supplicant.conf

At this point , your pi should be able to connect to the internet and you should be able to login to it with the default userid password (userid: pi password:raspberry). Change the default password.

Step-4

For controlling the Pi with MQTT, we are going to use a python library called pi-mqtt-gpio. Github - https://github.com/flyte/pi-mqtt-gpio . This library exposes Raspberry pi GPIO pins as switches that MQTT can control. Before we install flyte, we want to ensure that the pi has python and pyenv setup. Run the commands below to install

sudo apt-get update -y
sudo reboot
sudo apt-get dist-upgrade
sudo apt-get install supervisor
sudo apt-get install python-pip
sudo pip install --upgrade virtualenv
cd /home/pi
virtualenv ve
. ve/bin/activate
pip install pi-mqtt-gpio
pip install RPi.GPIO

Now ,we need to configure the pi-mqtt-gpio app by modifying the pi-mqtt-gpio.yml . Below is my configuration. You, will have to replace your MQTT Broker IP address and Port along with the user-id/password .
I used my GPIO pin #5 and #6 as output to drive the relay and pin #22, and #27 as inputs for the Reed switches.

mqtt:
   host: mqtt_broker_ip
   port: mqtt_broker_port
   user: "mqtt_broker_password"
   password: "mqtt_broker_password"
   topic_prefix: home/garage
   status_topic: status
   status_payload_running: online
   status_payload_stopped: offline
   status_payload_dead: dead

gpio_modules:
  - name: raspberrypi
    module: raspberrypi

digital_outputs:
  - name: switch5
    module: raspberrypi
    pin: 5 #GPIO 
    on_payload: "ON"
    off_payload: "OFF"
    inverted: true
    initial: high
  - name: switch6
    module: raspberrypi
    pin: 6 #GPIO 
    on_payload: "ON"
    off_payload: "OFF"
    inverted: true
    initial: high
 digital_inputs:
  - name: sensor22
    module: raspberrypi
    pin: 22 # GPIO 
    on_payload: "ON"
    off_payload: "OFF"
    pullup: yes
    pulldown: no
  - name: sensor27
    module: raspberrypi
    pin: 27 # GPIO 
    on_payload: "ON"
    off_payload: "OFF"
    pullup: yes
    pulldown: no

Step-5

To setup the pi-mqtt-gpio process as a daemon, we need to create a supervisor config at /etc/supervisor/conf.d/pi-mqtt-gpio.conf

[program:pi_mqtt_gpio]
command = /home/pi/ve/bin/python -m pi_mqtt_gpio.server pi-mqtt-gpio.yml
directory = /home/pi
redirect_stderr = true
stdout_logfile = /var/log/pi-mqtt-gpio.log
pi-mqtt-gpio.conf 

Update the Supervisor

sudo supervisorctl update
sudo supervisorctl status
Update Supervisor

Step-6

Update default boot up PIN levels on Pi

To ensure that the Raspberry Pi starts up with the right levels on its pin , we need to add the following to the boot

# Custom Setting for GPIO on startup
# Set GPIO4 and 5 to be an output set to 1
gpio=5,6=op,dh

At this point , you have fully functioning Raspberry Pi controlled relay that can be activated through MQTT. You can test the relay using any MQTT client

Step - 7

Setup Home Assistant. You need to configure two switches for two garage doors and two sensors for each door. If you have only one garage door, you need to modify the bellow configuration. If you have more than two switches or sensors, you can extend this configuration as well. The relay we used can work as a low voltage and high voltage (mains) relay. Before you use the relay for other applications, check the current draw to ensure that the relays that you use can support it.

#MQTT Switches 
#Default payload types are used 
switch:  
  - platform: mqtt    
    state_topic: "home/garage/output/switch5"
    command_topic: "home/garage/output/switch5/set_on_ms"    
    availability_topic: "home/garage/status"
    name: "Garage Door Large"
    state_on: "ON"
    state_off: "OFF"
    payload_on: 120
    payload_off: OFF
    optimistic: false
    qos: 0
    retain: false 
  - platform: mqtt    
    state_topic: "home/garage/output/switch6"
    command_topic: "home/garage/output/switch6/set_on_ms"    
    availability_topic: "home/garage/status"
    name: "Garage Door Small"
    state_on: "ON"
    state_off: "OFF"
    payload_on: 120
    payload_off: OFF
    optimistic: false
    qos: 0
    retain: false
configuration.yaml
binary_sensor:
  - platform: mqtt
    name: "Garage Door Small"
    state_topic: "home/garage/input/sensor22"
    payload_on: "ON"
    payload_off: "OFF"
    availability_topic: "home/garage/status"
    payload_available: "online"
    payload_not_available: "offline"
    qos: 0
    device_class: garage_door
    force_update: true
  - platform: mqtt
    name: "Garage Door Large"
    state_topic: "home/garage/input/sensor27"
    payload_on: "ON"
    payload_off: "OFF"
    availability_topic: "home/garage/status"
    payload_available: "online"
    payload_not_available: "offline"
    qos: 0
    device_class: garage_door
    force_update: true
configuration.yaml

Step-8

You have successfully converted your dumb garage opener to a smart one! Here's my Home Assistant mobile app UI. The top two icons show the status, and the big icons are buttons.