My water heater gave me exactly one warning, and I missed it. For about a month it had been taking noticeably longer to give me a hot shower in the morning, and I told myself it was the cold snap. Then one Sunday I walked into the utility room in socks and stepped into a spreading cool puddle, the tank corroded through at the base, forty gallons slowly emptying across the floor toward the finished side of the basement. The appliance had been dying in slow motion and it had no way to tell me.
This is the build log for making sure the next tank cannot fail silently: an ESP32 running ESPHome watching a leak sensor ringed around the base and a temperature probe on the tank, Home Assistant correlating them, and an alert that reaches me while the floor is still dry. It is local first, it cost about the price of a nice dinner, and unlike the boxed smart leak gadgets on the shelf, no company can turn it off with a bad firmware update or a discontinued app.
Why Not Just Buy a Smart Leak Detector
There are boxed products for this. Plenty of companies sell a Wi-Fi puck you drop on the floor that pings their app when it gets wet, and some water heater makers now build a sensor into new units. I looked at them, and I want to be fair: if you buy one, set it on the floor, and it alerts you the day your tank leaks, it did its job and I am glad you stayed dry.
Here is why I did not buy one. The intelligence lives in the vendor’s cloud. The puck talks to their servers, the servers decide it is an alarm, and the servers push a notification to their app. That is three points of failure I do not own, guarding an appliance whose failure mode is measured in ruined drywall, warped flooring, and a mad dash to find the main shutoff. When one of these products gets discontinued, or the company folds, or the app stops getting updates and eventually breaks on a new phone OS, your leak alarm quietly stops working and nothing tells you it stopped. A silent failure guarding against a silent failure is the worst possible design.
I wanted the alerting brain in my own basement, on hardware I control, making decisions that execute even if every server on earth went dark. That points at ESPHome and Home Assistant.
Step 0: Understand How Your Water Heater Fails Before You Buy Anything
Do this first, because it decides which sensors you actually need. Go look at your water heater and answer three questions.
Is it a tank or a tankless unit? A traditional tank heater fails by corroding through and dumping its whole volume, so it needs both leak detection at the base and temperature trending to catch the slow decline. A tankless unit holds almost no water, so a catastrophic flood is less likely, but it can still leak at fittings and it can fail to heat, so leak sensing at the connections and outlet temperature monitoring still matter.
Where would water go if it leaked? Look at the floor around the base and find the low point. Water heaters usually sit in a pan or on a slab, and you want your leak sensor at the lowest spot where escaping water pools first. If there is a drain pan with a drain line, put a sensor in the pan itself, because that is where the first weep shows up before anything reaches the floor.
Is there an accessible cold water shutoff above the unit? Every tank heater has a cold water inlet valve on top. Note whether it is a simple quarter-turn ball valve, because that is the one an automatic motorized shutoff can later be fitted to if you want the system to stop the water itself instead of just yelling at you.
Ninety percent of utility rooms are: a tank heater on a slab or in a pan, a clear low point on the floor, a quarter-turn inlet valve up top. If that is you, order an ESP32 board, a DS18B20 waterproof temperature probe, and a leak detection sensor cable and keep reading.
The Hardware
- An ESP32 development board, around $8. This is the whole brain. It runs ESPHome, connects to your Wi-Fi, reads the leak sensor and the temperature probe, and reports to Home Assistant over your LAN. Get one with screw terminals or solder headers so you can wire things cleanly.
- A DS18B20 waterproof temperature probe, around $6. This is a one-wire digital temperature sensor on a waterproof stainless tip. You strap it to the hot outlet pipe or against the tank body to trend how the heater is performing over time.
- A water leak detection sensor cable, around $12. This is a rope-style sensor that trips when water bridges its conductors anywhere along its length, so you ring it around the base of the tank and it catches a leak no matter which side weeps first. A plain two-probe spot sensor works too and is even cheaper, but the cable covers the whole footprint.
- Optionally, a ThirdReality Zigbee water leak sensor 4-pack, around $40, placed flat around the room as independent battery-powered tripwires that keep working even if the ESP32 loses power.
- Optionally, a motorized water shutoff valve, if you want Home Assistant to close the cold water supply automatically the moment a leak is detected. This is the upgrade that turns a flood into a damp spot.
Total for the core build: about $26 for the ESP32, temperature probe, and leak cable. Call it one tenth of what a single water-damage insurance deductible runs, paid once, for hardware you own and firmware no vendor can revoke.
Step 1: Place the Leak Sensor
Kill nothing, touch no plumbing. Lay the leak detection cable in a ring around the base of the water heater, sitting at the lowest point where water would pool, and inside the drain pan if you have one. The whole idea is that the first teaspoon of escaping water bridges the cable and trips it, long before there is a puddle you would notice by eye.
Run the cable’s two leads up to wherever the ESP32 will live, keeping them tidy and away from anything hot. This is a low-voltage signal circuit and it stays completely isolated from the heater’s gas or electrical supply. If you are using a spot sensor instead of a cable, put it at the single lowest point on the floor near the base.
Step 2: Attach the Temperature Probe
This is the sensor that catches the slow death, the weeks-of-warning signal that a spot leak alarm cannot give you. Strap the DS18B20 probe against the hot water outlet pipe coming off the top of the tank, or against the tank body itself, and insulate over it with a scrap of pipe wrap so it reads the tank and not the room air.
You are not trying to measure the exact water temperature, you are trying to trend behavior. A healthy heater shows a clear rhythm: temperature rises as it heats, holds, drifts down as hot water is drawn or standby loss bleeds off, then recovers. When a tank starts to fail, that recovery gets slower and the cycling gets more frequent, and a month of logged temperature data makes that decline obvious before it becomes a leak.
Step 3: The ESPHome Config
Here is the core of the ESPHome YAML. Wi-Fi credentials live in a separate secrets.yaml and are referenced with !secret, so nothing sensitive is ever in this file. Put your real values in secrets.yaml next to this config.
esphome:
name: water-heater-monitor
esp32:
board: esp32dev
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
api:
encryption:
key: !secret api_key
logger:
one_wire:
- platform: gpio
pin: GPIO4
binary_sensor:
- platform: gpio
name: "Water Heater Leak"
pin:
number: GPIO13
mode: INPUT_PULLUP
inverted: true
filters:
- delayed_on: 1s
sensor:
- platform: dallas_temp
name: "Water Heater Tank Temp"
update_interval: 30s
The delayed_on filter debounces the leak input so a single stray reading does not fire an alarm. Flash it with esphome run water-heater-monitor.yaml, adopt the device in Home Assistant, and you now have two local entities: a leak binary sensor and a tank temperature sensor.
Step 4: The Automations That Actually Matter
There are two automations here, because there are two failure modes. The first is the emergency: water on the floor, right now. The second is the early warning: the tank is declining.
alias: Water heater leak emergency
trigger:
- platform: state
entity_id: binary_sensor.water_heater_leak
to: "on"
action:
- service: notify.mobile_app_phone
data:
title: "WATER HEATER LEAK"
message: "Leak detected at the water heater. Go check the utility room now."
- service: light.turn_on
target:
entity_id: light.utility_siren_bulb
data:
color_name: red
flash: long
- service: switch.turn_on
target:
entity_id: switch.water_main_shutoff
That local light action and the shutoff switch are deliberate. Even if my internet is down, the red flashing bulb fires and, if you have fitted the motorized valve, the water main closes, because the ESP32, Home Assistant, the light, and the valve all live on my LAN. The phone push is the nice-to-have; the local response is the guarantee.
The early-warning automation watches the temperature trend instead of a single reading. In Home Assistant you build a template or a statistics sensor over the tank temperature and alert when the average recovery over a week degrades past a threshold you set after a couple of weeks of baseline data. It is a gentle heads-up, not a five-alarm event, but it is the signal I missed in socks, and it is the whole reason to add the temperature probe at all.
The Cloud Backup That Nobody Can Brick
Here is the honest tension in a local-first build: a local siren does no good if you are at work when the tank lets go. So I do keep a cloud path, but I keep it as an addition, not a dependency, and I make sure it cannot be unilaterally revoked.
Home Assistant Cloud (Nabu Casa) gives me reliable remote push notifications and funds the project I already depend on, and if it ever went away, my local alerting and my automatic shutoff would not even notice. I also put the ESP32, my router, and the Home Assistant box on a small UPS, so a brief power blip does not blind the monitor. The layering matters: local siren and shutoff first, cloud push second, battery backup underneath all of it. Every layer degrades gracefully instead of taking the whole system down with it.
What This Caught in the First Month
Three weeks after I finished the build on my replacement tank, the early-warning automation nudged me: the tank’s recovery time had crept up about fifteen percent over the baseline. No leak, no drama, just a slow drift. I pulled and flushed the tank, found a surprising amount of sediment for a young unit, and the recovery time snapped back to normal after I drained it.
A spot leak alarm would have told me nothing until the day the tank finally corroded through. Because I had temperature data trending over weeks, I caught a maintenance issue while it was still just maintenance. That is the whole argument for monitoring behavior over time instead of waiting for the catastrophic event.
The Bottom Line
A water heater is one of the few appliances in your house that can flood a finished room, and the factory version of it has no voice at all, no way to tell you it is weeping at the base or slowly losing its ability to heat. You can give it one for about twenty-six dollars and an evening of work, and when you build it yourself on ESPHome and Home Assistant, the alerting brain lives in your basement instead of on a server you do not own and a company that might not exist in five years.
Buy the cheap ESP32 board, a DS18B20 temperature probe, and a leak detection cable, ring the cable around the base, strap the probe to the tank, and write the two automations that scream on a leak and whisper on a decline. Put it on a UPS, drop a couple of ThirdReality leak sensors around the room as independent tripwires, and if you want the system to save you while you are away, add a motorized shutoff valve so it closes the water itself. Do that, and the next time a tank starts to go, you will be standing over a dry floor reading a temperature graph instead of stepping into a cold puddle in your socks. I have been on both sides of that, and local monitoring is the cheapest peace of mind I have ever bought.