Using ESPhome to build a water flow rate meter

It seems very weird, recently two of my five yf-B10 flow rate sensors started giving me crazy values. More than 80 000 and 160 000 pulses per min.
The specs limit this sensor to 50 L/min and the sensors are getting water from a river. I am quite surprised to see such big numbers (around 430 L/min).

Is it physically feasible? That much water is so little time in that tube?

Are the two sensors broken? I am using the 5V supply of my D1 board to supply the 5 YF-B10.

Is the mathematical lambda formula x/370 realist even for very high flow rates? Isnā€™t just a linear regression, which works fine until 50L/min? I read that it is actually a polynomial expression : F = Q * ( 6*Q - 8 ). Which would maybe make more sense?

If this could help, I draw the different formulas. And I post also the yaml I implemented, not sure if this is the most logical way to interpret my dataā€¦ The square root comes from the solution of the polynomial equation given by the manufacturer: F = (6Q-8) Q


       - lambda: |-
          if ( x >= 14600) {
            return 50;
          } else if (x <= 8) {
            return 0;
          } else {
            return ( (8 + sqrt(64 + 24 * x) ) / 12);
          }

And here is another value which could make it easier to implement and avoid the sqrt

1 Like

I could not agree more! I have spent the last 3 hours trying to work out what pins to use on my D1 Mini ESP32.
If anyone can point me in the right direction that would be awesome!

The image you posted seems to be pretty clear, so what exactly are you looking for?

Yup the image is great, I am glad it seems self explanitory but I kind dove deep into this project having never used any boards like this (tend to use OOT wifi sensors). So I have never set up pins on a board before I know its furstrating to keep repeating if its been mentioned or its obvious and im sorry but after hours of attempting to figure it out I seem to have a board with no youtube tutorials or online help as the D1 esp8266 seems to be the main version of D1 mini, I have the D1 Mini esp32 which has different pin layout, I have no idea what pin to use for signal wire on my flow sensor. GRN i get, and I think red is 5V but no idea where to put the yellow signal cable.
I found this form but that confused me even more tbh.
https://www.letscontrolit.com/forum/viewtopic.php?t=8191

Assuming that you are using a similar flow sensor as has been discussed earlier in this thread, it seems to be just a pulse generator (so no I2C or SPI protocol).
So you should be able to connect the signal wire to any of the general purpose digital I/O pins, like for instance the GPIO16 pin.

Yup its a pulse one I think (Amazon.co.uk)
ok! that totally explains my confusion I saw so many people using so many different pins I was pulling my hair out why. Thank you so much!

I did have a look at that Amazon page, and indeed this is such a flow sensor giving a pulse with every revolution. So thatā€™s OK.
However, on this Amazon page the flow rate is not specified (the number of pulses per litre).
Often with this kind of sensors this is specified with a formula like for instance F = ( 8 * Q ) - 4 (with varying constant values) where F is the pulse signal frequency in [pulses/sec] and Q is the flow in [L/min].
So hopefully this sensor is delivered with that information.
If not you can only use it by doing your own calibration.

Ah! thats great, thanks a lot for looking. I did not get anything in the package when they arrived and nothing on the site, I have reached out to the seller for more details the flow rate.

Good news is that I do not really mind if its incorrect for now (flow rate is a nice to have) I mainly need it as a binary, there is flow and there is no flow, its inline on my shower head to automate other bathroom devices.

Lets see what the seller come back with. Thanks again

Hi, I know this a discussion from 2020. Are there still any people responding to comments and questions? Nevertheless, I give it a try. I am building a supervisory system for a small water supply system. The supervisory system consists of a waterflow sensor YF-B10 and two pressure sensors connected to ESP32. I have got the sensors up and running and presenting values in Home Assistant.
The problem I am facing is that the flow sensor YF-B10 is non-linear which means the the model (pulse_counter) gives non zero values when the actual flow is zero. According to the spec for YF-B10, the device can meassure flow from 2 litre/min to 25 litre/min. So, my idea was to arrange for a dead band equal to zero between 0-2 litre/min flow. I tried to arrange that with logical operators IF and THEN . But it seams that the Pulse_counter in ESP32 do not accept that. I also tried with the Yaml function CLAMP (for defining of min and max operation area). But the Pulse_counter does not accept that either.

I am a new user of Raspberry Pi and Home Assistant, so I am not very familiar with Yaml yet.
Maybe there are someone that could give me som advice?

Introduction:

Some community members have approached me with requests to consolidate and detail the code Iā€™d developed into a singular post for easier comprehension. I must admit, itā€™s been several months since I last revisited this project. Today, Iā€™m pleased to finally share it in its entirety. Please note, this post is intended for informational purposes, and if it assists or inspires other enthusiasts in the community, it would bring me immense satisfaction.

Entities Overview:

Hereā€™s a summary of the entities that will be discussed and their respective functionalities:

  1. Instantaneous Water Flow Rate (sensor.debit_d_eau_instantane): Monitors the real-time flow rate of water.
  2. Total Water Volume in Cubic Meters (sensor.eau_total_en_m3): Tracks the cumulative water usage in mĀ³.
  3. Total Water Volume in Liters (sensor.utilisation_d_eau_total): Tracks the cumulative water usage in liters.
  4. Duration of the Last Water Usage (sensor.duree_ecoulement_eau_principale): Measures how long water has been flowing in the most recent usage.
  5. Volume of the Last Water Usage (sensor.volume_derniere_utilisation): Calculates the volume of water used in the last flow.
  6. Cost of the Last Shower (sensor.cout_de_la_derniere_douche): Estimates the cost associated with the water used during the last shower.
  7. Water Flow Binary Sensor (binary_sensor.debit_d_eau_on_off): A binary sensor indicating whether water is currently flowing.
  8. Starting Water Volume (input_number.volume_de_depart_debit ): A helper entity to store the starting volume for specific duration calculations.

Here is the card I created to have an overview of the entities:

Now, letā€™s delve into the specifics of the implementation.

Using ESPhome to Build a Water Flow Rate Meter for Shower Analysis

In this guide, weā€™ll explore a solution Iā€™ve implemented to monitor and analyze water usage during showers using the Home Assistant platform. This setup harnesses the capabilities of a NPT YF-B5 water flow sensor, though you can adapt it to work with other similar sensors. The goal here is twofold:

  1. Create an automation that provides contextual data via Google Home Mini after each shower.
  2. Design a Lovelace card displaying key metrics related to water consumption.

This setup not only records the duration and volume of water consumed during showers but also provides contextual feedback on the shower duration compared to the national average. Such insights aim to promote awareness and sustainable water usage.

Now, letā€™s delve into the implementation:

1. Instantaneous Water Flow Rate (in ESPHome)

Capture real-time water flow rate using the NPT YF-B5 sensor (or your chosen water flow sensor).

sensor:
  - platform: pulse_counter
    pin:
      number: 4
      mode:
        input: true
        pullup: true
    unit_of_measurement: 'L/min'
    accuracy_decimals: 2
    id: water_usage
    name: "DƩbit d'eau instantanƩ"
    update_interval: 5s
    filters:
      - lambda: return (x / 396); # 396 = 6.6 * 60

2. Total Water Volume Measurements (in ESPHome)

Determine the overall water volume in both cubic meters and liters:

a. Total volume in cubic meters:

sensor:
  - platform: integration
    name: "Eau total en M3"
    unit_of_measurement: 'mĀ³'
    accuracy_decimals: 2
    sensor: water_usage
    time_unit: min
    filters:
        - lambda: return (x / 1000);

b. Total volume in liters:

sensor:
  - platform: integration
    name: "Utilisation d'eau total"
    unit_of_measurement: 'L'
    accuracy_decimals: 2
    sensor: water_usage
    time_unit: min

3. Setting up Helper Entities (in the Home Assistant UI or configuration.yaml)

Helpers in Home Assistant are entities that store temporary values. In this project, weā€™ll utilize an input_number helper to keep track of the starting water volume for our calculations.

a. Setting up input_number for Starting Water Volume:

Helpers in Home Assistant are entities that store temporary values. They can be used in automations, scripts, or Lovelace dashboards. In this project, weā€™ll utilize an input_number helper to keep track of the starting water volume for our calculations.

a. Setting up input_number for Starting Water Volume:

If youā€™re using the Home Assistant UI:

  1. Navigate to Configuration > Helpers.
  2. Click on the ā€œ+ Add Helperā€ button.
  3. Select ā€œNumberā€.
  4. Provide a name such as ā€œStarting Water Volumeā€ and set the desired range and step values. Note down the entity ID; it will look something like input_number.starting_water_volume.

If you prefer to set up using the configuration.yaml file:

input_number:
  volume_de_depart_debit:
    name: Starting Water Volume
    initial: 0
    min: 0
    max: 100000
    step: 1

This input_number entity will store the water volume at the start of our monitoring period and can be used in template calculations to determine water usage for a specific duration.

b. Automation to Set the Starting Water Volume:

alias: "Set Starting Water Volume"
trigger:
  - platform: state
    entity_id:
      - binary_sensor.debit_d_eau_on_off
    to: "on"
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.volume_de_depart_debit
    data:
      value: "{{ states('sensor.utilisation_d_eau_total') | float }}"

This automation sets the starting water volume to the current total water volume whenever the water starts flowing.

4. Template Sensors (in configuration.yaml)

a. Binary Sensor for Water Flow Detection:

template:
  - binary_sensor:
    - name: DĆ©bit d'eau (ON/OFF)
      state: "{{ states('sensor.debit_d_eau_instantane') | float(0) > 0 }}"

b. Duration of the Last Water Usage:

sensor:
  - platform: template
    sensors:
      duree_ecoulement_eau_principale:
        friendly_name: "Duration of Last Water Flow"
        unit_of_measurement: "sec"
        value_template: >
          {% set t = states('sensor.duree_ecoulement_eau_principale') | float if states('binary_sensor.debit_d_eau_on_off') == 'off' else now().timestamp() - states.binary_sensor.debit_d_eau_on_off.last_changed.timestamp() %}
          {{ t | round(2) }}

c. Volume of the Last Water Usage:

sensor:
  - platform: template
    sensors:
        volume_derniere_utilisation:
          friendly_name: "Last Water Usage Volume"
          unit_of_measurement: 'L'
          value_template: >
            {{ (states('sensor.utilisation_d_eau_total') | float - states('input_number.volume_de_depart_debit') | float) | round(2) }}

d. Cost of the Last Shower:

sensor:
  - platform: template
    sensors:
        cout_de_la_derniere_douche:
          friendly_name: "Cost of the Last Shower"
          unit_of_measurement: '$'
          value_template: >
            {{ (states('sensor.volume_derniere_utilisation') | float * 0.01) | round(2) }} #change the multiplier (0.01) by your local cost of energy to heat up 1 litre of water to your tank set temperature

5. Prerequisites

To ensure the automation runs smoothly, ensure you have the binary_sensor.debit_d_eau_on_off set up to detect water flow.

6. Automations

a. Voice Feedback After Shower (Using Google Home Mini):

This automation is particularly interesting as it provides an integration of contextual data after a shower. It gives insights into the duration of the shower, the volume of water used, and how this compares with the national average.

alias: "Shower Feedback - Duration and Volume"
trigger:
  - platform: state
    entity_id:
      - binary_sensor.debit_d_eau_on_off
    to: "off"
    from: "on"
condition:
  - condition: numeric_state
    entity_id: sensor.duree_ecoulement_eau_principale
    above: "240" #this condition ensure that not all water usage will trigger the automation. A continuous 4 minutes and above will be considered a shower, below can be a toilet or a dishwaher. You can adjust according to your own house usage.
  - condition: not
    conditions:
      - condition: state
        entity_id: sensor.presence_iphone_lydia #My girlfriend has a beauty salon in the basement. If she uses the water for her salon and it goes above 240 seconds, it's not a shower, so I have a condition that check if her phone is located in her beauty salon (I use ESPresense but you can set your own method of detection if you have such exceptions)
        attribute: distance
        state: ess
