Monitoring Water Tank Levels with M5Stack Atom and HX711 in Home Assistant

Monitoring Water Tank Levels with M5Stack Atom and HX711 in Home Assistant

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

  1. Attach the Atom Lite to the Scales Kit base. Make sure it sits flush and all pins are properly connected.
  2. Connect the load cell to the HX711 module (comes prewired in the kit).
  3. 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

  1. Place the tank empty and call the set_empty service in Home Assistant.
  2. 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.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.