Dynamic Expiry Best Practice

I have a few cases where I want to turn on an item, then turn it off a bit later, based on information at the time that it’s turned on. My current example is with water sprinklers, which I want to turn off early based on recent rainfall.

Currently I do this with:

  • A rule which turns on the item, as well as setting a timer to turn it off
  • Another rule which turns it off at the maximum period (i.e. dry conditions)

This seems like it works, however has a redundant extra rule, plus will forget the timer if OH were to crash and restart (at least I believe this to be true, I assume it’s not persisted). Hopefully the backup rule would fire, although not if it had already passed.

Is this the standard approach here? Or is there a mechanism to create durable (temporary) rules that should be preferred, or that would also trigger upon restart if the time had passed?

Thanks

If it’s really important to turn off those items (Lossing water because of bug system openhab stopped etc) it will be best to see if the actuator you are using to turn the valves on has a hardware timer build in). Check that otherwise there are other solutions but again you depend on openhab to be somehow in a working state.

On my tasmota devices i use the the pulsetime comand to set the time how long the relay should be on. So openhab only turns on the relay and turning off is handeled by the node. This way it‘ll also turn off again if it looses connection or openhab restarts after the relay was turned on

Actually, these water valves are controlled by tasmota - so I will certainly use the PulseTime option! (I think I already have a rule in there which will limit the overall time.)

Is there no other option for devices which don’t have this capability? I am thinking that an at-least-once timer that survives restarts may be something that I’ll add if it’s not already available.

The only simple built-in way a timed rule like this is going to still work after a reboot is if you are using the time of an item trigger. If your starting rule sets a DateTime item to the time you want the stop to happen and the state of that item is persisted with restore in startup then the stop rule (or the same rule with multiple triggers and logic to determine which item triggered the rule) will run at the time as long as OH is running regardless of what has happened in between.

This is true. No timers nor Expire survives a crash or restart.

You could implement it in one rule but I also understand that’s not really the point.

Something akin to @JustinG’s approach is your best bet with what’s built into OH right now, though depending on which persistence engine and strategies you are using (it won’t work with rrd4j for sure) you might be able to use lastUpdate from persistence instead of creating another Item. You’ll still need the System Started rule though to see if we have reached the end time or not.

In cases where the requirements are loosened you have some simpler options. For example you can just shut everything off on system started or you can start the timers anew.

But as mentioned, it’s always better if something like this can be implemented in the device. You can’t guarantee that OH will come back up in a timely manner.

I’m not sure how easy it would be to create persistent timers in OH. There is certainly no mechanism to support them now. But it sounds like a good idea to me. In fact I’ve toyed with the idea of adding a feature to OHRT to support them but never had the need myself so it’s remained a low priority.

I’m not sure how easy it would be to create persistent timers in OH. There is certainly no mechanism to support them now. But it sounds like a good idea to me. In fact I’ve toyed with the idea of adding a feature to OHRT to support them but never had the need myself so it’s remained a low priority.

I am certainly considering adding this. It would be tough to do this like timers, because they rely on in-memory state (via a closure when running in a script engine). To survive restarts everything needs to be serialisable. I’m thinking that the simplest path would be via a new trigger type - similar to CronTrigger, but with a single point in time (and if this is detected as already passed, e.g. at startup, it would also trigger). This side-steps the whole persistence problem as the code would need to be part of a rule which is already handled. The way it would actually be used would be to define a rule with no triggers that (in this case) turns things off, then attach one-shot triggers to it when required (I guess the triggers could also be parameterised to allow some state passing to the rule code).

I’m sure that some higher-level constructs on top that make them feel more like timers would be fairly straightforward.

There already is a Time is <item> trigger so this would be more of a change in that trigger than a wholly new trigger. Just don’t make it always trigger if the time has passed on a reload. One doesn’t always want that (e.g. alarm clocks). It needs to be an option.