Utility Meter - Every 5 minutes

Hi,
I have a P1 meter from HomeWizard, it also measures my water usage. The sensor is in m³ and is always increasing. It updates every five minutes.

I would like to have a sensor (preferrable in liters instead of m³) that shows the water usage of the past five minutes.

I tried this:

template:
  - trigger:
      - platform: state
        entity_id: sensor.water_meter
    sensor:
      - name: Waterusage last update
        unit_of_measurement: "l"
        state: >
          {% set new = trigger.to_state.state | float(0) %}
          {% set old = trigger.from_state.state | float(0) %}
          {{ ((new - old) * 1000) | round(1) if trigger.from_state else 0 }}

This works as long as ‘some’ water is consumed. But when consumption is zero, the template sensor is not triggered and therefore the last value remains (instead of resetting to zero).

utility_meter:
  waterusage_last5min:
    source: sensor.water_meter
    name: Water usage last five minutes
    unique_id: waterusage_last5min
    cron: "*/5 * * * *"

This is the closest I got to what I need. But for some reason it always jumps to zero for five seconds before going to the actual value. So at e.g. 18:29:30 the value is “50 l” (I’m watering my garden). At 18:30:00 it jumps to “0 l” and at 18:30:05 it jumps to e.g. 45l.

And this will mess up some automations I want to build.

So I assumed this was going to be easy, but it is not.

So how to I translate my ever increasing water meter to one that gives me the amount of water consumed during the last five minutes?

I use eye-on-water from my local utility. I created utility meters in yaml. They are given below.

#  ------------------------------------------------------------------------------------
#  Water From EyeOnWater.com
#  ------------------------------------------------------------------------------------
  hourly_water_usage:
    unique_id: "Water Meter Hourly"
    source: "sensor.water_meter_70375411x064"
    name: "Hourly Water Usage"
    cycle: hourly
  
  daily_water_usage:
    unique_id: "Water Meter Daily"
    source: "sensor.water_meter_70375411x064"
    name: "Daily Water Usage"
    cycle: daily

  weekly_water_usage:
    unique_id: "Water Meter Weekly"
    source: "sensor.water_meter_70375411x064"
    name: "Weekly Water Usage"
    cycle: weekly

  monthly_water_usage:
    unique_id: "Water Meter Monthly"
    source: "sensor.water_meter_70375411x064"
    name: "Monthly Water Usage"
    cycle: monthly

  yearly_water_usage:
    unique_id: "Water Meter Yearly"
    source: "sensor.water_meter_70375411x064"
    name: "Yearly Water Usage"
    cron: "0 0 1 1 *"

My suggestion is to create utility meters and then every 5 minutes update a helper with the current value to use for the next five minute interval. Before you update the helper you do the (new - old) * 1000 | round(1). This will force a 0 as well if you use no water.

Thanks for the suggestion!

I think I have found a way to combine it all into one template sensor.

If the source-sensor didn’t change the last six minutes, I’m assuming it means that there was no water usage and change this sensor to null. It seems to work well, (I might decide to shorten the time window).

  - trigger:
      - trigger: state
        entity_id: sensor.water_meter
        to: null
        id: "meter_changed"

      - trigger: state
        entity_id: sensor.water_meter
        to: null
        for: "00:06:00"
        id: "meter_idle"
    sensor:
      - name: "Waterverbruik per update"
        unique_id: waterverbruik_per_update_l
        unit_of_measurement: "l"
        device_class: water
        state_class: measurement
        icon: mdi:water
        availability: >
          {{ is_number(states('sensor.water_meter')) }}
        state: >
          {% if trigger.id == 'meter_idle' %}
            0
          {% elif trigger.id == 'meter_changed'
                and trigger.from_state is not none
                and trigger.to_state is not none
                and is_number(trigger.from_state.state)
                and is_number(trigger.to_state.state) %}
            {% set delta = (trigger.to_state.state | float(0)) - (trigger.from_state.state | float(0)) %}
            {{ [0, (delta * 1000) | round(1)] | max }}
          {% else %}
            0
          {% endif %}