OH 2.x Timer Things

Just to add to the wish list, since it crops up as “how do I…” from to time -

Ability for a rule to read back unexpired time (or target timestamp, since one can be calculated from the other) from an active timer umm Thing.

I wonder how exploitable the discvery mechanism is, which allows bindings to create new Things. This would require the invention of a rules-based means to prompt the creation. Perhaps that would take the form of -
I want to use a timer Thing named XXX. If you haven’t got one, make one.

There is a cron binding for absolute times. Off course someone has to port it to OH2, but it falls into the responsibility of the cron binding, not the proposed one.

Ok, never hear of it. Could you point me to it, please. It is not in the PaperUI.

I’m confused, in what I talked about and what everyone else seems to be talking about solving the islamic prayer time problem involves one repeating timer and a triggered rule. The repeating timer fires every morning before first possible prayer time and repeats every day. It triggers a rule that calculates and creates single event timers for each prayer time. How is that complicated?

I also realized after I said it that the idea of returning handles is a bit alien to this project and so probably there needs to be a way to pass a name while creating a times so it can be accessed again in the future. that seems to be a better fit for this project.

Ira

It is complicated because there is no such think as a timer of any type right now thus this thread to discuss different proposals of how to introduce timers.

That is why my proposal wants the user to create timers beforehand (as channels so they have a unique channel id).

This isn’t too far from my understanding of how the Quartz scheduler in Rules DSL, which is how Timers work there is implemented. There is also a thread pool though because you can and will have multiple Timers that expire at the same time or while another Timer is actually executing (as opposed to waiting to execute) so when it comes time to execute the body of a Timer that happens in another thread.

Look at some of the links I have below for common uses of Timers.

Perhaps. But I’m coming at it honestly. There are a whole bunch of common problems users need to solve and I’m coming at this from the perspective of “today I solve problem x using a Timer to do y, how do I solve the same problem in NGRE without a Timer that persists?” which leads to “how do I create a Timer that does this.”

I’m very open to alternatives, so long as all the problems that we can currently solve using Timers have a solution and that solution is not significantly more work than what we can do today.

Some example uses for Timers in Rules DSL include:

There are more but these are the ones based on DPs I’ve written.

I would add a “Repeat rule with y delay until z condition is met” though I suspect rules will be involved to achieve that.

As long as these scheduled events can be cancelled and rescheduled from a rule I think that covers it.

I think that would cover the what. It’s the how that I’m more concerned about though which may be me getting too far ahead.

Yes, it comes up from time to time. Though we can probably work around it.

One thing I want to be careful of though is we don’t want to make decisions that will make it harder for developers to write Rule templates and libraries. Ultimately, we want to get to a point where non-technical users are not writing Rules at all but installing pre-written ones from PaperUI. And in that case, the code inside the Rules will not be able to know ahead of time how many Timers are needed or potentially what they are called.

Ever, on each run of OH, or each time it is executed? I think I need more to understand what you are thinking with the repeat times. This isn’t actually a use case that I’ve seen come up before. Usually when one wants to repeat a timer’s execution it is until some condition is met. I’m intrigued by the idea of a repeat times but I’m not sure how it could be used just yet.

So are all of these configurations Channels I can link to Items? Otherwise how do I kick off a Timer in response to some event? If enable is a Channel I can link to an Item, are the rest of the configuration parameters also Channels I can link to Items?

From a usability perspective though this is starting to look like a lot more work. Right now from one Rule I just need:

