Project: a home security door/window sensor with alerts
In short: This project uses a magnetic reed switch and an ESP32 to report when a door or window opens. The board sleeps almost all the time, waking on the switch or on an hourly timer to send a heartbeat. The security lesson is that a sensor which goes quiet is as important as one that reports an opening.
What you will build and what you need
You will build a contact sensor that sends open and closed events to your MQTT broker, plus an hourly heartbeat with the battery voltage. A home automation system such as Home Assistant or Node-RED turns events into phone notifications. This is a learning project; it is not a replacement for a certified, professionally monitored alarm.
| Part | Notes |
|---|---|
| ESP32 board with low sleep current | Boards without a power LED and USB chip always on are best for batteries |
| Reed switch and magnet | Surface-mount door contacts are ready-made and tidy |
| 100 kilohm resistor | External pull-up so the input is stable in deep sleep |
| Battery pack | A lithium cell with a suitable regulator, or 3 x AA with a low-dropout regulator |
| Two resistors for a voltage divider | To measure battery voltage on an ADC pin |
| Small enclosure | Keeps out dust and curious fingers |
Design
Fit the reed switch to the frame and the magnet to the door. Wire the switch between an RTC-capable GPIO (for example GPIO 33) and ground, with the pull-up resistor to 3.3 V. With the door closed, the magnet closes the switch and the pin reads low. When the door opens, the switch opens and the pin goes high, which wakes the ESP32 through wake_on_ext0. A timer wake every hour sends a heartbeat so the system knows the sensor is alive.
Build steps
- Prototype on a breadboard and confirm the pin value changes as you move the magnet.
- Reuse the Wi-Fi, TLS and
secrets.pyapproach from the temperature monitor. - Upload the code below, then test open, close and heartbeat messages with
mosquitto_sub. - Create an automation: notify when
openarrives while the house is in "away" mode, and notify when no heartbeat arrives for 90 minutes. - Measure sleep current with a multimeter and estimate battery life before final installation.
import machine, esp32, time
from machine import Pin, ADC
from net import publish # your Wi-Fi + MQTT/TLS helper from the earlier project
door = Pin(33, Pin.IN) # external pull-up fitted
batt = ADC(Pin(35)); batt.atten(ADC.ATTN_11DB)
BASE = "home/hall/door01/"
def battery_volts():
return round(batt.read_uv() * 2 / 1_000_000, 2) # divider halves the voltage
if machine.wake_reason() == machine.EXT0_WAKE:
publish(BASE + "state", "open", retain=True)
while door.value() == 1: # wait for the door to close again
time.sleep(1)
publish(BASE + "state", "closed", retain=True)
else:
state = "open" if door.value() else "closed"
publish(BASE + "heartbeat", str(battery_volts()))
publish(BASE + "state", state, retain=True)
esp32.wake_on_ext0(pin=door, level=esp32.WAKEUP_ANY_HIGH)
machine.deepsleep(3_600_000) # wake again in one hour for a heartbeat
Connecting to Wi-Fi from deep sleep takes a few seconds, so expect a short delay before the alert. A retained state message lets a dashboard show the current position immediately.
Threats and security checklist
- Supervise the sensor: alert on a missing heartbeat and on low battery, not only on "open".
- Encrypt and authenticate with TLS and per-device MQTT credentials so nobody on the network can publish a fake "closed".
- Restrict topics: the sensor can write only to
home/hall/door01/#. - Tamper resistance: hide wiring, and consider a second switch on the enclosure lid.
- Avoid single points of failure: keep the broker and router on a small UPS.
- Protect privacy: door events reveal when you are home; keep them local rather than in a public cloud if you can.
Practice
Why does the design send an hourly heartbeat?
Why is an external pull-up resistor used instead of relying only on the internal one?
How do you stop someone on your network from publishing a fake 'closed' message?
Key takeaways
- A reed switch plus an ESP32 in deep sleep makes a long-life contact sensor.
- Wake on the switch for events and on a timer for heartbeats.
- Alert on missing heartbeats and low battery, not just on openings.
- Use TLS, unique credentials and topic ACLs to stop spoofed messages.
- A DIY sensor is a learning tool, not a certified alarm system.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.