Keeping track of water levels in a tank can be a simple yet highly useful automation project. In this post, I’ll demonstrate how to build a smart water tank monitor. We will use an M5Stack Atom Lite, the M5Stack Scales Kit, and ESPHome. This will be fully integrated into Home Assistant.
Components Used
- M5Stack Atom Lite – a compact ESP32 development board
- M5Stack Scales Kit – includes HX711 load cell module and weight plate
- HX711 Load Cell – built into the kit
- ESPHome – to flash the Atom and integrate with Home Assistant
- Home Assistant – for monitoring, visualizations, and automation
Optional: a mobile device for push notifications.
Hardware Setup
- Attach the Atom Lite to the Scales Kit base. Make sure it sits flush and all pins are properly connected.
- Connect the load cell to the HX711 module (comes prewired in the kit).
- Double-check the ribbon cable orientation between Atom and HX711; the correct pins are:
DOUT → GPIO32
CLK → GPIO26
That’s it! The hardware is plug-and-play if using the official M5Stack kit.
ESPHome Firmware
Below is the complete ESPHome YAML for this project, including the raw sensor, calibrated liter sensor, percent sensor, and calibration services.
esphome:
name: water
friendly_name: Water
esp32:
board: m5stack-atom
framework:
type: arduino
logger:
api:
services:
- service: set_empty
then:
- lambda: |-
id(min_raw) = id(hx711_sensor).state;
ESP_LOGI("calibration", "New EMPTY value stored: %f", id(min_raw));
- service: set_full
then:
- lambda: |-
id(max_raw) = id(hx711_sensor).state;
ESP_LOGI("calibration", "New FULL value stored: %f", id(max_raw));
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
globals:
- id: min_raw
type: float
restore_value: yes
initial_value: '0.0'
- id: max_raw
type: float
restore_value: yes
initial_value: '10000.0'
- id: max_liter
type: float
restore_value: yes
initial_value: '5.0'
sensor:
- platform: hx711
id: hx711_sensor
name: "Water raw"
dout_pin: GPIO32
clk_pin: GPIO26
gain: 128
update_interval: 2s
- platform: template
name: "Water liter"
unit_of_measurement: "L"
accuracy_decimals: 1
update_interval: 2s
lambda: |-
if (isnan(id(hx711_sensor).state)) {
return NAN;
}
float raw = id(hx711_sensor).state;
if (raw < id(min_raw)) return 0.0;
if (raw > id(max_raw)) return id(max_liter);
return (raw - id(min_raw)) * id(max_liter) / (id(max_raw) - id(min_raw));
- platform: template
name: "Water percent"
unit_of_measurement: "%"
accuracy_decimals: 0
update_interval: 2s
lambda: |-
if (isnan(id(hx711_sensor).state)) {
return NAN;
}
float raw = id(hx711_sensor).state;
if (raw < id(min_raw)) return 0.0;
if (raw > id(max_raw)) return 100.0;
return (raw - id(min_raw)) * 100.0 / (id(max_raw) - id(min_raw));
#Optional to add Bluetooth proxy
bluetooth_proxy:
Calibration
- Place the tank empty and call the
set_empty
service in Home Assistant. - Fill the tank completely (e.g., 5 liters) and call the
set_full
service.
The sensors will now automatically calculate the water volume and percentage.
Home Assistant Lovelace Dashboard
Here’s a clean dashboard layout that includes:
- Gauge showing tank fill percentage
- Raw and liter sensor values
- Buttons for calibration
type: vertical-stack
cards:
- type: gauge
entity: sensor.water_percent
name: Fill percentage
unit: "%"
min: 0
max: 100
severity:
green: 70
yellow: 30
red: 0
- type: entities
title: Water status
entities:
- entity: sensor.water_liter
name: Liter in tank
- entity: sensor.water_percent
name: Fill percentage
- entity: sensor.water_raw
name: Raw value
- type: horizontal-stack
cards:
- type: button
name: Set Empty
icon: mdi:scale-unbalanced
tap_action:
action: call-service
service: esphome.water_set_empty
- type: button
name: Sett FULL
icon: mdi:scale
tap_action:
action: call-service
service: esphome.water_set_full
Home Assistant Automation for Low Water Level
To get notified when the water level drops below 20 %, use the following automation:
alias: Water low level
description: "Notify when tank is below 20%"
trigger:
- platform: numeric_state
entity_id: sensor.water_percent
below: 20
condition: []
action:
- service: notify.mobile_app_your_phone
data:
title: "Wops"
message: "Water level below 20%! Time to refill!"
mode: single
Conclusion
With this setup, you now have a fully automated water tank monitoring system:
- Accurate measurement using a load cell and HX711
- Easy calibration with two services (
set
_empty/set_full
) - Lovelace dashboard with visual gauge and raw/liter values
- Push notifications for low water levels
This setup is flexible. It can be adapted for larger tanks or multiple tanks. It can even be integrated with other Home Assistant automations for irrigation or water management.
Some of the links in this article are "affiliate links", a link with a special tracking code. This means if you click on an affiliate link and purchase the item, we will receive an affiliate commission. The price of the item is the same whether it is an affiliate link or not. Regardless, we only recommend products or services we believe will add value to our readers. By using the affiliate links, you are helping support our Website, and we genuinely appreciate your support.