Water flow meter with pulse counter - Daily Usage

I’ve added a water flow meter using a Wemos D1 mini and ESPhome.
The pulses are counted as pulses per minute by ESPhome. I’ve calculated the pulses as 17 per min per litre of water (it’s 1pulse per gallon of water through the meter).

Homeassistant is displaying the L/min water flow no problem, I added a second sensor to the ESPhome config to divide by 60 giving the actual flow in L/sec. I thought this would be useful to calculate the total water flow per day. I need this total to know when to backwash my water filters but I am unable to find a reliable way of totaling the water flow from either sensor and displaying in the Dashboard as “Water total today in Litres”.

I’ve tried the utility meter and its calculations are way off. I tried the statistics feature but can’t find how to expose it to the front-end or where to even see the data it’s collecting.

I tried the power_meter but that’s for energy and doesn’t seem to work with L as it’s expecting W for electricity.

Any suggestions welcome.
Thanks

1 Like

I have a similar pulse meter setup to yours and I do this to calculate the total usage over the last 24 hours:

- platform: statistics
  entity_id: sensor.water_usage
  name: "Water Usage Stats"
  # 10s sampling, so 6*60*24 points
  sampling_size: 8640
  max_age:
    hours: 24

- platform: template
  sensors: 
    water_usage_total:
      friendly_name: Total Usage
      value_template: >-
        {% if not is_state("sensor.water_usage_stats", "unavailable") %}
          {{ state_attr('sensor.water_usage_stats','total') | float }}
        {% else %}
          0.00
        {% endif %}
      unit_of_measurement: "gals used last 24h"

Displaying it in Lovelace looks like this:

              - type: entities
                entities:
                  - entity: sensor.water_usage_total
                    icon: 'mdi:water-pump'

My ESPHome sensor is pretty simple:

sensor:
  - platform: pulse_counter
    pin: 12
    name: "Water Usage"
    update_interval: 10s
    unit_of_measurement: 'gal'
    filters:
      # reports in pulses/min, so divide by 6 and by 64 pulses per gallon
      multiply: 0.0026041667
2 Likes

You could use a lambda and a static int variable to maintain a running value

Cheers’ I’m going to try this.

Where do you get the number 8640 for this? I presume I’ll need to adjust accordingly!

edit.

