This was my first project I did for any automation.
Indeed pressing the button does short two wires. So all you really need is a solid state relay and something to flip the relay when it receives a command and back again.
You can wire the relay to the button on the wall or follow the wire and connect the relay directly to the opener. I have two openers so I got a dual relay board. How it’s wires will vary so be sure to read up on the relay you get. In general on one side you’ll have power to the relay (3.5v or 5v), ground, and control pins and on the other side you’ll have the wires that are connected to the garage door opener/button.
The something to control it can be a microcontroller (e.g. ESP8266, Arduino, etc.) or an SBC (e.g. RPi 0W). With an ESP8266 you could use Tasmota, ESPHome or ESPEasy as the firmware and then it’s just a simple matter of configuration.
You could use openHAB for this but that’s going to require a beefier RPi in the garage. I use an RPi and wrote GitHub - rkoshak/sensorReporter: A python based service that receives sensor inputs and publishes them over REST (should work with any API but mainly tested with openHAB) or MQTT. It can also receive commands and perform an action (e.g. set a GPIO pin to HIGH). It currently supports Bluetooth, GPIO on Raspberry Pi, Amazon Dash buttons, command line scripts, and Roku IP address discovery. to do this instead, though plan on moving to an ESP eventually. I also wired up some reed sensors to the doors and for awhile I had a RaspiCam served up from it (hence the RPi).
My config is:
Logging:
File: /tmp/sensorReporter.log
MaxSize: 67108864
NumFiles: 10
Syslog: NO
Level: DEBUG
Connection1:
Class: mqtt.mqtt_conn.MqttConnection
Name: MQTT
Client: cerberos
User: rich
Password: hes10d27
Host: argus.koshak.lan
Port: 1883
TLS: NO
Keepalive: 60
RootTopic: sensor_reporter/cerberos
Level: DEBUG
SensorHeartbeat:
Class: heartbeat.heartbeat.Heartbeat
Connections:
MQTT:
FormatNumber:
StateDest: heartbeat/number
FormatString:
StateDest: heartbeat/string
Poll: 60
Level: DEBUG
SensorLargeGarageDoor:
Class: gpio.rpi_gpio.RpiGpioSensor
Connections:
MQTT:
Switch:
StateDest: garagedoor1/state
Pin: 7
PUD: DOWN
Btn_Pressed_State: HIGH
EventDetection: BOTH
Level: DEBUG
SensorSmallGarageDoor:
Class: gpio.rpi_gpio.RpiGpioSensor
Connections:
MQTT:
Switch:
StateDest: garagedoor2/state
Pin: 8
PUD: DOWN
Btn_Pressed_State: HIGH
EventDetection: BOTH
Level: DEBUG
ActuatorLarageGarageDoor:
Class: gpio.rpi_gpio.RpiGpioActuator
Connections:
MQTT:
CommandSrc: garagedoor1/cmd
Pin: 17
InitialState: ON
SimulateButton: True
Level: DEBUG
ActuatorSmallGarageDoor:
Class: gpio.rpi_gpio.RpiGpioActuator
Connections:
MQTT:
CommandSrc: garagedoor2/cmd
Pin: 22
InitialState: ON
SimulateButton: True
Level: DEBUG
I use MQTT above but the script does support talking to OH directly. It even supports Homie so it can be automatically be discovered.
On the OH side I have:
Thing
UID: mqtt:topic:mosquitto:cerberos_sensor_reporter
label: cerberos sensor_reporter
thingTypeUID: mqtt:topic
configuration:
payloadNotAvailable: OFFLINE
availabilityTopic: sensor_reporter/cerberos/status
payloadAvailable: ONLINE
bridgeUID: mqtt:broker:broker
location: Garage
channels:
- id: garagedoor1
channelTypeUID: mqtt:contact
label: Large garage door
description: Large garage door open status
configuration:
stateTopic: sensor_reporter/cerberos/garagedoor1/state
off: CLOSED
on: OPEN
- id: garagedoor2
channelTypeUID: mqtt:contact
label: Small garage door
description: Small garage door open status
configuration:
stateTopic: sensor_reporter/cerberos/garagedoor2/state
off: CLOSED
on: OPEN
- id: garagedoor1_opener
channelTypeUID: mqtt:switch
label: Large garage door opener
description: ""
configuration:
commandTopic: sensor_reporter/cerberos/garagedoor1/cmd
off: OFF
on: ON
- id: garagedoor2_opener
channelTypeUID: mqtt:switch
label: Small garage door opener
description: Small garage door opener controller
configuration:
commandTopic: sensor_reporter/cerberos/garagedoor2/cmd
off: OFF
on: ON
- id: online
channelTypeUID: mqtt:switch
label: Online status
description: Indicates online status of this sensor_reporter
configuration:
stateTopic: sensor_reporter/cerberos/status
off: OFFLINE
on: ONLINE
The Items are pretty straight forward.
The widget I use is:
uid: garage_widget
tags:
- card
- garage
props:
parameters: []
parameterGroups: []
timestamp: Sep 20, 2023, 10:58:06 AM
component: f7-card
config:
title: '=(items.GarageCamera_Status.state === "ON") ? "Garage Doors" : "Garage Doors: Camera Offline!"'
slots:
default:
- component: f7-row
config:
class:
- justify-content-center
slots:
default:
- component: f7-col
config:
width: auto
slots:
default:
- component: oh-image-card
config:
refreshInterval: 3000
style:
height: auto
width: 100%
url: '=(items.GarageCamera_Status.state === "ON") ? items.GarageWyzeCamera_ImageURL.state : "/static/garage.jpg"'
- component: f7-row
config:
class:
- justify-content-left
slots:
default:
- component: f7-col
slots:
default:
- component: oh-label-card
config:
action: command
actionCommand: ON
actionItem: Small_Garagedoor_Opener
footer: Small Garage Door Opener
icon: '=(items.Small_Garagedoor_Sensor.state == "CLOSED") ? "f7:house" : "f7:house_fill"'
iconColor: '=(items.Small_Garagedoor_Sensor.state == "CLOSED") ? "green" : "orange"'
item: Small_Garagedoor_Sensor
label: '=(items.Small_Garagedoor_Sensor.state == "OPEN") ? "close" : "open"'
- component: f7-col
slots:
default:
- component: oh-label-card
config:
action: command
actionCommand: ON
actionItem: Large_Garagedoor_Opener
footer: Large Garage Door Opener
icon: '=(items.Large_Garagedoor_Sensor.state == "CLOSED") ? "f7:house" : "f7:house_fill"'
iconColor: '=(items.Large_Garagedoor_Sensor.state == "CLOSED") ? "green" : "orange"'
label: '=(items.Large_Garagedoor_Sensor.state == "OPEN") ? "close" : "open"'
The camera comes from the IP Camera binding.