Rule structure suggestions/approach for activating waterflow switch to fill pond (daily specific amounts)

Hi,

I have a koipond which I like to (re)-fill on a daily basis, probably about 1,000 liters/day. I have a KNX watermeter and water-actuator connected, so I can activate the flow and read out the flow/amount values.
I’m trying to think of the best way to create a set of rules in openhab to manage the whole thing. One of my main questions/scenarios would be:

I’d like to start a fill around 6am for let’s say 300 liters , then the same at 12pm, and at 6pm. (for those who wonder, I don’t like it to trickle since it’s connected to a waterpump which would be running all the time otherwise). Then I want a button which would do a manual fill for another 300 liters.

My main question is, would you create a rule that starts a fill at 6am, and in the rule you create a loop that checks it value is reached and stops the fill and ends the rule?

Or is it a better approach to spread it out over several rules: a rule start the process (e.g. 6am) and another rule that takes care of stopping when the daily var has reached a specific value?

I’d think the first approach looks cleaner but haven’t used loops yet in any rules, and my rule would run for half an hour or so.

thanks
philippe

It is usually a bad idea to block, sleep, or otherwise have the rule continuously running because it ties up an execution thread and if you have too many such rules you will end up running out of threads and all rules will stop responding until the long running rules exit.

So I would recommend spreading the behavior across multiple rules if necessary. Something like:

var Number targetMeter = -1

rule "Pond filling"
when
    Time cron "0 0 6,12,18 * * ?" or // double check this cron expression, I'm just typing
    Item ManualFill received command ON
then
    targetMeter = WaterMeter.state as Number + 300
    WaterPump.sendCommand(ON)    
end

rule "Stop pond pump"
when
    System started or
    Item WaterMeter changed or
    Item ManualFill received command OFF
then
    var pumpState = ON
    if(targetMeter < 0 || WaterMeter.state as Number >= targetMeter) pumpState = OFF
    if(triggeringItem.name == "ManualFill") pumpState = OFF
    if(WaterPump.state != pumpState) WaterPump.sendCommand(pumpState)
end

I make a whole lot of assumptions above (e.g. the water meter always grows forever instead of being reset daily) and if OH restarts we always turn off the pump. You will also want to add all sorts of error checking and logging and such and think about edge cases (e.g. what happens when everything loses power, what happens when the water meter only loses power, what happens when OH loses power, etc).

If you want to have the pump resume or continue running after an OH restart you can replace the global var with a persisted Item and instead of just shutting off the pump in the system started rule check to see if the level has reached that level before the restart and if not start the pump again.

Personally, to me, this looks way cleaner than a do while or for loop in a Rule. You only have two rules, you are not blocking waiting for the pump to complete, and you have at most one level of nested contexts, and you would need two rules anyway if you use a blocking polling loop because you need a way to turn off the pump manually.

Thanks Rich! Very clear!

I’ll get cracking now. :slightly_smiling_face: