Self-taught YAML glue for things that should happen without opening an app. ESP32 beacons, Bermuda BLE tracking, template sensors, and enough safety gates that the garage does not open for a passing cyclist (or me).

Nothing fancy, just automations that (mostly) survived contact with real life.

Garage door (bike arrival)

BLE iBeacons on the bikes, ESP32 listeners in the garage, Bermuda for presence. Pull in, door opens. Everyone leaves, door closes. False opens are the enemy.

Sync allow toggles with auto arm. When auto arm is on, the separate allow-open and allow-close toggles flip on too. Disarm and both shut off. Keeps the dashboard honest so you are never half-armed.

Open on bike arrival. Fires when a bike has been near the garage long enough (configurable dwell). Requires auto arm, allow-open, no manual override, door closed, and an idle cooldown timer. Opens the door and starts cooldown so it cannot retrigger immediately.

Close after bikes gone. Waits until at least one bike tracker reads not home for a configurable stretch. Same safety checks as open, but the door must already be open. Closes and cooldowns.

Manual override exists for when the automation should stay out of the way. RSSI threshold, dwell seconds, gone minutes, and cooldown are tunable from helpers without editing YAML.

Comfort (season and setpoints)

Indoor comfort index sensors upstairs and downstairs, outdoor weather feeds, and a thermostat in auto mode. The idea is to stop babysitting setpoints when the weather shifts.

Infer season (7-day outdoor average). Every six hours, and when rolling outdoor temperature and dew point stats change, picks winter, shoulder, or summer. Uses hysteresis and a minimum hold period so it does not flap on a warm week in January. Extreme cold or heat can force a switch. Respects a manual season lock.

Apply thermostat setpoints (season + CLI). Every five minutes, and when related inputs change, pushes heat and cool targets to the thermostat if auto-setpoints is enabled. Base targets come from the current season. Comfort load index trim nudges cooler when the house feels muggy. Upstairs gets an offset because it runs warm. Daytime solar and evening relax offsets shift targets with the sun. Enforces a minimum deadband between heat and cool setpoints.

Dryer kiosk (laundry room)

ESP32-C3 with a small TFT and rotary encoder mounted near the dryer. Pick a cycle mode and who loaded it without opening the phone app. Home Assistant helpers hold the selections; the kiosk reads and writes them over ESPHome.

Mode and user selection. Rotate to scroll, short press to lock or unlock, long press to switch focus between cycle mode and user. When locked, the encoder ignores input so nobody changes a run mid-cycle.

Running state and auto-lock. When the drum activity sensor reports motion (or a demo helper is toggled on), the display shows a running animation and the kiosk locks itself if someone left it open.

Marquee messages. Home Assistant can push scrolling text to the screen for announcements. Duration is configurable; the display stays awake while a message plays.

Screen power saving. Idle timers dim the backlight, then turn the panel off. Any touch or HA update wakes it back up. Dim and off delays are tunable from helpers.

Light Studio (side project)

A Go daemon that sits between Home Assistant and lights the stock integrations handle awkwardly: MagicHome WiFi LED controllers over TCP and Zigbee bulbs through Zigbee2MQTT. MQTT commands drive fades with easing curves; a small local web UI handles manual control and device import from HA.

It works. It was vibe coded more than engineered, and nothing in the house depends on it day to day. Mostly a cool experiment in smooth fades and bridging oddball hardware, kept around because it was fun to build.

← All projects