Sorry I missed this bit: ```

10s sampling, so 66024 points

I tried this using exactly the code as you provided and adjusted sampling times etc. accordingly but the daily total numbers are waaayyy off. Total usage so far today is showing as 15412.8 litres :slight_smile:
My flow rate is L/min and that is reading correctly. If I turn on the water at a flow rate of say 5L/min the total daily usage would jump by random amounts from 5L to 150-200L.
Not sure what’s going on. It seems that trying to record a total of water used by summing up the individual L/min is not going to give accurate results.

I think what needs to be done is that a separate pulse counter needs to be added to ESPhome keeping a running total of each pulse counted since say the previous midnight. This would be a simple number that just increments with each pulse counted. Then we could easily convert that to L or Gal etc.

I wonder is this even possible?

Review the ‘Tip:’ just above this bookmark:

This looks exactly like what i need:

lambda: |-
  static int num_executions = 0;
  ESP_LOGD("main", "I am at execution number %d", num_executions);
  num_executions += 1;

However, I’ve tried to add it to the pulse counter sensor and it won’t validate. I also tried to add it to a template sensor but it won’t validate either.

sensor:

  • platform: pulse_counter
    id: water_pulse
    pin: D3
    name: “Pulse Counter”
    update_interval: 3s
  • platform: template
    name: “Water Usage”
    id: water_usage
    accuracy_decimals: 1
    unit_of_measurement: “L”
    icon: “mdi:water”
    lambda: |-
    static int num_executions = 0;
    ESP_LOGD(“main”, “I am at execution number %d”, num_executions);
    num_executions += 1;
    update_interval: 3s

I also tried adding the id to the lambda like this

lambda: |-
  static int num_executions = 0;
  ESP_LOGD("main", (id(water_pulse).state), "I am at execution number %d", num_executions);
  num_executions += 1;

Still not validating. Any idea where I’m going wrong?

What confused me for a while was that the pulse counter always extrapolates out to pulses/min based on whatever sampling rate you choose, so that’s why I have to do the multiplication to convert it to the actual number of pulses used in the last sampling period, and from that into the number of gallons used during that time.

    filters:
      # reports in pulses/min, so divide by 6 and by 64 pulses per gallon
      multiply: 0.0026041667

at that point, it should be perfectly usable for what you need. Each point represents the last 10s of usage, and adding them all up over the course of a 24 hour period is your usage. I don’t know why it would be jumping around for you, but if you enable logging like this:

logger:

you’ll get a log message each time the pulse counter is read and the computed value is sent to HA:

[15:41:43][D][pulse_counter:158]: 'Water Usage': Retrieved counter: 0.00 pulses/min
[15:41:43][D][sensor:092]: 'Water Usage': Sending state 0.00000 gal with 2 decimals of accuracy

I tried going down a similar road to what you’re doing when I first started on this and finally realized after a few days of messing around that it was much more complicated than it needed to be.

What sensor are you using?

I apologize for bringing up an old thread…

I’ve got a similar goal – tracking total water usage. My meter provides a pulse per gallon. With a 60 second update_interval that gets me gallons/minute.

I don’t think this config will work in my case, right?

This is the config I’ve used since and it works great.

time:

  • platform: homeassistant
    id: homeassistant_time
    on_time:
    • seconds: 0
      minutes: 30
      hours: 6
      days_of_week: MON-SUN
      then:
      • switch.turn_on: restart_switch

ota:

sensor:

  • platform: pulse_counter
    id: water_pulse
    pin:
    number: D1
    mode: INPUT_PULLUP
    internal: true
    name: “Pulse Counter”
    update_interval: 1s
    filters:

    • lambda: |-
      static float total_pulses = 0.0;
      total_pulses += x * 1 / 60.0;
      id(lifetime_counter).publish_state(total_pulses / 17);
      return x ;
  • platform: template
    id: lifetime_counter
    name: “Water Total”
    unit_of_measurement: “L”

  • platform: template
    name: “Water Flow Rate”
    id: water_flow_rate
    accuracy_decimals: 1
    unit_of_measurement: “L/min”
    icon: “mdi:water”
    lambda: return (id(water_pulse).state /17);
    update_interval: 3s

    meter is 1 pulse per gallon so divide by 17 gives litre/min

switch:

  • platform: restart
    name: “Restart”
    id: restart_switch
    internal: true

The restart at 6am switch is just a crude way to reset the values to 0 for the next day. Homeassistant has since added a daily total sensor which I’ve yet to implement but this works well for me and is very accurate. Matches actual flow rate etc. as shown on my water filter display in the garage.

2 Likes

Thank you @craggy!

Any reason why you’ve got the flow rate returning every 3s but the pulse counter updating every 1s?

Hey
Bought the yf-b10 water flow sensor.
Now I get no reading of any flow in homeassistant.
I assume that it somehow because of the flow pulse formula.

This is how I define the sensor in esphome:

sensor:

  • platform: template
    id: lifetime_counter
  • platform: pulse_counter
    id: water_pulse
    pin: D2
    name: “Pulse Counter”
    update_interval: 1s
    filters:
    • lambda: return (6.5163 * x) - 2.7;
      unit_of_measurement: “L/hr”

What am I doing wrong???

I don’t have a wemos but a reed switch water meter hooked up to an esp32. I was fiddling around with integration sensor and utility meter, tried statistics too, nothing really accomplishing what could have been. Finally I got the idea to treat the input as a binary sensor, in that case we can count the amount of times it turned ‘on’ which in my case corresponds to one litre. The history stats integration actually does a great job of counting the amount of on times and can easily be reset every hour, day, month. I also use the history stats to show the total usage over the past 24 hours.
esp32 code:

binary_sensor:
  - platform: gpio
    pin: 22
    name: binary_water

home assistant configuration code:

sensor:
  - platform: history_stats
    name: water_daily_usage
    entity_id: binary_sensor.binary_water
    state: "on"
    type: count
    start: "{{ now().replace(hour=0, minute=0, second=0) }}"
    end: "{{ now() }}"
  - platform: history_stats
    name: water_24_usage
    entity_id: binary_sensor.binary_water
    state: "on"
    type: count
    end: "{{ now() }}"
    duration:
        hours: 24

Maybe this’ll help with daily usage

1 Like

Hey @craggy did you ever manage to improve on this using the new “daily total sensor” stuff?
My flow meter does 3357 pulse per 1 litre based on my testing… I’m trying to figure out how to use your example to get an accurate cumulative daily total litres and also a flow rate of l/min.