Make Your Garage Door Smart with ESP32 and Home Assistant
I’ve always had this nagging anxiety about whether I remembered to close the garage door. After driving halfway to work only to turn back and check (more than once, I’ll admit), I decided it was time for a solution. I wanted something more reliable than my memory and more integrated than a basic standalone smart opener.
In this tutorial, I’ll show you how I used a cheap ESP32 board and some reed switches—the same type of sensor in door/window alarms—to create a smart garage door monitor that integrates seamlessly with Home Assistant. The best part? This solution gives you both status monitoring and remote control, all without modifying your garage door opener’s internal wiring.
What You’ll Need
Before we dive in, let’s gather our tools and components. I opted for components that are widely available and budget-friendly.
- ESP32 Development Board: Any variant will work. I used an ESP32 DevKit C. (Amazon | AliExpress)
- Magnetic Reed Switches (x2): You need two to detect “open” and “closed” states independently. (Amazon | AliExpress)
- 10kΩ Resistors (x2): For pull-down resistors on the GPIO pins.
- Jumper Wires: A mix of male-to-male and male-to-female is useful.
- Breadboard (optional): For prototyping before final soldering.
- Micro-USB Cable & Power Adapter: To power the ESP32.
- Small Breadboard or Perfboard: For a more permanent installation.
- Electrical Tape & Wire: For safe, clean wiring.
Tools: A soldering iron, wire strippers, and a multimeter will be helpful.
How It Works: The Simple Plan
The logic is straightforward. We’ll attach two reed switches to the garage door frame: one at the top (Open position) and one at the bottom (Closed position). A magnet will be attached to the garage door itself. As the door moves, the magnet will trigger the corresponding reed switch.
The ESP32 reads the state of these switches and reports them to Home Assistant via Wi-Fi using ESPHome. We can then use this state to create automations, like sending a notification if the door has been open for more than 10 minutes, or adding a toggle button to our dashboard.
Step 1: Assembling the Hardware
Let’s get our hands dirty. Safety first: ensure your garage door is disconnected from power while you’re working on the installation.
Wiring the Reed Switches
Reed switches are simple; they act as a switch that closes (completes the circuit) when a magnet is nearby. We’ll connect them to the ESP32 using a pull-down resistor configuration to ensure a stable, clean signal.
Here’s the wiring diagram:
- Connect one pin of the first reed switch (for “Open”) to the 3.3V pin on the ESP32.
- Connect the other pin to GPIO 4 (D4) on the ESP32.
- Connect a 10kΩ resistor between that same GPIO 4 pin and the GND pin. This is our pull-down resistor.
- Repeat this exact setup for the second reed switch (for “Closed”), but connect its signal pin to GPIO 5 (D5).

