OH 2.x Timer Things

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.