The Boring Automations That Pay for the Whole Setup
The unglamorous automations that keep a house safe: a freezer temperature guard, a gas fireplace safety cutoff, leak alerts, and a nightly lock-and-check.
On this page
The Echo Show on the wall and the voice assistant that reads recipes are the parts of my setup people ask about. None of that is why the server stays on. The reason is a handful of small, ugly automations that do nothing for months and then, one evening, do the only thing that matters.
Here’s a few of my most important automations and why I run them. Nearly every one exists because something went wrong first. I didn’t design a safety system; I got burned and wrote a rule after each time.
The freezer that was open for five days
We came home with our newborn son to a garage freezer that had been standing open the entire time we were gone. Five days. Everything in it was gone, and the smell had gotten into the garage. That was the first guardian automation I wrote, and it’s still the one I’d keep if I could only keep one.
There’s a door contact on that freezer, and it does send a “door has been open for 2 minutes” alert. That’s the fast alarm. But a contact sensor only knows whether the magnet is near the reed switch. A door that’s closed enough to satisfy the magnet and not closed enough to seal looks fine to it, and so does a compressor that dies with the door shut. The thing I actually trust is a thermometer sitting inside the freezer.
That thermometer is an Aqara temperature sensor, the same $20 Zigbee puck I have in half the rooms of the house. It runs two rules:
1. Cold Storage Temperature Guard. If the garage freezer reads above 15°F for 10 straight minutes, send one alert with the current temperature: “Garage freezer temperature is 22°F. Check door/power.” The 10-minute hold is there so restocking the freezer on grocery day doesn’t page me.
2. Garage Freezer Temp. If it reads above 20°F for 5 minutes, alert. Then, on a time_pattern trigger every 5 minutes, check whether it’s still above 20°F, and if so, alert again. This one does not stop until the freezer is cold. It is deliberately annoying, because the garage freezer is the appliance nobody walks past, and a single notification at 2 PM on a Tuesday is very easy to swipe away and forget.
That’s the whole design: the door sensor is the fast alarm, the thermometer is the truth, and the truth nags.
One thing worth knowing before you put a Zigbee sensor in a freezer: a coin cell reports a much lower percentage at -7°F than it would on a shelf, because that’s what cold does to lithium cells. The sensor keeps working fine. Just expect the battery number to look scary and read it against what the sensor is actually doing. Mine has held up, but most indoor Zigbee sensors are only rated down to about 14°F, so if you are buying one specifically for this job, read how to add temperature sensors to a fridge and freezer first - a probe sensor that keeps its battery outside the cold is the sturdier build.
The gas fireplace that hit 120°F
Our enclosed porch has a gas fireplace on its own thermostat, completely separate from the house HVAC. One night the thermostat contact stuck closed. The fireplace didn’t know anything was wrong; it just kept going. By the time anyone went out there the porch was somewhere around 120°F.
Gas appliances have their own safety limits, and the fireplace didn’t burn the house down. But “the appliance’s own high-limit switch is the only thing standing between you and a fire” is not a comfortable sentence, so the fireplace now runs through Home Assistant, and the porch has more rules than any other room in the house.
The setup: the fireplace’s call-for-heat circuit goes through a Tuya single-gang Zigbee switch, paired to Zigbee2MQTT (rather than ZHA, for the reasons in this comparison). On top of that switch sits a Home Assistant generic thermostat, climate.porch, which reads the Aqara temperature sensor on the porch and turns the switch on and off to hold a target. From the dashboard it looks like an ordinary thermostat. Under it there are five automations.
Night setback, 9 PM. Set climate.porch to mode off and turn the switch off. Not “lower the target to 55.” The description I left on that automation says it plainly: the heater doesn’t self-regulate, so a lower target alone won’t stop it. Once you’ve watched a heat source ignore its thermostat, “off” stops being a setpoint and becomes a physical state you insist on.
Morning heat, 7:30 AM. If the Tempest says it’s under 50°F outside, or the porch is under 65°F, set the target to 71°F. Otherwise leave it alone.
Midday auto-off, noon. If it’s 50°F or warmer outside, turn the heat off. The porch gets sun; by noon on a mild day it doesn’t need help. When it is still cold at noon this rule does nothing and the morning setting rides through the afternoon. Same 50°F threshold as the morning rule so the two never disagree.
Safety cutoff. This is the one the 120°F night bought. It fires on any of three conditions: the thermostat has been in heat continuously for four hours, the Aqara sensor reads above 85°F, or a second thermometer reads above 85°F. When it fires, it sets the mode to off, turns the switch off, and sends a notification titled PORCH HEATER SAFETY CUTOFF that ends with “Check physically.”
The second thermometer matters. It’s a ThirdReality sensor, different maker, different radio firmware, mounted separately. If the Aqara sensor freezes and reports 68°F forever, the generic thermostat will happily keep calling for heat, because from its point of view the room never warms up. The ThirdReality sensor doesn’t know about the thermostat and will cross 85°F on its own. A safety cutoff that depends on the same sensor the thermostat uses isn’t a safety cutoff; it’s the thermostat again.
Refresh on startup. Two minutes after Home Assistant boots, ask Zigbee2MQTT to re-poll the porch switch and temperature sensor, wait 30 seconds, and then turn the fireplace off regardless of what the poll said. Then send a note that it did so. If HA crashes while the fireplace is running, the moment it comes back up is the moment its idea of the switch state is least likely to match reality. I’d rather relight a fire than trust a restored state.
Notice that every one of those “off” actions turns off both climate.porch and switch.porch_switch. The generic thermostat is supposed to turn the switch off when you set it to off, and it does. I also turn the switch off directly, every time, because “supposed to” is what got me a 120°F porch.
Water
Two leak sensors, one automation. The Shelly Flood Gen4 sits on the floor by the washer, and a second sensor covers the utility area. Notifying is only half a leak system - the other half is a valve that closes the water, which is the subject of the Zigbee leak sensors with shutoff integration roundup. When either one goes wet, three things happen at once:
- The iPhone gets a critical push - the kind that plays at full volume through Do Not Disturb.
- The Android phone gets a high-priority push with
ttl: 0, which is the closest Android gets to the same idea. - Home Assistant creates a persistent notification that stays on every dashboard until someone clears it.
The automation runs in parallel mode with a max of 3, so if both sensors trip in the same minute the second doesn’t queue behind the first. There’s nothing clever about it. The only decision was letting this one automation bypass the phone’s quiet hours, which I don’t do for anything else in the house. A flooded laundry room at 3 AM is worth waking up for; a fridge door is not.
10:30 PM: lock and check
The last guardian runs every night at 10:30, and again whenever the house flips into Night mode, and again after a Home Assistant restart. It does two things.
First, it sends lock.lock to every exterior lock at once: the front door and the garage deadbolt. This is not “lock if unlocked”; it’s “lock, unconditionally.” The August on the front door and the Kwikset on the garage door both just lock, and if they were already locked nothing happens.
Then it waits 20 seconds, which is roughly how long a Zigbee deadbolt takes to actually throw the bolt and report back, and builds a list. The list is a Jinja template that walks through every door contact, the garage door, and every lock, and collects anything whose state is open, on, or unlocked:
Front Door: open
Garage Door: open
Garage Deadbolt: unlocked
If the list is empty, the automation does nothing and I never hear from it. If it isn’t, both phones and the dashboard get “Night Security Check - Issues found:” with the list. The important part is that it checks after locking. Sending the lock command tells you what you asked for. Reading the state 20 seconds later tells you what you got. A deadbolt that jams on a misaligned strike plate reports unlocked, and I want to know that at 10:30 PM, not at 7 AM when I find the door.
Two smaller rules back this one up during the day. Any exterior door open for five minutes, or the garage door open for ten, sends a “Door Left Open” alert with the door’s name. And after 8:30 PM, if the garage door is open, a separate rule nags every 30 minutes until it’s closed, and the message includes whether the obstruction sensor is tripped, because “garage door won’t close” and “garage door is open” need different responses from the couch.
The battery digest that keeps all of this alive
Every guardian above depends on a battery-powered sensor somewhere. The freezer thermometer, both porch thermometers, the door contacts, the leak sensors, the deadbolt. A dead coin cell doesn’t fail loudly; the sensor just stops reporting, Home Assistant keeps showing the last value it saw, and the automation waits politely for a trigger that will never come. The freezer can be at 40°F while the dashboard says -7°F.
So the last automation I’d point to isn’t a safety rule at all. It’s bookkeeping.
Sunday, 10 AM: the weekly digest. One template walks every sensor in Home Assistant with device_class: battery, skips anything unavailable or unknown, and collects everything under 20% into a list. If the list is empty, nothing happens. If it isn’t, both phones get one message titled “Low Batteries” with the device names and percentages. That’s it. No per-device automations, no entity list to maintain. A new sensor joins the house and it’s covered the following Sunday.
Every day, 9:15 AM: the critical version. Same idea, tighter threshold. Anything at or below 15% goes into a “Replace Batteries” notification that also lands as a persistent notification on the dashboard, so it stays visible until someone actually swaps the cell. It skips any entity with voltage in its name, because a few devices expose raw volts as a battery sensor and 3.0 “percent” would be on the list forever.
Five minutes later, 9:20 AM: the unavailable check. A hand-maintained list of the entities that matter - the locks, the door contacts, the garage door and its obstruction sensor, both leak sensors, the freezer thermometer, the cameras, the air-quality monitors, the bedroom temperatures - gets checked for unavailable or unknown. Anything that’s dropped off the network shows up in a “Critical HA Entities Offline” message. This is the one that catches a battery that died between digests, or a Zigbee device that fell off the mesh, or a sensor that got knocked off its shelf.
Together those three rules are the difference between “I have a freezer alarm” and “I know, this morning, that the freezer alarm can still hear the freezer.” I check the weekly one with coffee. The daily ones I only see when something is wrong, which is how a good digest should behave.
What they have in common
Looking at these together, the same few habits show up in every one:
- A
for:on every trigger. Two minutes on a door, ten minutes on a freezer temperature, four hours on a heater. None of the guardians fires on a single reading. Sensors bounce; alarms shouldn’t. - Off means off. When the action is “stop the dangerous thing,” it turns off the abstraction (the climate entity) and the physical switch under it, in that order, every time.
- Verify after acting. Lock, wait, read. Turn off, then re-poll on the next boot. The command is not the state.
- A second sensor for anything that can hurt you. The fireplace cutoff has two thermometers. The freezer has a door contact and a thermometer. One sensor is an opinion.
- Nag for the ones nobody walks past. The garage freezer and the garage door repeat until they’re fixed. The front door doesn’t, because you’re standing next to it. Repetition is a budget you only get to spend a few times, so everything that hasn’t earned it should get quieter - which is the whole argument in making a smart home less chatty.
- Watch the watchers. A guardian is only as good as the sensor feeding it, so the battery and unavailable digests are as important as anything that fires on a door.
- Nothing here leaves the house. Zigbee sensors, a Zigbee switch, a Shelly on the LAN, a weather station on UDP broadcast, and Home Assistant doing the thinking. If the internet is down, the fireplace still gets shut off at 9 PM and the freezer still nags. The push notifications need a route to the phone, and the August on the front door is the one actuator in this list that is not unconditionally local: depending on which integration you point at it, it is either cloud push or a local Bluetooth link. Everything else that acts here is on Zigbee or the LAN. That was a deliberate choice, because the night the freezer door is open is exactly as likely to be the night the ISP is having a bad time.
None of this is impressive to look at. There’s no dashboard for it. Most weeks every one of these automations runs and does nothing, and that’s the outcome I’m paying for.