This setup means that when a magnet is near a reed switch, its GPIO pin will read HIGH (3.3V). When the magnet is away, the pull-down resistor will pull the pin to LOW (0V).
Installing the Sensors on the Garage Door
This is the part that requires a bit of creativity, as every garage door is different.
- Position the Magnet: Attach a strong magnet (often comes with the reed switch) to the top of your garage door. I used strong double-sided tape.
- Position the Reed Switches: Attach the “Open” reed switch to the door frame so that the magnet is directly adjacent to it when the door is fully open. Attach the “Closed” reed switch to the frame so the magnet is adjacent when the door is fully closed.
- Test Before Finalizing: Use your multimeter in continuity mode or temporarily hook up the ESP32 to verify that each switch closes reliably when the door is in the correct position. Move the door slowly and watch for the exact trigger points. A little adjustment here saves a lot of frustration later!
I mounted my ESP32 and breadboard in a small plastic project box and stuck it to the wall near the ceiling to keep it out of the way.
Step 2: Flashing the ESP32 with ESPHome
ESPHome is a fantastic system that lets you configure ESP boards with a simple YAML file, and it integrates perfectly with Home Assistant. If you haven’t set it up yet, follow the ESPHome Getting Started Guide.
Creating the ESPHome Configuration
Create a new device in ESPHome and use the following YAML configuration as your starting point. Replace your_wifi_ssid and your_wifi_password with your own details.
esphome:
name: smart-garage-door
friendly_name: Smart Garage Door
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging and a safe "fallback" hotspot in case of Wi-Fi issues
logger:
api:
ota:
wifi:
ssid: "your_wifi_ssid"
password: "your_wifi_password"
# Optional: Add a static IP for more reliability
# manual_ip:
# static_ip: 192.168.1.200
# gateway: 192.168.1.1
# subnet: 255.255.255.0
captive_portal:
# The core of our project: the binary sensors for the reed switches
binary_sensor:
- platform: gpio
pin: GPIO4
name: "Garage Door Open Sensor"
id: open_sensor
filters:
- invert: # Invert because the switch is normally open
- delayed_on: 50ms # Debouncing to prevent false triggers
- platform: gpio
pin: GPIO5
name: "Garage Door Closed Sensor"
id: closed_sensor
filters:
- invert:
- delayed_on: 50ms
# A template sensor to combine the two switches into a single door state
sensor:
- platform: template
name: "Garage Door State"
id: door_state
lambda: |-
if (id(open_sensor).state) {
return "open";
} else if (id(closed_sensor).state) {
return "closed";
} else {
return "unknown";
}
# A status LED to show the device's connection state
status_led:
pin: GPIO2
This configuration does a few key things:
- It defines two binary sensors for the reed switches.
- It uses
filtersto “invert” the logic (since our switches are “normally open”) and adds a 50ms debounce delay to ignore electrical noise. - It creates a template sensor that outputs a simple string—“open”, “closed”, or “unknown”—based on which reed switch is active.
Flashing the Device
With the YAML file saved, connect your ESP32 to your computer via USB and run:
esphome run smart-garage-door.yaml
ESPHome will compile the firmware and guide you through flashing it. Once done, the device should reboot, connect to your Wi-Fi, and be ready for the next step.
Step 3: Integrating with Home Assistant
If you have the ESPHome integration installed in Home Assistant (and you should!), the smart-garage-door device should appear automatically. You might get a notification; if not, just go to Settings > Devices & Services and it should be listed under ESPHome.
The three sensors we defined (Garage Door Open Sensor, Garage Door Closed Sensor, and Garage Door State) will be available to use immediately.
Creating a Lovelace Dashboard Card
Let’s make a nice control panel. I prefer the “Garage Door” card from HACS (Home Assistant Community Store), but a simple button or entity card works too.
Here’s a basic manual card configuration you can add to your dashboard:
type: button
entity: sensor.garage_door_state
name: Garage Door
tap_action:
action: more-info
icon: mdi:garage
hold_action:
action: call-service
service: notify.mobile_app_your_phone
data:
message: "Garage door is currently {{ states('sensor.garage_door_state') }}"
Step 4: Creating Useful Automations
Now for the magic. Here are two automations I found incredibly useful.
Alert Me if the Door is Left Open
This one saved me from a potential raccoon invasion last week.
alias: "Alert: Garage Door Left Open"
description: ""
trigger:
- platform: state
entity_id:
- sensor.garage_door_state
to: "open"
for:
hours: 0
minutes: 10
seconds: 0
condition: []
action:
- service: notify.mobile_app_my_phone
data:
message: "Your garage door has been open for 10 minutes."
title: "Garage Door Alert 🚪"
mode: single
Close the Garage Door at Night
A simple peace-of-mind automation. (Note: This assumes you have a separate smart controller to close the door. This project only handles monitoring).
alias: "Auto-Close Garage Door at Night"
description: ""
trigger:
- platform: time
at: "23:00:00"
condition:
- condition: state
entity_id: sensor.garage_door_state
state: open
action:
- service: switch.turn_off
target:
entity_id: switch.smart_garage_door_opener_switch
mode: single
Troubleshooting and Common Pitfalls
I ran into a few issues during my build; hopefully, this saves you some time.
- Flickering State: This is almost always due to switch “bouncing” or a weak magnet. The
delayed_onfilter in the YAML code is your first line of defense. If it persists, make sure your magnet is strong enough and aligned properly. - ESP32 Won’t Connect to Wi-Fi: The signal in a garage can be weak. Consider adding a Wi-Fi repeater or using an ESP32 board with an external antenna. Setting a
manual_ipin the YAML can also help with reliability. - State Stuck on “unknown”: This means neither reed switch is being triggered. Check your wiring, ensure the ESP32 is getting power, and verify the magnet is passing close enough to one of the switches in each end position.
- Home Assistant Can’t See the Device: Ensure the ESP32 and Home Assistant are on the same subnet/VLAN. Firewall rules can sometimes block the communication ESPHome uses.
Taking It Further
This project is a solid foundation. Here are a few ways I’m thinking of expanding it:
- Add a Door Control: Integrate a smart relay (like a Shelly 1) to physically trigger the garage door button, giving you full open/close control from Home Assistant.
- Battery Backup: Add a small UPS to keep the system running during a power outage.
- Obstruction Sensor: Use a time-of-flight (ToF) sensor to detect if something is blocking the door’s path.
- Multiple Doors: The ESP32 has plenty of GPIO pins. You can easily scale this design to monitor two or three doors with the same board.
Frequently Asked Questions (FAQ)
Q: Can I use an ESP8266 (like a Wemos D1 Mini) instead of an ESP32?
A: Absolutely! The process is identical. Just change the esp32: section in the YAML to esp8266: and update the board type (e.g., board: d1_mini). The GPIO pins will be different, so wire accordingly.
Q: My garage door has intermediate positions (like partially open). Will this work? A: This specific setup will report “unknown” for any position that isn’t fully open or fully closed. To detect intermediate states, you’d need a different sensor, like a rotary encoder attached to the door’s pulley system.
Q: Is this safe? It won’t damage my garage door opener? A: Yes, it’s perfectly safe. We are only monitoring the door’s state using passive, low-voltage sensors. We are not interfacing with the opener’s motor control circuitry at all.
Q: Can I use this without Home Assistant? A: While this guide is designed for Home Assistant, the ESP32 can be programmed with the Arduino IDE to send data to other platforms like MQTT brokers or Blynk. The core hardware and sensor logic would remain the same.
Transforming my dumb garage door into a smart, connected device was incredibly satisfying. It eliminated my anxiety and added a genuinely useful layer of automation to my home. If you’re looking for other ways to leverage the ESP32, check out my guide on monitoring home temperature with ESP32 and ESPHome. Happy building