Options to pause rule execution? OH3 WebUI

Hi!

Is there any option to create a timer without scripting in OH3?
While defining a rule I think there should be a straightfoward “delay execution of rule by … (seconds|mintues|etc)” item in the list of Add Action dialog.

There are already some options dependent on bindings (e.g.: zoneminder, mqtt, astro, etc). I think expire binding (or a new timer binding) should provide and action like that. Or even better if core actions list that.

Note: I know that I can write a rule for that. And I’m avare of that I can define an Item with old expire binding to fire another rule to delay script. But this add clutter to items. This addition should be a very convenient way for noobs/no developers to be able to pause execution.

Regards,
Zsolt.

Expire is now a core functionality for Items.

I’ve found in Add Metadata → Expiration Timer. (Just for future reference).
Thanks.

1 Like

Documentation posted by Kai is here.

Yes, I found that earlier and thought it is for textual definitions only. I’m trying to use and learn OH3 as codeless (mean: simple) as possible. Somewhere in the manuals it should be described how to use expire in OH3 with tags. I could not find it in forum within the revised documentation series (and I was not sure if it exists - I read before that it was dropped) only after your reply.

Thanks again.

I did not know of the docs before this week when Kai posted.

IMO there should have been the start pf official documentation available from the developers before Milestones were released. They are, hopefully, the experts on how to use their code.

Just a note on that. None of those are functional. I’ve already opened an issue to either fix them so they can be used or remove them from the list.

Right now all binding actions get added to that list (whether it makes sense or not, e.g. the astro actions don’t make any sense to use as an Action) but there is no way to set any of the arguments that get set to action. So, for example, you can’t specify the topic or message if you choose “publishMQTT” as the Action.

But going down this idea a little further, as Bruce has pointed out, Expire is already built into the core now. And it’s use is essentially identical to what the old 1.x binding was only you don’t have to install a separate binding. But I actually don’t think Expire is a good fit for what you are originally asking for.

I actually do not have too much experience with rules that have more than one Action. Some important questions to answer are:

  • do the Actions run in sequence or in parallel? I’m pretty sure it’s in sequence.
  • if in sequence, do they run in the order listed?

Only if the answer to the first is that they run in sequence and the answer to the second is they run in the order shown in MainUI would setting a “delay” Action make sense. I wouldn’t want to call it a Timer because that’s not what it does.

But note that this will not delay the execution of the rule. It will block the rule from continuing to execute the next Action in the list for a given amount of time. Also note that while the rule is running (i.e. it’s being delayed) no additional instances of the Rule can run. So if you have the rule delayed for 20 minutes, and the rule gets triggered again, you’ll have to wait for the 20 minutes to expire before that second trigger starts to process.

Given that, I could see some use cases outside of Expire where it might make sense to be able to insert a delay between the Actions of a Rule. I’d recommend filing an issue on the openhab-core repo as a feature request.

2 Likes

Hi!
I filed an issue. My first one so I hope it is OK. I could not find a way to label it as enhancement but I think I don’t have rights to do it. Thank you.

It was filed against the core instead of the UI. I do not know how to change that.

For an example of this, when I leave the house I have a one-minute delay before my hall light turns off (so that I don’t exit the house in total darkness) and a five-minute delay before the house goes into “Away” mode (so that I can come back in if I forget something).

And when I go to bed, I use createTimers to have individual lights turn off in half-second intervals, so that it feels like they’re shutting off behind me as I walk to my bedroom. It’s a very silly thing that feels extremely satisfying.

2 Likes

Do you throw your hands up in the air as you walk off into the distance in slow motion with the lights switching off one by one?!

I think I’ve found the next thing I can annoy my partner with…

1 Like

He filed it in the right location. That will have to be implemented by the automation engine which is located in the core.

For something like this written a reusable library that people can use called debounce. You can create a proxy Item and add some metadata and it will hold onto a command/change to an Item until a certain amount of time has passed before passing it to the configured proxy. Ive a Jython and YAML (OH 3) version available at GitHub - rkoshak/openhab-rules-tools: Library functions, classes, and examples to reuse in the development of new Rules..

I think there is now a debounce Profile as well, but of course that only works with Items linked to a Channel.

I use this all over the place. My presence detection rule has been completely replaced by this.

I can’t say if this would be useful but I want to bring it up as the sorts of rules capabilities you will be able to just download and use going forward instead of needing to copy from the forum and adapt.

For the lights timers I’ve create an implementation of the Gatekeeper DP which would be perfect for that. In your rule you can just have something like:

from community.gatekeeper import Gatekeeper

