Perform basic calculations in water monitoring system

Hello everybody,

I’m completely new to HASS, but I’m trying to set up a system that monitors the entire water system of my farm.

For now, I’m just focusing my attention on the water storage part of the system. Things like well water level, pump start-stop, soil humidity and automatic irrigation will be dealt with later.

So, I’ve got four water tanks, and I installed a Dragino LDDS75 distance sensor in each tank.
The idea being to monitor the water level inside each tank.
The four tanks are connected together, but in a funny way that makes them work as a sedimentation system, that’s why they are NOT filling and emptying together, so they are not just connected in series.

Now my dashboard is reporting the distance (in centimeters) from the top of the tanks (where the sensors are installed) to the water level, like so:

As you can see from the gauges, more centimeters (distance from sensor to water level) = low water level = bad situation!

The sensors are installed in the lid of the tanks, at around 200 centimeters height, while the minimum allowed water level is a distance of 170 centimeters, which would mean a 30 centimeters water level from the bottom of the tank (10 centimeters above the outlet).

What I’d really love to do, is to manipulate those numbers in order to get more interesting data, such as:

  • available water (in liters) for each tank and for the whole system
  • water level (percentage) for each tank and for the whole system

So, is there a way to do so, by using the template sensor?

Thank you in advance for your help!

1 Like

Yes. If you can express the numbers you want mathematically in terms of the distance numbers you already have, we can advise on how to turn the arithmetic into a template.

At the moment, we have no information on the shape or dimensions of the tanks, which we would need.

Your are totally right!

So here is what I have inside configuration.yaml:

  - platform: mqtt
    state_topic: "Tank1/#################/uplink"
    name: "Tank #1 Water Level"
    unit_of_measurement: 'cm'
    expire_after: 1000
    force_update: true
    icon: mdi:water
    value_template: '{{(value_json.data[4:8] | int(base=16))/10}}'

All other sensors are the same of course, apart from names and EUIs

Regarding the tanks, they hold 2,000 liters each, for a total of 8,000 liters.
Dimensions for each tank:

  • height: around 200 centimeters (at the lid level)
  • radius: 60 centimeters

Thank you

The shape must be rounded at the top and bottom.
6 x 6 x 3.14 x 20 = 2260 liters.
Can you live with that inconsistency?

An untested example. Check the name of your existing sensor: I’m not sure how HA deals with # in the name.

- platform: template
  sensors:
    tank_1_percent:
      friendly_name: "Water tank #1 percentage"
      unit_of_measurement: "%"
      value_template: >-
        {% set water_height = 170 - states('sensor.tank_1_water_level')|float %}
        {% if water_height >= 0 %}
          {{ (water_height * 100 / 170)|round(0) }}
        {% else %}
          0
        {% endif %}

It definitely worked, thank you for that!

How do I convert centimeters to liters with another entity? Just to add the last touch of magic!
As you imagine, what I really need to see is the amount of liters and the percentage, I don’t really need to know the centimeters from lid to water level.

I guess I’ll get it to work first, and then I’ll fix the math until it shows what it should

That formula will give you the liters.
Radius x radius x pi x height.
Using decimeters mean you get the result in liters.

Height needs to be (200 - sensor reading)/10 in your case.

My issue is to apply that formula in yaml format, any idea?
Or a documentation I can read

Value_template: {{ 6*6*3.14*((200-states('sensor.tank_1_water_level'))/10) }}

If you go to Developer Tools / Template, you can play with ideas there, and there is a link to the Jinja2 template documentation that HA uses. Example below, I’ve had to fake your sensor as I obviously don’t have it on my system:

If you call the radius z and the height a, then the volume is pi·z·z·a :upside_down_face:.

I was having some issues with your code, so I’ve found another way around it.

I created to templates:

  - platform: template
    sensors:
     tank_1_positive:
      friendly_name: "Tank #1 Positive Value"
      unit_of_measurement: "cm"
      value_template: >-
        {{200 - (states('sensor.tank_1_water_level')) |float }}
        
  - platform: template
    sensors:
     tank_1_liters:
      friendly_name: "Tank #1 Liters"
      unit_of_measurement: "L"
      value_template: >-
        {{(11.42 * (states('sensor.tank_1_positive')) |float ) |round(0) }}

tank_1_positive gives me what I call a positive value, which is the true water level in centimeters, from the bottom of the tank.
This is useful also to show a history graph which is more user friendly.

tank_1_liters multiplies tank_1_positive by the liters in 1 centimeters of water.

I had to fill the tanks, and play with the numbers to account for rounding errors, and this is the result:

I think everything is fine now!

I get weird line charts because I’m having some issues with the configuration of the sensors, I’m fixing them as I type!

I don’t understand why my template would not give you a positive number.
It seems to work for me.

Good that you solved though :slight_smile:

Take a look:

Why is that?

Perhaps the state needs to be int casted first.

Value_template: {{ 6*6*3.14*((200-states('sensor.tank_1_water_level') | int)/10) }}

It worked!

Hi there,

I was wondering if you would mind sharing the whole code for this as I’m busy setting up a sensor for a single tank.

Many thanks :smiley: