Water flow reseting to zero in lambda - help

Hi, rather new to code so hopefully someone can help. Have a water flow meter working but want to rest the value to zero before the pump turns on. I have cut and paste from other examples on the forum but can’t get it to work.

the “litres delivered” works fine.
the template switch and setting the id: fish state to zero works
can’t seem to push the litres delivered to the id fish - not sure about the global bit too.

thanks very much

globals:
  - id: am
    type: int
    restore_value: no

    
    
sensor:
  - platform: pulse_counter
    name: "Flow rate"
    pin: GPIO5
    update_interval: 2s
    filters:
    - lambda: return (x / 450.0) * 60.0;
    unit_of_measurement: "L/hr"  
    

    total:
      unit_of_measurement: 'litres'
      name: 'litres delivered'
      accuracy_decimals: 2
      filters:
        - lambda:  |-
            return (x /450.00);
            id(am) += x;
            id(fish).publish_state(id(am));
            return x;
     
      
            
  - platform: template
    id: fish
    name: "Water amount" 
    unit_of_measurement: 'l'
   

      
switch:
  - platform: gpio
    pin: GPIO5
    name: reset
    on_turn_on:
      sensor.template.publish:
        id: fish
        state: 0
        

bump with thanks

I’d like to try to help, but it’s not clear to me what it’s supposed to be doing?
Can you explain the way it’s used a little further?

Think I have cracked it! I changed the type in the global variable (to float) along with the lambda code slightly.

Thanks for replying, next task is to use input slider to stop the pump at a certain amount of litres!

Hi, thanks for replying, thought I had it cracked but no so. Hopefully you can help.

So want to transfers water from container A to container B. Transferring “X” amount of litres every time, ideally in the end using a slider/number input to change X.

The problem I have is reseting the pulse counter to zero before each time the pump is turning on. At the moment the counter is accumulative.

I have copied this code from other threads and using a global value to store the litres delivered. The litres delivered works great its calibrated and using the 450 pulses records the correct amount of litres. The publish_state then pushes this value to the global “am”.

I am then trying to get the switch template to reset the global AM value to zero before the pump is turned on again. It does do this but straight after it updates to the “litres delivered”.

I hope that explains my problem. I need the amount delivered to reset to zero each time the pump is turned on.

My code so far:

thanks again

globals:
  - id: am
    type: float
    restore_value: yes

    
    
sensor:
  - platform: pulse_counter
    name: "Flow rate"
    pin: GPIO5
    update_interval: 2s
    filters:
    - lambda: return (x / 450.0) * 60.0;
    unit_of_measurement: "L/hr"  
    total:
      unit_of_measurement: 'litres'
      name: 'litres delivered'
      accuracy_decimals: 2
      filters:
        - lambda:  |-
            x = x / 450.00;
            id(am) = x;
            id(fish).publish_state(id(am));
            return x;
            
  - platform: template
    id: fish
    name: "Water amount" 
    unit_of_measurement: 'l'
    accuracy_decimals: 2
   
switch:
  - platform: gpio
    pin: GPIO5
    name: reset
    restore_mode: ALWAYS_OFF
    on_turn_on:
      sensor.template.publish:
        id: fish
        state: 0

How about, in the on_turn_on automation within the switch, instead of sensor/id/state, use this lambda:

- lambda:  |-
            id(am) = 0 ;

You currently are having it publish the state 0 for ‘fish’ but that does not change the contents of the variable, it just sends an artificial ‘0’ to Home Assistant. Then, when the sensor runs it also publishes the actual amount from the global ‘am’. So the ‘am’ variable needs to be reset to 0, and there’s no need to make the publish call at that time, because the sensor will publish when it sees activity.

Thanks very much, I did try something similar earlier but seems I am getting the same result. copied below is the amended code. Also included a picture of Lovelace. The reset toggle now doesn’t change the “water amount”, as previously it would momentarily change to 0.

the automation I have created works fine, it starts the pump via the 1 litre WC toggle and stops it when the litres delivered reaches greater than 1 litre. My expectation was to adjust the automation to stop the pump when the “water amount” gets to 1, with this reseting to zero after each cycle.

Spent hours on this and beginning to think I am missing the obvious!

hopefully sorted soon thanks again, much appreciated.

switch:
  - platform: gpio
    pin: GPIO5
    name: reset
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - lambda:  |-
            id(am) = 0 ;

I missed this earlier. The pulse counter sensor is keeping its own running total, and is applying it to ‘am’ each time, so ‘am’ is just tracking along with the pulse-counter’s running total.
What you want to do is reset the pulse-counter’s total, or ignore it (you wouldn’t need the whole section under ‘total:’)

In the pulse-counter’s filter lambda, add this line:

id(am) += x;

so that whatever flow is being clocked at the moment is added to the accumulating total in ‘am’.

Then, your reset switch will reset ‘am’ to 0 for you, and the count-up begins again next cycle.

thanks again

 filters:
        - lambda:  |-
            x = x / 450.00; 
            id(am) += x;
            id(fish).publish_state(id(am));
            return x;

this is what I changed. now the water amount is an accumulative total of the litres delivered with each increment the same value as the litres delivered. so its water amount + litres delivered + litres delivered and so on, if I use the reset toggle the count starts from zero, adding litres delivered each time. hope that makes sense.