gk = new Gatekeeper(logger)

    # Inside a rule, add a command to the queue and prevent another command until
    # a second after this command runs.
    gk.add_command(".5s", lambda: events.sendCommand("Light1", OFF))
    gk.add_command(".5s", lambda: events.sendCommand("Light2", OFF))
    gk.add_command(".5s", lambda: events.sendCommand("Light3", OFF))
    gk.add_command(".5s", lambda: events.sendCommand("Light4", OFF))
    # putting the above into a loop is an exercise for the student

NOTE: I’ve not yet implemented a JSONDB OH 3 version but it’s high on my list.

Notice the use of “.5s” to denote the time for when you want the timer to go off. I’ve implemented a timer_mgr class that greatly simplifies the creation and management of Timers. And I’ve created a time_utils library that lets you convert all sorts of stuff to a ZonedDateTime needed by createTimer so I can schedule a timer like:

timer_mgr.check("ItemName", "2m5s", func=runme) # if it doesn't already exist, create a Timer with "ItemName" as the key to go off in two minutes five seconds and execute runme, cancel the timer if it exists
timer_mgr.check("ItemName", 1000, reschedule=True, func=runme) # if it doesn't exist, create a Timer with "ItemName" as the key to go off in 1000 msec and execute runme. If it does exist reschedule it.
timer_mgr.check("ItemName", items["MyDateTimeItem"], flapping=runme2) # if it doesn't exist, create a Timer with "ItemName" as the key to go off at the instant defined by the state of MyDateTimeItem. If check is called again while the Timer still exists, call runme2
timer_mgr.check("ItemName", items["MyNumberItem", func=runme) # same as first example only the number of milliseconds is defined by the state of a Number Item

Anway, what the above rule does is send a command to Light1 and then it will wait for half a second before the command is stent to Light2 and so on. The time passed is how much time must pass after that command runs before the next one is allowed to run.

This is a great way to set up cascading timers too as you can just send all the commands all at once to the Gatekeeper and it will do the timing stuff for you.

It’s this sort of stuff that has me excited about rules in OH 3. I’ve done all the work and all you have to do is download and use them.

As of this writing I’ve only ported ephem_timeofday, timer_mgr, time_utils, and debounce to OH 3 JSONDB rules or libraries. I’ve implemented but not yet posted rate_limit (it’s like gatekeeper but instead of queueing up the commands and sending them all but a certain amount of time apart, it drops any additional commands sent to it, useful for doing things like preventing a given alert from being sent to you more than once a day).

For an example of how these can simplify your rules, here is a rule I have that sends me an alert when the humidity gets too low in one of the rooms where I track humidity. I use rate_limit to prevent the alert from being sent more than once a day even if the humidity bounces around the threshold.

var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.Rules.Humilert");
this.OPENHAB_CONF = (this.OPENHAB_CONF === undefined) ? java.lang.System.getenv("OPENHAB_CONF") : this.OPENHAB_CONF;
load(OPENHAB_CONF + "/automation/lib/javascript/community/rateLimit.js");
load(OPENHAB_CONF + "/automation/lib/javascript/personal/utils.js")

this.rateLimit = (this.rateLimit === undefined) ? new RateLimit() : this.rateLimit;

var sendAlertGenerator = function(msg) {
  return function() {
    sendAlert(msg);
  }
}

var name = getName(event.itemName);
this.rateLimit(sendAlertGenerator("Remember to fill the humidifier in " + name + ", current humidity is " + event.itemState + "."), "1d");

I don’t even have to think about the timers. It’s amazing how freeing that is. Note getName is defined in my utils.js and it returns the value of a name medata on the Item. Similarly sendAlert is a function that sends an OH notification during the day but an email at night.

1 Like

I don’t, but tonight I’m going to attempt to point at each light as it turns off so that I feel like a Jedi.

I am also excited by this. Particularly since I bailed on electrical engineering in the 90’s specifically because I hated programming…and also because I’m red-green colourblind and couldn’t read transistors. Seemed like an electrical fire just waiting to happen.

I have something more as a midnight idea. All action should have two properties defined. Run mode - parallel and sequential -, and a delay time. Just like powerpoint animations. With this there is no need for a separate delay action. As far as I know - without any deeper knowledge of - the oh framework has an event bus and there must be some governor or marshall that executes these. It should take into account when the action appeared on the bus - timestamp all parallel action - start delay timer if appropriate. And sequential actions should be chained each after, again with a proper timer started if delay exists. Default mode should be sequential with zero timer.
This is I think is a major change in the framework, but is a huge advantage for simple users who is familiar with PowerPoint already…

Hi Rich,

do you know if there is already an update on mentioned questions in quote?

I’ve not had a chance to test it. It appears that they run in sequence one at a time for Conditions. I would assume the same is true. Anyone who cares to find out the answer can set up a test as easily as I can. Just create a bunch of script actions with log statements, maybe with some sleeps. If the logs are printed in the right order with the right amount of time between them you have the answers.