This project aims to design and implement a smart garage door opener system that operates reliably and securely using local control. The solution is built on an ESP32 DevKitC microcontroller running ESPHome firmware, with multiple sensors to determine the door state, safety mechanisms to prevent accidental closures, and smart integration with Home Assistant and Sonos for automation and feedback.
Key Goals
Enable remote and automated control of a garage door.
Ensure accurate door state tracking using multiple sensors.
Provide clear pre-close alerts for occupant safety.
Operate independently of the cloud with local automation.
Seamlessly integrate with Home Assistant and Sonos.
2. Diagnostics
Purpose
Diagnostics help ensure the device is operating reliably and is correctly integrated with Home Assistant. This includes monitoring uptime, firmware version, device identity, and the ability to remotely restart the ESP32 if needed.
Diagnostic Entities
Entity Name
Description
sensor.garage_door_uptime_sensor
Tracks how long the device has been running
text_sensor.garage_door_esphome_version
Shows the version of ESPHome firmware
button.garage_door_restart_button
Allows manual restart of the ESP32 remotely
sensor.garage_door_wifi_signal
Wi-Fi signal strength in dBm
sensor.garage_door_wifi_rssi
Relative Wi-Fi signal quality (RSSI)
sensor.garage_door_free_heap
Current available heap memory on the ESP32
sensor.garage_door_restart_reason
Reason for the last microcontroller reboot
Best Practices
Add these entities to a dedicated “Diagnostics” dashboard tab in Home Assistant.
Use uptime to monitor stability and catch unexpected reboots.
Monitor Wi-Fi signal strength (optional) to catch connectivity issues.
Use the restart button to recover the device if it becomes unresponsive.
3. Hardware Configuration
Microcontroller
ESP32 DevKitC: Chosen for its dual-core processing, integrated Wi-Fi, and ESPHome compatibility. This board provides sufficient GPIOs and power to manage all the peripherals used.
Components Overview
Component
Function
Notes
Relay Module (BESTEP 3V)
Controls the garage door motor
Simulates a button press
HC-SR04 Ultrasonic
Measures distance to the door
Detects open/closed states
Reed Switch
Detects when door is fully open
Wired backup to ultrasonic
PIR Motion Sensor
Senses movement inside garage
Used for safety/interruption
Piezo Buzzer
Emits warning tone before closure
Configurable beep patterns
LED
Strobes before closing
Synchronized with buzzer
Sonos Speaker
Plays voice messages via HA
Requires Home Assistant setup
Garage Motor Light
Optional light relay control
Not directly controlled yet
GPIO Pin Mapping
This table defines the GPIO pin connections used on the ESP32. Always verify pin compatibility and strapping pin warnings before flashing.
Name
GPIO
Connected Component
door_control_pin
GPIO1
Relay module
wired_sensor_pin
GPIO5
Reed switch
warning_beep_pin
GPIO4
Piezo buzzer
warning_leds_pin
GPIO3
LED
wireless_sensor_trig
GPIO12
HC-SR04 trigger
wireless_sensor_echo
GPIO14
HC-SR04 echo
motion_sensor_pin
GPIO13
PIR motion sensor
status_led
GPIO18
ESP32 onboard/status LED
4. Software Configuration
Platform Details
ESPHome v2025.5.1: Manages sensor input/output, automations, and state tracking.
Home Assistant: Provides dashboard visibility, TTS alerts, and automations using ESPHome entities.
File Structure
####
# GENERAL SETTINGS
# Customize these variables to your preferences and needs
# more: https://esphome.io/guides/configuration-types.html#substitutions
substitutions:
####
# NAME
# By default, the name of the ESPHome device is "garage-door-xxxxxx" where xxxxxx is a unique identifier. The device's
# hostname on your network is also defined by the name, defaulting to "garage-door-xxxxxx.local". Edit this variable to
# customize the name and hostname. Note: only lowercase characters, numbers and hyphen(-) are allowed.
name: garage-door
friendly_name: Garage Door Opener
project_name: parsons.garage-door-esp32
project_version: "0.1.1"
garage_door_cover_name: Garage Door
switch_name: STR output
####
# GARAGE DOOR OPENER MOMENTARY DURATION
# Duration to make the relay contact closure for the garage door opener button circuit.
garage_door_opener_momentary_duration: 300ms
####
# OPEN GARAGE DOOR DISTANCE MARGIN OF ERROR
# The margin of error (+/-) in meters from the value above to consider the garage door in the open position.
open_garage_door_distance_margin_of_error: "0.05"
####
# GARAGE DOOR CLOSE WARNING DURATION
# Duration to blink the warning LED and beep the buzzer before the garage door closes.
garage_door_close_warning_duration: 5s
warning_beep_pulse_time: 100ms
warning_beep_pause_time: 130ms
warning_beep_internal_only: "true"
warning_beep_shared: "false"
sensor_debounce_time: 200ms
range_sensor_polling_time: 2500ms
range_sensor_debounce_time: 3s
blink_on_state: "true"
####
# INTERNAL MAPPINGS
door_control_pin: GPIO1 #TX
wired_sensor_pin: GPIO5 #5
warning_beep_pin: GPIO4 #4
warning_leds_pin: GPIO3 #RX
output_switch_pin: GPIO2 #2
status_led: GPIO18 #18
sda: GPIO6 #CLK
scl: GPIO7 #D0
wireless_sensor_trig_pin: GPIO12 #12
wireless_sensor_echo_pin: GPIO14 #14
status_led_inverted: "false"
esphome:
name: $name
friendly_name: $friendly_name
name_add_mac_suffix: true
min_version: '2024.12.0' # Includes ESP-IDF 5.1
project:
name: $project_name
version: $project_version
platformio_options:
board_build.flash_mode: dio
on_boot:
- priority: 800.0
then:
- lambda: |-
id(device_id).publish_state(get_mac_address());
id(project_version).publish_state(ESPHOME_PROJECT_VERSION);
esp32:
board: esp32dev
framework:
type: esp-idf
version: recommended
sdkconfig_options:
CONFIG_LWIP_MAX_SOCKETS: "16"
text_sensor:
- platform: template
name: Device ID
id: device_id
entity_category: diagnostic
update_interval: never
- platform: version
name: ESPHome Version
hide_timestamp: true
- platform: template
name: Project version
id: project_version
entity_category: diagnostic
update_interval: never
sensor:
- platform: uptime
name: Uptime
id: uptime_sensor
entity_category: diagnostic
button:
- platform: restart
name: Restart
id: restart_button
entity_category: config
####
# OTA UPDATES
# Enables over-the-air updates
# more: https://esphome.io/components/ota.html
ota:
- platform: esphome
id: konnected_ota
password: "0d332334936534534323b166bef31f5634"
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "SMSPSXteLehs/8CJaMPXW9dLTTexYNRUfySD0CnNIPQ="
wifi:
manual_ip:
static_ip: 192.168.4.107
gateway: 192.168.4.1
subnet: 255.255.255.0
ssid: !secret wifi_ssid
password: !secret wifi_password
##Install package components
packages:
garage_door_control: !include /config/packages/garage_door/garage_door_control.yaml
garage_door_wired_sensor: !include /config/packages/garage_door/garage_door_wired_sensor.yaml
garage_door_wireless_sensor: !include /config/packages/garage_door/garage_door_wireless_sensor.yaml
garage_door_motion_sensor: !include /config/packages/garage_door/garage_door_motion_sensor.yaml
garage_door_warning_alerts: !include /config/packages/garage_door/garage_door_warning_alerts.yaml
garage_door_cover_template: !include /config/packages/garage_door/garage_door_cover_template.yaml
garage_door_status_led: !include /config/packages/garage_door/garage_door_status_led.yaml
garage_door_diagnostics: !include /config/packages/garage_door/garage_door_diagnostics.yaml
garage_door_door_state_sensor: !include /config/packages/garage_door/garage_door_state_sensor.yaml
Central configuration resides in garage_door.yaml
All logic is modularized under /config/packages/garage_door/
Software Modules and Their Roles
File Name
Description
garage_door_control.yaml
Defines GPIO relay switch and template button for triggering door
garage_door_wired_sensor.yaml
Reed switch input, filtered for debounce
garage_door_wireless_sensor.yaml
Ultrasonic sensor to measure door distance
garage_door_state_sensor.yaml
Template logic to infer door open/closed state
garage_door_warning_alerts.yaml
Buzzer and LED outputs with alert patterns
garage_door_motion_sensor.yaml
Motion detection using PIR sensor
garage_door_cover_template.yaml
Main cover entity logic for open/close/toggle/stop