Glad it worked.
If you feel it is so, plase mark my answer as the solution, which brings closure to the question.

no sorry it didn’t work. the reset toggle just resets the value to zero but it then adds the litres delivered to it straight away irrespective of the pump and pulses received(wihich are zero). its just a calculator adding up constantly, its over 350 litres now with no pump on.

Could you paste your entire code here once again?
I think I see what’s wrong. We’re adding to ‘am’ during each call to read the sensor, which isn’t what we want.
Let me have a fresh look at the whole thing, and I believe the solution will emerge.

thank you so much, this is driving me nuts…

globals:
  - id: am
    type: float
    restore_value: no

    
    
sensor:
  - platform: pulse_counter
    name: "Flow rate"
    pin: GPIO5
    update_interval: 2s
    filters:
    - lambda: return (x / 450.0) * 60.0;
    unit_of_measurement: "L/hr"  
    total:
      unit_of_measurement: 'litres'
      name: 'litres delivered'
      accuracy_decimals: 2
      filters:
        - lambda:  |-
            x = x / 450.00; 
            id(am) += x;
            id(fish).publish_state(id(am));
            return x;
            
  - platform: template
    id: fish
    name: "Water amount" 
    unit_of_measurement: 'l'
    accuracy_decimals: 2
   
switch:
  - platform: gpio
    pin: GPIO5
    name: reset
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - lambda:  |-
            id(am) = 0;

belongs in the ‘filters:’ lambda, not the ‘total:’ lambda.

You can discard the entire ‘total:’ block, because you aren’t using that total anyway since it’s ever-cumulative.

Your sensor should look like this:

really sorry if I am being slow here…

pic of Lovelace, and code below.

sorry and thanks

change to this:

globals:
  - id: am
    type: float
    restore_value: no

sensor:
  - platform: pulse_counter
    name: "Flow rate"
    pin: GPIO5
    update_interval: 2s
    filters:
    - lambda: return (x / 450.0) * 60.0;
            id(am) += x;
            id(fish).publish_state(id(am));
            return x;
    unit_of_measurement: "L/hr"  
    #total:
    #  unit_of_measurement: 'litres'
    #  name: 'litres delivered'
    #  accuracy_decimals: 2
    #  filters:
    #    - lambda:  |-
    #        x = x / 450.00; 
    #        id(am) += x;
    #        id(fish).publish_state(id(am));
    #        return x;
            
  - platform: template
    id: fish
    name: "Water amount" 
    unit_of_measurement: 'l'
    accuracy_decimals: 2
   
switch:
  - platform: gpio
    pin: GPIO5
    name: reset
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - lambda:  |-
            id(am) = 0;

I keep missing small stuff.
You return the first statement in the lambda, so none of its other code is happening.
Change it to be this:

- lambda: |-
            id(am) += (x / 450.0) * 60.0;
            id(fish).publish_state(id(am));
            return x;

I may be misunderstanding your units-conversion math, but I think that this will do what it should, and accumulate an amount in ‘am’ while displaying the current flow rate (which is sometimes zero).
The yellow line on the lovelace display is because we did away with an entity that you don’t care about: the sensor’s total accumulated flow.

This may be more accurate, units-wise:

- lambda: |-
            id(am) += x / 450.0 / 30; // liters-per-minute, sampled 30 times per minute
            id(fish).publish_state(id(am));
            return  x / 450.0 * 60.0;

amended code below, this is worse, got the calculator effect on water amount and the calibration is way off.

the 450 is the pulses which equal 1 litre. so the x/450 would be all that matters. I don’t really care about litres/min/hours etc, just the total amount passing through the sensor.

is there away to reboot the d1 mini after or before each pump on/off command. the resetting zeros the litres delivered.

thanks again

globals:
  - id: am
    type: float
    restore_value: no

    
    
sensor:
  - platform: pulse_counter
    name: "Flow rate"
    pin: GPIO5
    update_interval: 2s
    filters:
    - lambda: |-
            id(am) += (x / 450.0) * 60.0;
            id(fish).publish_state(id(am));
            return x;
    unit_of_measurement: "L/hr"  
  
    
    total:
      unit_of_measurement: 'litres'
      name: 'litres delivered'
      accuracy_decimals: 2
      filters:
        - lambda: |-
            id(am) += x / 450.0 / 30; // liters-per-minute, sampled 30 times per minute
            id(fish).publish_state(id(am));
            return  x / 450.0 * 60.0;        
  
  - platform: template
    id: fish
    name: "Water amount" 
    unit_of_measurement: 'l'
    accuracy_decimals: 2
   
switch:
  - platform: gpio
    pin: GPIO5
    name: reset
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - lambda:  |-
            id(am) = 0;

Not sure why you’d want to reboot just to reset a counter - there’s always a way.
What’s not working at this point? Is the ‘reset’ switch not clearing ‘am’ back to zero?
Don’t worry about the units being correct, yet. First thing is to get the counter to increment when flow is happening, and go back to 0 when you push ‘reset’.
BTW, why is the reset switch pointed at the same GPIO as the sensor? That may be a small problem, too. All you want the reset switch to do is clear the ‘am’ variable at this point, so the switch should probably be a template, not GPIO, type.

And do try using the code I posted above, in the second block where I said it may be more accurate. There are several differences betwen it and what you just now posted.