har.sh

Some things that I've done.

Garage Door Monitor

I've left the garage door open at least a couple of times. My wife has done it at least once. Surely something can be done to alert us if this happens again! For this project I used an ESP32 to monitor the state of the garage door, and a simple server-side Rust process to generate alerts if the door is left open for too long.

Hardware

As the ESP32's built-in Hall Effect sensor can detect a magnetic field, the hardware for this project consisted of simply:
► An ESP32-PICO-KIT (but any ESP32 would do)
► A USB charger and cable
► A magnet

By using the built-in sensor, there is no wiring required, apart from plugging in a USB charger to provide power.

Reading from the Hall Effect sensor

Reading from the Hall Effect sensor is very easy. First the ADC1 module needs to be configured to reading 12 bit values, as the Hall Effect sensor readings to not cover the full range of the input. Then we can read from the sensor simply by calling hall_sensor_read().

adc1_config_width(ADC_WIDTH_BIT_12);
...
int value = hall_sensor_read();

At first glance the Hall Effect sensor on the ESP32 acts a lot like a random number generator — the values it returns are super noisy! A simple way to filter out the noise is to perform lots of readings (200) and average them.

Is the door open or closed?

This logic is implemented on the ESP32. It could easily be implemented on the server-side instead. I read 200 samples from the Hall Effect sensor every 5 seconds, and then decide whether the door is open or closed.

My initial idea to define fixed thresholds for door open and door closed didn't work reliably. The values returned by the sensor seemed to drift over time, possibly due to temperature. Instead I maintain an average of recent readings from when the door is considered closed, and define a difference threshold relative to this average. Graph showing threshold changing over time

ESP32 to server messaging

To keep things simple, I use a fixed message format over UDP. The message is only sent when we determine that the door is open, and for 30 seconds after the door closes. The message contains three fields:
► An indication of whether the door is open or closed
► Number of seconds since the last state change
► The most recent sensor reading (for debugging).

The IP addresses of the ESP32 and the server are hardcoded, as is the port number for the UDP messages. UDP is a connectionless protocol, so this simplifies the the implementation on both sides.

Server-side processing

On the server side I use syslog to log when the door changes state, but otherwise the alerting behaviour is config-driven. I use CallMeBot and their Signal API to send messages when the door has been left open for too long, and then again when the door is closed.

Configuration defines:
► How long the door needs to have been open before sending an alert,
► The phone number of the recipient,
► The recipient's CallMeBot API key,
► The message text for when the door is open, and for when it is closed.
Signal message indicating garage door is open

Monitoring

monit is used to monitor the state of the ESP32 (via ping), and that the server process is running and listening on the expected UDP port. I'll receive an email if either side fails, and the server process can be restarted automatically.

Not long after the initial deployment this monitoring identified that if the ESP32 lost its wifi connection, it never came back. As this is a rare occurrence, I fixed it in the simplest possible way by rebooting the ESP32 on disconnection.

The finished product

The final packaging for the ESP32 is somewhat rough. The plastic zip-lock bag keeps the dust off, while the elastic bands hold it in position.

ESP32 monitoring garage door status

ESP32 monitoring garage door status

Source code for this project can be found on Bitbucket.