myTimerMap.put(triggeringItem.name, createTimer(now.plusMinutes(5), [ | // do stuff ]))

My best understanding of the proposal means I now need to:

  • Create a Thing for every Timer I may ever need
  • Create 2-4 Items that link to the various channels of the Timer so I can enable/disable/reschedule/adjust parameters from a Rule
  • Create a new Rule triggered by the Timer’s trigger Channel which is where I put // do stuff. Of course, the context that I would normally have in the timer body (i.e. all the variables that existed when the lambda was create gets persisted in the lambda so I can, for example, reference triggeringItem inside the timer’s lambda) and all that will be lost in this separate Rule

It feels like a lot more work clicking together a bunch of Items and Things and I’m losing just a little bit of capability. But I think this might get us 75%-80% there.

This is an area that needs some more exploration. How do I keep track of these IDs? If I’m going to enable/disable/reschedule the timer by ID from a Rule then I need some way to associate the Timer ID with events from a given Item in a Rule. If I’m going to write generic Rules, I can’t hard code this ID into the Rule. So how would that work?

How many of the parameters can be configured through the create timer Action? All of them or only create one with the already preconfigured parameters on the Thing?

I guess I’m just a little confused how this all would work together. I like all the ideas independently but as I think about how I would go about using it I can’t figure it out. I’m sure I’m just missing something.

I can see a couple of usage scenarios:

  • Create a new Timer channel for each Timer you will need and set all the configurations for each, including the ID. In a Rule, when it is time to trigger a Timer, I sendCommand to an Item linked to the enabled Channel for that Timer. I have another Rule that gets triggered by the trigger channel when the timer expires. How does the Action work in this usage?

  • In a Rule I know I need to create a Timer. I use the create a timer Action to configure and schedule the Timer. I have a Rule that gets triggered by the trigger channel. How do I know what the trigger channel is to create this Rule?

I love this, but one thing I haven’t figured out yet is how to execute another Rule from inside the Script of a Rule? Sometimes deciding whether or not you need a timer, and especially to cancel a timer depends on the results of a bunch of other calculations.

One concern I’m having with the NGRE over all is the logic is becoming dispersed all over the place. There won’t be any way to just look and see everything all in one place. I’ll have at least two Rules with logic split between but only if and actions. If the only way I can use Delay rule is by the Execute rule Action and I can’t use if from inside my Script Action I worry about maintainability. Perhaps with Yannick’s UI this won’t be as big of a deal but with PaperUI I have real concerns.

I think that is what David’s Execute on date/time x is for. In that case it would repeat exactly once at the specified date and time.

Wouldn’t one do this through a Rule trigger instead of a Timer?

In my mind Timers are used to schedule something to occur in the future based on some event, like a door opening. It seems awkward and out of place to implement cron type expressions using Timers. Though perhaps there can be synergies reached if both types of scheduling are merged…

But the “separate binding” is actually what we are talking about here. Essentially we are talking about a 2.x replacement for Timers in Rules DSL and the 1.x Expire Binding. I think you are talking about Time cron "..." Rule triggers.

That is also something that is mostly missing from the NGRE and needs to be addressed but not what we are discussing in this thread.

That is what we are working through.

And actually so long as you don’t have to reaccess the Timers to reschedule or cancel them from some other Rule the NGRE handles this now. The missing part is that there is no way to persist any variables from one run of a rule to the next or across rules. So we can create Timers but as soon as the Rule exits so do the references to the created Timers. But the Timers are still there scheduled in the background.

In short, I don’t think you have anything to worry about. And this thread is to make sure you have nothing to worry about going forward.

Correct, which is what Vincent currently uses. He executes a perl script to calculate the times (IIRC) then creates a Rules DSL Timer to execute a function at the calculated times. In this thread we are trying to come up with an OH 2.x NGRE approach that preserves the ability to continue doing this (and other Timer use cases).

Shouldn’t be hard to get that from a Channel on the Thing.

I was not clear enough, I guess. The trigger channel is THE one and only available channel but it has multiple configurations, like Thing configurations. You are not creating a single item at all. Trigger channels are directly supported by the rule engine.

To modify a timer, you would alter the configuration value of the destination timer. It is not possible with the currently available actions of the NRE.

Just trying to understand. Is the trigger channel the same as a trigger in the new rule engine? And can’t these timer kinds be implemented as different new trigger classes and as such become available for the user?

If I’m understanding you correctly, this means from a Script Action I cannot enable or schedule or cancel or reschedule a Timer?

I don’t like that at all.

Maybe I’m jumping the gun, but how would I implement, for example Motion Sensor Timer DP above?

In this case the motion sensor generates an event, I schedule a timer, subsequent events reschedule the timer further into the future, and only after X minutes after the last motion event does the timer go off. To add a wrinkle, let’s say I want to use a different X minutes for the timer during the day and at night.

Maybe a concrete set by step would help me see how this could work.

1 Like

I have created an issue:

1 Like

Seems overly restrictive.
A substantial proportion of uses for current createTimer() rely on being able to detect in a rule if a timer is already running or not.
A fair proportion also require rescheduling, although that could be fudged with a cancel/restart approach.
An improvement over current timer would be a means to readout target or unexpired time.

These could be fairly easily supplied by a few channels per timer-Thing.

The hard part about this approach is how to interface to these channels from rules. Preferably without the faff of pre-declaring a multitude of Items. Or is that the key to success, having a more fluid environment of dynamical created Items?

Rule calls/creates timer Thing with name XXX
Items XXX-running , XXX-timestamp , XXX-trigger or suchlike are automatically conjured up.

I’m unfamiliar with new rules environment - does/will it allow use of channels directly? (avoiding Items altogether)

So some clarity. For me anyway. I’ve only been using OpenHab for a few weeks so my knowledge is limited but this thread is certainly opening my mind to possibilities.

Effectively at the moment rules can be timers because they can be triggered at some time in the when clause.

It seems like what might help is a timer class which has a rules like file but instead of a when clause, they just have a name so we effectively have a bunch of named rules that can be triggered by the timers firing or I guess also potentially called by name by other routines.

Ira

Not quite.

Right now Rules can be triggered by time using a Cron expression. These are not Timers and not what we are talking about, that I’d also a need in the Next Gen Rule Engine.

Timers are something else. Right now in the current Rules DSL we can schedule a little chunck of coffee to run at some time in the future inside a Rule. Once created, we can cancel or reschedule the Timer as needed.

Unfortunately, creation and user of Timers in this way is not possible in the NGRE. This thread is exploring how to bring this capability to the NGRE using OH 2.x concepts.

OH 2 is quite different from OH 1 and the NGRE is quite different from the Rules DSL.

Not to sound daft, but what are NGRE and DSL? And FWIW, I’ve never seen OH 1 so all I have to go on is past languages and my feeble attempts to learn OH 2.

Ira

Rules DSL, Domain Specific Language. The default language rules are written in. It has been around for a very long time and is loosly based on the obscure XTend language.

The Experimental Next Gen Rules Engine (NGRE) will eventually replace Rules DSL. It is structured very differently but it supports more standard languages like JavaScript and Jython.

The topic of this thread is figuring out how to bring functionality that exists in the current rules DSL to the up and coming NGRE in a way that makes sense given the underlying architecture, conventions, and artifacts that make up OH 2.

I’m not so sure that taking what we might call cron-style rule triggers out of the discussion is right.

There are two different time related needs;
Do something (run a rule) at scheduled times e.g. on the hour
Do something (run a rule) at arbitrary times e.g. in ten minutes time

Plus of course means to manage the timers

The arbitrary version is really just scheduling plus a run-once condition.
Seems likely to be driven by the same mechanism, even if there are two or more ways to control it.

I see current ‘expire’ binding as just a shorthand special case of the arbitrary timer, with “Do something to this Item” and hidden rescheduling.

I agree that there needs to be a lot of new work on scheduling on OH and perhaps using the same infrastructure for creating Timers from Rules and cron type triggers would be appropriate.

But I’m not sure forcing ALL scheduling through Things is necessarily a step forward. Would you rather set up the cron expression as a trigger, with a nice UI form that helps you build the expression, or would you rather have to create a new Thing on a different UI page and trigger the Rule based on the command channel of the Thing?

One of the concerns I have already is that the NGRE is already going to diffuse code that we are already used to being all in one place all over the place. Moving Rule scheduling to Things only exacerbates that.

However, if that can be the first step towards building a better scheduling service into OH that can support modifying of the schedule from the user’s UIs I can live with that trade.

I will admit that I’m a bit myopic right now in my view of NGRE and how to move forward with it that I’m failing to see a lot of the benefits that the new way enables. I’m mainly seeing functionality that we are losing.

The Thing -> Channel Timers were just a first proposal.

Personally I’m now convinced that a dedicated framework sub-component like the current rules timer scheduler with its own REST API endpoint and PaperUI section is a better choice.

I’m liking this idea better as well. I got excited when I read about it in the Issue. I can see all sorts of opportunities a separate service like this can enable.

Maybe an approach is to instead extend that kind of process to arbitrary timers as well.

e.g.
Rule trigger condition → TimerABC → option = periodic cron-type setup
Rule trigger condition → TimerXYZ → option = when timer ends

Another rule starts TimerXYZ Some other rule can cancel/reschedule

If timers are Item-y in this way, perhaps they could also be Group-y for shared code purposes. More I think on it, more it feels like a viable way to manipulate timers from rules is to have them act a bit like Items. Send commands, read “states”.