action:
  - delay: "00:00:25"
  - service: media_player.volume_set
    data:
      volume_level: 0.5
    target:
      entity_id: media_player.salle_de_bain_rdc
  - service: tts.speak
    data:
      cache: true
      media_player_entity_id: media_player.salle_de_bain_rdc
      message: >
        {% set t = states('sensor.duree_ecoulement_eau_principale') | int %}
        {% set m = t // 60 %}
        {% set s = t - m * 60 %}
        Your shower lasted {{ m }} minutes and {{ s }} seconds, consuming {{ states('sensor.volume_derniere_utilisation') | int }} liters of water. 
        {% if t > 480 %}
        This duration is {{ ((t - 480) / 480) | round(1) * 100 }}% longer than the national average.
        {% endif %}
        Please be mindful of your water consumption. Thank you and have a great day.
    target:
      entity_id: tts.google_translate_say
mode: single

This comprehensive setup offers a deep dive into understanding water consumption patterns and, when combined with Home Assistantā€™s automation capabilities, can be a powerful tool for promoting water conservation.

15 Likes

Thank you @donparlor, quite an extensive explanation! :slight_smile:
The biggest problem I get is how to make sure the flow meter is well calibrated. I personally use the YF-B10 but I canā€™t get to a formula which provides satisfactory results. The other problem is that this sensor is working properly between 2 and 50 L/min. So what happen outside these boundaries?
For information, I need this kind of sensors as it regulates the full water supply and consumption in my entire houseā€¦

Hello @mgim,

YF-B10 is a 1" diameter 2-50 L/min flow sensor. If your house provide more than 50 litres per minute it means calculations wonā€™t be reliable beyond 50 litres if you are using your water at its full capacity. GPM (or LTM litres per minute) can be calculated manually by a bucket test filling. If you house goes beyond 50 L/min there are other 1" flow sensors with a larger capacities like the FS400A 1-60L/min and the YF-G1 2-100L/min, but they both are in plastic. It might work well for many years but Iā€™d be worried to install a plastic flow sensor on my house main water line.

Provide your code so we can help

Could you find which pin to use? Based on your picture I would use the GPIO16 or GPIO17 pin. These pins are general and do not appear to have any associated special functions, making them suitable for pulse reading.

An example of an ESPHome configuration for your flow sensor might look like this:

sensor:
  - platform: pulse_counter
    pin: GPIO16
    name: "Flow Sensor"
    update_interval: 5s
    filters:
    - multiply: [conversion value to get the flow rate]

You just need to find your conversion values

About using your flow sensor as an ON/OFF value that you can track and use, I would recommend a binary_sensor in your configuration.yaml as I described above in my own code structure post.

a. Binary Sensor for Water Flow Detection:

template:
  - binary_sensor:
    - name: DĆ©bit d'eau (ON/OFF)
      state: "{{ states('sensor.debit_d_eau_instantane') | float(0) > 0 }}"

@donparlor you sir are a legend!
I put pause on this while we finish up running the electrics so that I can plug it all in and test it.
Here are some pictures of the current state, once all electrics are in ill pop this ESPHome int a little box and hook it up then start configuring in home assistant.

Ah the binary config makes perfect sense thanks! ill start with that then once I feel adventurous I can attempt measuring flow if I want to give that a go.
Thanks again!
Flow sensors one for each shower head (its a dual shower)


Electrics all accessible in the cupboard the other side.

Ill come back and update once I get something configured.
Ill also come back to share config and step by step for anyone else looking to do the same.
Thanks again!

Very interesting setup! A water flow sensors for each shower head will provide you with very specific and detailed data for each shower head. I am jealous of your setup, I am using a water flow sensor on my main valve so itā€™s a little bit more clunky and hard to isolate the water going to the shower head.

Keep us updated.

Have a good day @Phatty

hello everybody,

I bought the YF-S402B sensor

Iā€™ve been struggling to figure out how to calculate the Liters/min and Liters/hour.
I canā€™t figure out how to calculate the formula to enter into esphome.

Frequency: F=38 * Q (L / Min) error: Ā±2%

Thanks for the support

1 Like

Based on the given frequency relationship F=38 * Q (L / Min) error: Ā±2% (where F is the frequency and Q is the flow rate in L/min), we can derive the flow rate from the frequency. The pulse counter in ESPHome counts the number of pulses (or edges) per given time period. If we assume the pulse counter measures the frequency in Hz (pulses per second), then:

Capture dā€™eĢcran, le 2023-10-17 aĢ€ 11.49.14

Given that the update interval is every 5 seconds, the pulse count will be 5 times the frequency in Hz. Thus, if x is the pulse count over 5 seconds

:Capture dā€™eĢcran, le 2023-10-17 aĢ€ 11.49.19

Letā€™s adapt the code with the above calculations:

sensor:
  - platform: pulse_counter
    pin:
      number: 4
      mode:
        input: true
        pullup: true
    unit_of_measurement: 'L/min'
    accuracy_decimals: 2
    id: water_usage
    name: "Instant flow rate"
    update_interval: 5s
    filters:
      - lambda: return (x / (5.0 * 38)); # Calculation based on given frequency relationship

This will give you the instantaneous water flow rate in liters per minute.

Let us know if it works. You can also do a bucket test and calculate what is your full flow rate GPM or LTM and compare with the values calculated by your flow sensor once you programmed it.

4 Likes

Thanks for the support, Iā€™ll try the setup as soon as I can.

Just one question where does the update value come from? is it a value that we set or is it a fixed value

Thanks again