How to make a total increasing water consumption sensor from water level of a water tank?

Hi,

I just managed to implement a ultrasonic sensor via ESPhome to home assistant.
I then calculate the current water level of my water tank like this:

  - sensor:
      - name: "Zisterne Füllstand"
        unit_of_measurement: L
        device_class: water
        state: "{{(states('sensor.ultraschallsensor_zisterne')|float*(-3161.9)+4600)|round(0)}}"
        state_class: measurement

As you can see, the water level is going down to a lower value, when I consume water, and it is raising up, when rain falls, due to the ultrasonic-sensor is reducing its distance with increasing water level.

Next I want to implement a total_increasing sensor that increases its level from the reduced water level. It should not change, when the water level is increasing due to rain.
How do I implement this?
The unit should be in m³, as home assistant wants this unit in the energy dashboard.

Would it work any like this?

  - sensor:
      - name: "Wasserverbrauch Zisterne"
        unit_of_measurement: m³
        device_class: water
        state_class: total_increasing
        state: "{{(states('sensor.zisterne_fullstand')|float/1000*(-1))}}"

By multiplication with (-1) I just set the value of the water tank to a negative value, to let the measurement value increase, when the water tank level sinks.
But when I manually change the value of the water tank, the value of the water usage also goes to a negative value, when the water increases again.
I must miss something

I wonder if it’s this, the cycle is being reset when you have an increasing value due to rain? Or am I missing something?

STATE_CLASS_TOTAL_INCREASING

For sensors with state_class STATE_CLASS_TOTAL_INCREASING, a decreasing value is interpreted as the start of a new meter cycle or the replacement of the meter. It is important that the integration ensures that the value cannot erroneously decrease in the case of calculating a value from a sensor with measurement noise present.

Yes, but how do I ensure, that the value only sums up the positive changes and ignores when the measurement changes due to a filling water level?

Do you think this could ever give you a reliable value? There is quite some noise on the readings, even with heavy filtering, outlier removal and averaging, the water level still goes up and down by a few litres during the day without rainfall or water use. And that is totally to be expected.

This is no issue if you just want to now how much is left in your watertank as a few percent error is insignificant. But if you try to measure actual water use by looking only at the water level going down, you will essentially integrate part of that noise as water consumption. There is no easy way to distinguish between random noise and rainfall. When you start integrating all those negligible percentage errors (and only the negative ones, not the positive ones), your reading will be completely off very quick.

I don’t think you will be able to do this, though happy to be proven wrong :smiley:

There is not that much noise - the value is constant over several time. The most noise is filtered out by accuracy of decimals of the ultrasonic sensor set to 2 decimals in meters (3 delivers some noise).
Further the value of the water tank is rounded to liters.
And I think due to the fact, that the value of interest is in m³ (not in liters), the accuracy would be sufficient.

So in fact I think it is better, than having no measurement at all.
And I don’t want to spend money on another sensor that measures my water consumption. If I would like to have the exact value I pay, I can read off my water meter manually.

This is not going to work. Imagine you are using 1 m3/h but the tank is filling at a rate of 1 m3/h at the same time. Your water level won’t change and your derived usage meter will record 0 m3/h.

This is an extremely contrived example but does show the problem with your proposed method.

ok,
I think I just found the solution here

I don’t measure the current state of my water tank for the counter sensor, but its “emptyness” meaning:
My water tank has a volume of 3999 l => the “emptyness”-value is then (current water level)*(-1)+3999
By doing so, I get a new positive counter value, each time the current ultrasonic-measurement gives a lower water level. If the water level is rising, the value is not measured.

  - sensor:
      - name: "Zisterne Füllstand"
        unit_of_measurement: L
        device_class: water
        state: "{{(states('sensor.ultraschallsensor_zisterne')|float*(-3161.9)+4600)|round(0)}}"
        state_class: measurement

  - sensor:
      - name: "Zisterne Leerstand"
        unit_of_measurement: L
        device_class: water
        state: "{{(states('sensor.zisterne_fullstand')|float*-1+3999)}}"
        state_class: measurement

I still do think, that this is going to work with my ultrasonic sensor.
Maybe it is not as exact as a volume counter sensor, but it gives some approximate results I can live with.