ESP Projects

Build a DIY Flo: whole-house water monitor and automatic shutoff with an ESP32

Commercial smart shutoffs like the Moen Flo watch your main water line, spot leaks from the way water flows, and close a valve before a burst pipe floods the house. This build does the same job with an ESP32, an inline flow sensor, a pressure sensor and a motorized ball valve. Everything runs locally in Home Assistant, with no subscription.

Read this first. This project cuts into your main water line. If you aren't comfortable sweating copper or crimping PEX, have a plumber fit the valve and sensors; the electronics are low voltage and safe to build on the bench. If your house's electrical ground is bonded to metal water pipe, a plastic flow sensor breaks that bond. Fit a bonding jumper across the new section, and check your local code.

Cost
$80–150
Time
An afternoon, plus plumbing
Difficulty
Advanced
Skills
Plumbing, 12 V wiring

How it catches a leak

A leak looks different from normal use, so the monitor watches for three patterns:

  • A burst: very high flow that keeps going. The ESP32 closes the valve on its own after two minutes, even if Home Assistant or Wi-Fi is down.
  • A running fixture: water that never stops, like a toilet flapper stuck open or a hose left on. Home Assistant warns you after flow has run nonstop for longer than any normal use.
  • A slow drip: too small for the flow sensor to see. At night, Home Assistant closes the valve and watches the pressure for five minutes. If it falls, water is escaping somewhere. This is the same trick the Flo calls its MicroLeak test.

A leak probe under the water heater or washer adds a fourth check: if it gets wet, the valve closes at once.

Parts

  • An ESP32 DevKit.
  • A hall-effect water flow sensor sized for your main line, usually 3/4" or 1". It must be rated for drinking water and your line pressure.
  • A 12 V motorized ball valve, full port, the same size as your main. Get a 3-wire or 5-wire model; they open and close from a single 12 V supply.
  • A 0–100 psi pressure transducer with a 0.5–4.5 V output, 1/4" NPT thread.
  • A 2-channel relay module.
  • A 12 V, 2 A power supply for the valve, and a small 12 V to 5 V buck converter for the ESP32.
  • Four resistors: two 10 kΩ and two 20 kΩ, plus a 1 MΩ for the leak probe.
  • A leak probe and an enclosure that will stay dry next to the plumbing.
  • ESP32 DevKit
    ESP32 DevKitView on AmazonPhoto: Edwiyanto, CC BY-SA 4.0
  • Hall-effect water flow sensor (3/4" or 1")
    Hall-effect water flow sensor (3/4" or 1")Illustration
  • 12 V motorized ball valve (3- or 5-wire)
    12 V motorized ball valve (3- or 5-wire)Illustration
  • 0–100 psi pressure transducer (0.5–4.5 V)
    0–100 psi pressure transducer (0.5–4.5 V)Illustration
  • 2-channel relay module
    2-channel relay modulePhoto: Suyash Dwivedi, CC BY-SA 4.0
  • 12 V 2 A power supply
    12 V 2 A power supplyIllustration
  • 12 V to 5 V mini buck converter
    12 V to 5 V mini buck converterIllustration
  • Resistor assortment
    Resistor assortmentView on AmazonPhoto: Afrank99, CC BY-SA 2.5
  • Water leak probe cables
    Water leak probe cablesIllustration
  • Plastic project enclosure
    Plastic project enclosureIllustration

Where it goes on the pipe

Install everything just after your existing main shutoff, in this order: main shutoff → motorized valve → flow sensor → pressure sensor → the house. Keep the old manual shutoff so you can still turn the water off by hand. The pressure sensor must sit downstream of the motorized valve, or the nightly drip test can't work.

Point the flow sensor's arrow the way the water flows, and give it a few inches of straight pipe on each side so the reading stays steady.

Don't want to cut the pipe? You can measure flow without plumbing by reading your water meter's internal magnet with a QMC5883L magnetometer taped to the meter. It counts water just as well, but you lose the shutoff and the pressure test unless you fit the valve anyway.

Wiring

PartWireGoes to
12 V supply+12 V / −Buck converter input, relay COM terminals, valve common
Buck converter (5 V out)OUT+ / OUT−ESP32 5V (VIN) / GND
Flow sensorRed / black / yellow5V / GND / 10 kΩ to GPIO27, 20 kΩ from GPIO27 to GND
Pressure transducerRed / black / signal5V / GND / 10 kΩ to GPIO34, 20 kΩ from GPIO34 to GND
Relay moduleVCC / GND / IN1 / IN25V / GND / GPIO26 (open) / GPIO25 (close)
Relay 1 NOValve OPEN wire
Relay 2 NOValve CLOSE wire
Leak probeTwo contactsGPIO32 and GND, with 1 MΩ from GPIO32 to 3.3V

The flow and pressure sensors run on 5 V, so their signals go through a 10 kΩ / 20 kΩ divider that brings 5 V down to about 3.3 V for the ESP32.

Valve wire colors vary between makers, so go by your valve's label or listing. A 3-wire valve has one common wire and one wire each for open and close. 12 V on the open wire turns it open, and 12 V on the close wire turns it closed; limit switches inside stop the motor at each end. A 5-wire valve adds two feedback wires that report when it is fully open or fully closed.

Wiring diagram
Wiring diagram. Click to open full size.

The ESPHome config

The valve shows up in Home Assistant as a valve you can open and close. The leak probe and the burst check close it directly on the ESP32, so they work even when Home Assistant doesn't.

switch:
  - platform: gpio
    id: relay_open
    pin: GPIO26
    restore_mode: ALWAYS_OFF
    interlock: [relay_close]
    internal: true
  - platform: gpio
    id: relay_close
    pin: GPIO25
    restore_mode: ALWAYS_OFF
    interlock: [relay_open]
    internal: true

valve:
  - platform: template
    name: "Main water"
    id: main_valve
    optimistic: true
    open_action:
      - switch.turn_on: relay_open
      - delay: 20s
      - switch.turn_off: relay_open
    close_action:
      - switch.turn_on: relay_close
      - delay: 20s
      - switch.turn_off: relay_close

sensor:
  - platform: pulse_meter
    pin: GPIO27
    name: "Water flow"
    id: water_flow
    unit_of_measurement: "L/min"
    device_class: volume_flow_rate
    state_class: measurement
    accuracy_decimals: 2
    internal_filter: 1ms
    timeout: 1min
    filters:
      - multiply: 0.002222   # 1 / 450 pulses per litre
    total:
      name: "Water used"
      unit_of_measurement: "L"
      device_class: water
      state_class: total_increasing
      accuracy_decimals: 1
      filters:
        - multiply: 0.002222

  - platform: adc
    pin: GPIO34
    name: "Water pressure"
    id: water_pressure
    attenuation: 12db
    update_interval: 5s
    unit_of_measurement: "psi"
    device_class: pressure
    state_class: measurement
    accuracy_decimals: 1
    filters:
      - multiply: 1.5
      - lambda: 'return (x - 0.5) * 25.0;'
      - sliding_window_moving_average:
          window_size: 6
          send_every: 1

binary_sensor:
  - platform: gpio
    pin: GPIO32
    name: "Water heater leak"
    device_class: moisture
    filters:
      - invert:
      - delayed_on: 2s
    on_press:
      - valve.close: main_valve

  - platform: template
    name: "Burst pipe suspected"
    device_class: problem
    lambda: 'return id(water_flow).state > 30.0;'
    filters:
      - delayed_on: 2min
    on_press:
      - valve.close: main_valve

Add your usual esphome, esp32, wifi, api and ota blocks at the top. The 20-second delay covers the slowest valves; the limit switches stop the motor sooner, so a longer delay does no harm.

Calibrate it

Flow

Every flow sensor has its own pulses-per-litre figure, and the number in the listing is only a starting point. To check yours, note the Water used total, fill a bucket of known size from a tap, then compare. If 10 litres reads as 9.2, multiply both multiply values by 10 ÷ 9.2.

Pressure

Compare the reading with a cheap gauge on an outdoor tap. If it's off by a fixed amount, add an offset filter after the lambda. Most homes sit between 40 and 80 psi.

The burst threshold

30 L/min (about 8 gallons a minute) is roughly two showers and a washing machine at once. Run everything you might ever run together, watch the peak flow, and set the threshold comfortably above it.

Water use in Home Assistant

Water used has the right device class and state class for Home Assistant's water dashboard. Go to Settings → Dashboards → Energy, find Water consumption, and add it. You'll get daily and hourly water use next to your electricity.

Home Assistant automations

  • Running water warning: notify when Water flow stays above 0 for 45 minutes. Raise it if you have long irrigation runs, or add a condition that the sprinklers are off.
  • Away mode: when everyone leaves, close the valve, or warn on any flow at all while the house is empty.
  • Nightly drip test: at 3 a.m., if flow is zero, close the valve and save the pressure. Wait five minutes. If the pressure has dropped by more than 2 psi, notify that a slow leak is likely. Then open the valve again. Skip the test if anyone uses water while it runs.
  • Leak probes elsewhere: any leak sensor in the house can close the valve too, through a Home Assistant automation.
  • Exercise the valve: close and reopen it once a month so it doesn't seize. Do it at night, when nobody is using water.

A pressure drop during the test isn't always a leak. A water heater that's heating pushes pressure up, and one that's cooling can pull it down a little. If you get false alarms, run the test at a time the heater is idle, or raise the 2 psi threshold.

What it costs compared with a Flo

A commercial smart shutoff typically costs several hundred dollars before installation. The parts here come to roughly $80–150, depending mostly on the valve size and brand. The trade-off is the work: you're responsible for the plumbing, the calibration, and making sure it fails safe.

Troubleshooting

SymptomLikely cause and fix
Flow always reads zeroThe arrow points the wrong way, or the sensor's output needs a pull-up. Try a 10 kΩ from the signal to 3.3V in place of the divider.
Water used is off by a steady percentageThe pulses-per-litre figure doesn't match your sensor. Calibrate with a bucket and adjust both multiply values.
Valve hums but doesn't moveThe 12 V supply is too weak, or open and close are swapped. Check the valve label and use a 2 A supply.
Valve shows open after a reboot when it's closedThe template valve can't see the real position. A 5-wire valve's feedback wires fix this.
Nightly test fails every nightWater heater cooling, or a real slow leak. Check toilets with dye tablets, then try a different test time.