DIY Water Tank Level Monitoring with ESP8266 + HC-SR04 (Wi-Fi + Home Assistant Integration)

DIY Water Tank Level Monitoring with ESP8266 + HC-SR04 (Wi-Fi + Home Assistant Integration)

Hi everyone,
I’d like to share my latest DIY project: a water tank level monitoring system built with an ESP8266 and an HC-SR04 ultrasonic sensor. It features a web interface, REST API, automatic Wi-Fi setup, and full testing pipeline (UI + API + mocked sensor values).

I designed this to reliably track how full my water tank is, visualize it in Home Assistant, and get notifications when the tank runs low.

Hardware

  • ESP8266 (NodeMCU/WeMos D1 Mini)
  • HC-SR04 ultrasonic distance sensor (measures air gap)
  • Optional: level shifter (to protect ESP8266’s 3.3V input on Echo pin)
  • A water tank :wink:

Features

  • Web UI served from the ESP8266

    • Tank setup (L, W, H in cm)
    • Wi-Fi setup (configure once, stored in EEPROM)
    • Live dashboard (air gap, water height, volume in liters, percent)
  • REST API
    Example:

    GET /status
    {
      "air_gap_cm": 12.34,
      "water_height_cm": 117.66,
      "liters": 47064.00,
      "percent": 90.5,
      "full_gap_cm": 15.00
    }
    
  • “Full reference” calibration
    Fill the tank, press a button → it records the air gap at full.

  • Overfill detection
    Percent can exceed 100% if water level is above the calibrated “full”.

  • Wi-Fi fallback

    • Connects to saved Wi-Fi if available
    • Otherwise starts its own Access Point (TankLevel-XXXX)
  • EEPROM reset shortcut
    Double-press reset button clears stored Wi-Fi and tank config.

Home Assistant Integration

The ESP8266 exposes metrics via /status. You can pull this data into Home Assistant using the RESTful Sensor integration.

Example configuration:

sensor:
  - platform: rest
    name: "Tank Water Level"
    resource: http://192.168.1.42/status
    value_template: "{{ value_json.percent }}"
    unit_of_measurement: "%"
  - platform: rest
    name: "Tank Water Liters"
    resource: http://192.168.1.42/status
    value_template: "{{ value_json.liters | round(0) }}"
    unit_of_measurement: "L"

Now you can graph water levels, trigger automations, or notify when the tank drops below a threshold.

Testing Pipeline

To keep the project reliable, I built a BDD-style test suite in Python:

  • UI tests (Playwright + pytest-bdd)

  • REST API tests (pytest + requests)

  • Mocking sensor readings

    • Over HTTP (/mock?gap=15.0)
    • Or via USB serial commands (MOCK ON, MOCK SET <value>, MOCK OFF)

This allows automated validation of both firmware logic and HA integration.

Getting Started

  1. Flash firmware to ESP8266
  2. Connect HC-SR04 to pins D5/D6
  3. Power it up → connect to AP → configure Wi-Fi
  4. Calibrate with a full tank
  5. Add sensors in Home Assistant

Links

With this setup I can always see exactly how full the tank is, get alerts before it runs dry, and trust that the readings are consistent thanks to automated tests.

Nice project but most people here integrate the HC-SR04 sensor using ESPHome as it is a fully supported component that only requires a couple of lines of YAML.

If you notice you are getting erroneous reading due to condensation on the sensor (as has been reported in the past) you might want to look at these as an alternative: https://www.aliexpress.com/item/1005005928682318.html

1 Like

Thanks for your feedback!

My situation is that the Raspberry PI is far away from the water tank and I need to read it wireless, at a distance. That’s the solution I found.

Yeah, that is how ESPHome works.

1 Like