Total water usuage, based on l/m

I’ve got a water flow meter, that sends data based on mqtt.

Number   dodgerWaterFlow   "Rainwater"   { channel="mqtt:topic:451040c553:a2ef0b77f9:Waterflow" }
DateTime dodgerPumpStart   "Pump started"

This gives me nicelty the values:

2022-03-25 11:04:57.654 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 0 to 5.2
2022-03-25 11:05:00.663 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 5.2 to 0
2022-03-25 11:13:04.925 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 0 to 0.13333333333333333
2022-03-25 11:13:07.926 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 0.13333333333333333 to 12.133333333333333
2022-03-25 11:13:10.936 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 12.133333333333333 to 12
2022-03-25 11:13:31.990 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 12 to 11.866666666666667
2022-03-25 11:13:35.002 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 12
2022-03-25 11:13:38.016 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 12 to 11.866666666666667
2022-03-25 11:13:41.109 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 12
2022-03-25 11:13:45.134 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 12 to 11.866666666666667
2022-03-25 11:13:50.041 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 12
2022-03-25 11:13:53.056 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 12 to 11.866666666666667
2022-03-25 11:14:17.117 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 2.2666666666666666
2022-03-25 11:14:20.123 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 2.2666666666666666 to 0
2022-03-25 11:14:47.195 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 0 to 4.266666666666667
2022-03-25 11:14:50.196 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 4.266666666666667 to 12
2022-03-25 11:14:56.218 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 12 to 11.866666666666667
2022-03-25 11:15:17.275 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 11.733333333333333
2022-03-25 11:15:20.281 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.733333333333333 to 11.866666666666667
2022-03-25 11:15:26.301 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 11.733333333333333
2022-03-25 11:15:29.306 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.733333333333333 to 11.866666666666667
2022-03-25 11:15:41.337 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 11.733333333333333
2022-03-25 11:15:47.362 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.733333333333333 to 11.866666666666667
2022-03-25 11:15:53.373 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 11.733333333333333
2022-03-25 11:15:59.392 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.733333333333333 to 11.866666666666667
2022-03-25 11:16:02.395 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 11.733333333333333
2022-03-25 11:16:08.409 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.733333333333333 to 11.866666666666667
2022-03-25 11:16:11.428 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 11.866666666666667 to 2.6666666666666665
2022-03-25 11:16:14.441 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 2.6666666666666665 to 0
2022-03-25 11:19:50.984 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 0 to 3.3333333333333335
2022-03-25 11:19:53.978 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'dodgerWaterFlow' changed from 3.3333333333333335 to 0


I'm now trying to calucate now the total amount of water that I used. But after 2 days fighting with founding out how I can calcute the time between 2 values, I think it's time to ask some help. ;)

I’ve got follow rule that works.

rule "Rainwater usuage"
when
   Item dodgerWaterFlowLastUpdate received update
then
   var now3000 = now.toInstant().toEpochMilli()
   dodgerPumpStart.postUpdate(now3000)     
   logInfo("Water", "TEST021 now     : " + now3000 )

   var item3000 = (dodgerPumpStart.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000
   logInfo("Water", "TEST022 item    : " + item3000 )

   var runtime3000 = (now3000 - item3000)/1000
   logInfo("Water", "TEST025 diff    : " + runtime3000 )
end

Gives me, as expected:

2022-03-25 12:17:50.398 [INFO ] [org.openhab.core.model.script.Water ] - TEST021 now     : 1648207070397
2022-03-25 12:17:50.401 [INFO ] [org.openhab.core.model.script.Water ] - TEST022 item    : 1648198361000
2022-03-25 12:17:50.403 [INFO ] [org.openhab.core.model.script.Water ] - TEST025 diff    : 0

But I should have the previous datetime value for the pumpstart. This way, I can find out the amount of seconds, and calculate the excact water usuage (I hope).
rule "Rainwater usuage"
when
   Item dodgerWaterFlowLastUpdate received update
then
   var now3000 = now.toInstant().toEpochMilli()
   dodgerPumpStart.postUpdate(now3000)     
   logInfo("Water", "TEST021 now     : " + now3000 )

   var item3000 = (dodgerPumpStart.previousState().state as DateTimeType).getZonedDateTime.toEpochSecond * 1000
   logInfo("Water", "TEST022 item    : " + item3000 )

   var runtime3000 = (now3000 - item3000)/1000
   logInfo("Water", "TEST025 diff    : " + runtime3000 )
end

error:

2022-03-25 12:16:37.287 [INFO ] [org.openhab.core.model.script.Water ] - TEST021 now     : 1648206997285
2022-03-25 12:16:37.290 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'waterTest-1' failed: cannot invoke method public abstract org.openhab.core.types.State org.openhab.core.persistence.HistoricItem.getState() on null in waterTest



Of course, better suggestions are more then welcome. :wink:

ps I tried also the timestamp profile, but these gave me a lot more updates. Not sure from where these came from, guess each time a mqtt sync?

There are two timestamp profiles. One for update, one for change. “Update” can include update to same value. Understanding what your MQTT device is sending you would help here.

Specifically, if it is sending flow updates at regular intervals, maybe that is just what you need to trigger the process of calculating volume since last update …

1 Like

This is a small python script on a raspberry pi zero, with following in it.

global count
count = 0
 
def countPulse(channel):
   global count
   if start_counter == 1:
      count = count+1
 
GPIO.add_event_detect(FLOW_SENSOR_GPIO, GPIO.FALLING, callback=countPulse)
 
start_counter = 1
time.sleep(2)
start_counter = 0
flow = (count / 8.7) # 8.7 = Pulse frequency (Hz), Q is flow rate in L/min.
publish.single("WaterFlow", flow, hostname=127.0.0.1)
count = 0
time.sleep(1)

I could trigger it every 3 seconds (at this moment) with a cron, but guess it would be better that openHAB only acts on changes, no? Since this will only happen 5 times a day or so for some minutes.



Ahhh, I just changed it from timestamp-update to timestamp-change. This can explain the ‘many’ updates.
Correct me if I’m wrong, but in my script, I should also use the previousState of it, correct? So guess I’ll have the same issue/error?

I don’t know what your issue/error is.

There are several ways to calculate volume.

If you get periodic reports, calculate flow x time since last report, trigger on every report.

Or, ignore periodic reports except changes, calculate flow x time since last change, trigger on every change.
Same if reports are coming irregularly on change only.

Or ignore reporting method, just let it update an Item as and when, and on an independent periodic basis, calculate flow x time since last period, trigger from clock.

People often do the last on an every-minute basis because the result is convenient for charting.

Obviously in each case, you add the new volume-for-some-period amount to a running total, if you wish.

There may be other considerations in the choice of approach - getting periodic reports make it easier to find out when something goes wrong, the reports stop coming.

Guess that this would be the less load for my server, and the most details?

I ended up with following rule. Couldn’t test it, since my wells are empty. First time I’m eager for rain.

//------------------------------------------------------------------------------------------
rule "Regenwater verbruik 10000L"
when
        Item titoWaterFlow changed
then
        var lMin10000 = titoWaterFlowPrev.state as Number                                               //amount usuage in L/min
        if (lMin10000 > 0) {
                var now10000 = ((now.toInstant().toEpochMilli()) as Number)                             //Now time
                var item10000 = (((titoWaterFlowLastUpdate.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000) as Number)  //Get last update time
                var runtime10000 = ((now10000 - item10000) / 1000 )                                     //Time ran in seconds 
                var usuage10000 = ( lMin10000 * runtime10000 / 60 )                                     //Used water since last time
                logInfo("Water", "Verbruik 10000L : " + usuage10000 )
                var lastTotal10000 = ( titoWaterCounterTotal.state as Number )
                var newTotal10000 = ( lastTotal10000 + usuage10000 )
                titoWaterCounterTotal.postUpdate(newTotal10000)
                logInfo("Water", "Totaalverbruik 10000L : " + newTotal10000 )
                }
        titoWaterFlowPrev.postUpdate(titoWaterFlow.state)                                               //Update last state with new value
end

Suggestions for improvement always welcome.

Might be a clue this is not the best approach in your case … don’t you want it to report/confirm “zero” from time to time?

I would not worry about performance impact much.

If the pumps aren’t running, the flowsensor reads every 3 sec to ‘0’. And send this with MQTT.

Or do you mean in case of fe signal/MQTT lost?
Maybe a safety could be fe a timer to bring it every 5 min to 0, if no updated the last 5 minutes?