When the First Alert Fails: Building an Escalation Chain for a Water-Leak Notification
A water leak is a condition, not an event. That distinction is the whole problem with the way most of us wire up leak notifications. We write an automation that triggers when the leak sensor goes on, sends a notification, and stops. If that notification is missed, dismissed, or delivered to a phone that is face-down on a desk in another room, nothing brings it back while water is still running.
Home Assistant’s own automation documentation frames the issue plainly: automations react when something happens, not while something is true. A leak sensor that goes on and stays on is a condition that remains true. A one-shot automation is the wrong shape for it.
What follows is a three-level escalation chain built from documented Home Assistant primitives: a persistent notification in the interface, a phone notification through a specific notify entity, and a repeating alert that keeps firing until someone acknowledges it — then re-arms itself so an acknowledged leak does not go silent forever. The chain is deliberately redundant. Each level fails differently, and that is the point.
Why a one-shot automation is the wrong shape
The standard leak automation looks like this: trigger on the leak binary sensor changing to on, action sends a notification. It fires once. If the notification is swiped away, the automation has already run and will not run again until the sensor goes off and back on. A slow drip that keeps the sensor wet for hours produces exactly one notification.
Home Assistant’s Alert integration exists for this class of problem. The documentation describes it as designed to notify when problematic issues arise, with repeating notifications at customizable intervals, and explicitly names water leak sensors among its use cases. That is the primitive the escalation chain is built on.
The escalation ladder
Three levels, each with a different failure mode:
Level 1 — Persistent notification. A notification in the Home Assistant notifications panel. This survives a phone being off, silenced, or out of the house. It is the quietest level and the one most likely to be ignored, but it is also the one that cannot be lost to a notification tray swipe. The Notify integration documents notify.persistent_notification for exactly this, and the documentation’s own example is a kitchen leak sensor.
Level 2 — Phone notification via a specific notify entity. This reaches the person who can act. The critical detail is the target. The Notify documentation warns that notify.notify is a shorthand for the first notify action Home Assistant can find, so the destination is not explicitly selected and the message might not be sent where you expect. For a leak, the destination is the whole point. Use notify.send_message with an explicit notify entity target.
Level 3 — Repeating alert with acknowledgement. The Alert integration watches a single entity’s state and sends repeating notifications at customizable intervals until the condition clears or someone acknowledges. This covers the case where levels 1 and 2 were seen and ignored.
Configuring the alert for a leak sensor
The Alert integration only checks whether a single entity’s state equals a value. For a plain leak binary sensor, that is sufficient — no Template Binary Sensor is required. The documentation notes that more complex criteria (a battery percentage below a threshold, a condition that depends on more than one input) are handled by pairing the alert with a Template Binary Sensor. A leak sensor that reports on when wet does not need that layer.
A minimal alert entry in configuration.yaml:
alert:
water_leak_utility:
name: Water leak at utility sink
entity_id: binary_sensor.utility_leak
state: "on"
repeat:
- 5
- 15
- 30
- 60
can_acknowledge: true
skip_first: false
notifiers:
- mobile_app_eli
The repeat option takes either a number or a list of numbers. With a list, the delays between notifications change as the alert continues to fire. The documentation’s example: with repeat: [15, 30, 60], the first message is sent after 15 minutes, the second 30 minutes after that, and a 60-minute delay falls between every following notification.
For a leak, widening intervals are the right shape. Frequent early reminders while someone is likely nearby, then spacing out so the alert stays present without becoming noise that gets muted. A five-minute first interval is aggressive; whether that is appropriate depends on where the sensor sits and who is home. I have not seen a case where a leak alert needed to fire faster than the sensor’s own reporting interval, and I would not set the first repeat shorter than the sensor’s expected reporting cadence.
skip_first: false sends the first notification immediately when the condition becomes true. Setting it to true delays the first notification until the first repeat interval. For a leak, immediate is usually correct — the first notification is the one that matters most.
Making the alert acknowledgeable from the phone
An alert entity has three states: idle when the condition is false, on when the condition is true, and off when the condition is true but acknowledged. That third state is the one that trips people up. off does not mean the leak is resolved. It means someone acknowledged it.
To acknowledge from a phone notification, the Alert documentation shows triggering on the mobile_app_notification_action event and calling alert.turn_off on the alert entity:
automation:
- alias: Acknowledge utility leak alert from phone
triggers:
- trigger: event
event_type: mobile_app_notification_action
event_data:
action: ACKNOWLEDGE_UTILITY_LEAK
actions:
- action: alert.turn_off
target:
entity_id: alert.water_leak_utility
The alert.turn_off action acknowledges the alert so it stops sending notifications. The alert.turn_on action removes the acknowledgement so it sends notifications again.
Re-arming: the step that prevents silent failure
Here is the failure the chain exists to prevent, and the one it can create if you stop too early. Someone acknowledges the leak alert from their phone while standing in the kitchen. The alert entity goes to off. The leak is still there. If nothing re-arms the alert, it stays silent forever — which is exactly the failure mode the escalation chain was built to avoid.
The Alert documentation shows the pattern: an acknowledged alert can be turned back on by a zone trigger when a person leaves home, so reminders resume if the condition is still true. The same shape works for a leak:
automation:
- alias: Re-arm utility leak alert when leaving home
triggers:
- trigger: zone
entity_id: person.eli
zone: zone.home
event: leave
actions:
- action: alert.turn_on
target:
entity_id: alert.water_leak_utility
If the leak has cleared by the time the person leaves, the alert entity is already idle and alert.turn_on has no effect. If the leak is still present, the alert resumes firing on its repeat schedule. This is the step that converts an acknowledgement into a temporary silence rather than a permanent one.
Clearing the persistent notification on resolution
The persistent notification from level 1 should clear when the leak resolves, not linger in the notifications panel. The Alert integration supports a done_message sent after an alert transitions from on or off to idle, but only if an alert notification was sent for the transition from idle to on.
For companion-app notifications, the documentation describes a pattern using a tag in the message data and clear_notification as the done_message. That pattern is documented for companion-app notifications; I have not verified it against every notifier type, and the Alert documentation does not claim it works universally.
The diagnostic path
When a leak notification does not arrive, the question is where the chain broke. The alert entity’s state is the first diagnostic surface:
idle— the condition is false. Either there is no leak, or the sensor is not reporting one. The problem is upstream of the alert.on— the condition is true and unacknowledged. The alert should be firing. If no notification arrived, the problem is in the notifier or the notification path.off— the condition is true but acknowledged. Someone silenced it. If that was not intentional, the re-arm step is missing or broken.
From there, the diagnostic path follows the chain backward. Home Assistant’s automation documentation describes testing automations by running the automation or a single step and reading its trace, and troubleshooting guidance that maps symptoms to causes. The Notify documentation describes testing a notification action from Settings > Tools > Actions: choose the action, select targets, enter the message, and select Perform action. That test isolates the notifier from the automation.
If the notifier test succeeds but the alert does not fire, the problem is in the alert configuration or the entity it watches. If the notifier test fails, the problem is the notification target — a phone that is unavailable, a notify entity that has gone unavailable or unknown. The Notify documentation notes that a notify entity’s state is a timestamp showing when a message was last sent, and that it can also be unavailable or unknown. That timestamp is a useful check: if it has not updated since the leak started, the message never left.
If the alert entity is idle while water is present, the problem is the sensor. For a Zigbee leak sensor, Zigbee2MQTT publishes device availability to zigbee2mqtt/FRIENDLY_NAME/availability when Device-Availability is configured. If that topic shows the device offline, the sensor dropped off the mesh and no leak state will arrive. Zigbee2MQTT also publishes the bridge state as a retained message — {"state":"online"} on startup and {"state":"offline"} right before the bridge stops — which distinguishes a dead sensor from a dead bridge.
For an ESPHome-based leak sensor, the binary sensor component supports a timeout filter that invalidates the state if no value is published for the specified time period. That turns a silent sensor into an unknown state rather than a stale off, which is a more honest failure. The delayed_on_off filter only publishes an ON or OFF value if the sensor has stayed in the same state for at least the specified time period, which debounces a sensor that flickers as water spreads.
Graceful degradation
If the phone notifier is unavailable, the persistent notification level still records the leak in the interface, and the alert entity still transitions to on. The chain degrades to a quieter but still truthful signal rather than to silence. That is the argument for keeping level 1 even when level 2 is the one that actually reaches you.
What the chain does not do: it does not work when Home Assistant itself is down. It does not wake you, bypass Do Not Disturb, or override phone notification settings. It does not detect leaks — that is the sensor’s job, and the alert only watches an entity’s state. If the host is off, no level of the chain fires. A mechanical water alarm with its own battery and its own siren is a reasonable complement for that case, and for some installations it is the smarter primary and the smart-home chain is the secondary. I would not argue against a standalone alarm on the floor near the water heater.
A repeatable procedure
Build the chain in this order, testing each level before adding the next:
- Confirm the leak sensor’s entity ID and that it reports
onwhen wet. Watch the entity in Developer Tools while you wet the sensor. If it does not change, stop here — the chain cannot fix a sensor that does not report. - Test the phone notifier in isolation. Go to Settings > Tools > Actions, choose
notify.send_message, select the specific notify entity, enter a test message, and select Perform action. Confirm the message arrives on the intended phone. - Add the persistent notification automation. Trigger it manually and confirm the notification appears in the Home Assistant notifications panel.
- Add the alert entry with a short first repeat interval for testing — one or two minutes, not the production value. Restart Home Assistant to load the configuration.
- Wet the sensor and confirm the alert entity goes to
onand the first notification arrives. - Acknowledge the alert from the phone notification and confirm the alert entity goes to
offand notifications stop. - Trigger the re-arm automation manually and confirm the alert entity returns to
onwhile the sensor is still wet. - Dry the sensor and confirm the alert entity returns to
idleand the persistent notification clears. - Set the production repeat intervals and restart.
Step 7 is the one people skip, and it is the one that catches the silent-failure bug. If the alert does not resume after acknowledgement, the bug is in the re-arm automation, not the alert configuration — and the alert entity’s state will show off rather than on.
Where this fits in a broader audit
A leak escalation chain is one of several small systems that run quietly until they fail. The same diagnostic shape — identify the condition, check each level of the chain, test the notifier in isolation — applies to any alert that is supposed to keep firing while a problem persists. If you are inventorying the systems in your home that fall into this category, How to Audit the Small Systems That Quietly Run Your Week covers the broader audit.
Questions that come up
Does the alert fire again if the leak clears and returns? Yes. The alert transitions from idle to on when the condition becomes true, and the repeat schedule starts again. The done_message is sent on the transition back to idle, but only if a notification was sent for the idle-to-on transition.
Can I use notify.notify instead of a specific entity? You can, but the documentation warns that the destination is not explicitly selected and the message might not be sent where you expect. For a leak, use notify.send_message with an explicit target.
What if I have more than one leak sensor? Create one alert entry per sensor. Each alert watches a single entity’s state. If you want one alert to cover a group, pair it with a Template Binary Sensor that is true when any leak sensor is on — the Alert documentation describes this pattern for criteria more complex than a single entity state equaling a value.
Does the alert survive a Home Assistant restart? The retrieved documentation does not cover alert behavior across a restart. I have not tested it, and I would not assume the repeat schedule resumes where it left off. If the alert entity returns to on after restart, the condition is still true and the alert should fire again on its schedule; if it returns to off, the acknowledgement may persist. Test this on your own instance before relying on it.
Should I set can_acknowledge: false? That prevents the alert from being acknowledged, so it keeps firing until the condition clears. For a leak, that is defensible — an acknowledged leak is still a leak. The tradeoff is that a false positive from a wet sensor becomes an alert you cannot silence without fixing the sensor. For a sensor you trust, can_acknowledge: false removes the re-arm step entirely and the failure mode it carries.