Timers and DateTime

Hi, i have two separate questions.

I am using timers and wanted to execute something, when a specific time is met.
is there a way to create a timer and give it a time to execute? e.g.

timer = createTimer(09:00 AM [| // or maybe with cron expressions?
    //do stuff
|)

The other question is about DateTime items. I have a DateTime item which stores its value like this:

2022-12-02T04:45+01:00

Now i only need to extract the time “04:45”. Is there a way to do this properly in a rule? something like

then
    item1.sendUpdate(DateTimeItem.getTime.state)

Is this possible in any way?

Thanks :slight_smile:

Timers are relative measures. Start the timer now, stop it after a certain amount of time and then run the code.

If you want something to happen at a specific time, then you would just trigger a rule at a certain time.

image

The actions in a rule won’t run unless the rule is triggered first. So if you were to put a specific time in a rule (if that’s even possible), you would still have to trigger the rule at a specific time. And then there wouldn’t be a point to having the time repeated inside of the rule.

Yes, you can use state.toString to convert it to a string value, which you can then manipulate and pass to a string item. I don’t know how to do that, so I can’t help you on this part. If you search on state.toString, you might find something similar in the community.

umm, I wouldn’t say that, at least in the case of createTimer() as used in rules.
Although we invariably set them up with e.g. now.plusMinutes(5), that is designating a moment in time.
We do it that way because createTimer() wants a datetime target.

So in truth you must do this.
The question is really about calculating that target time, which is really a datetime.
You’d usually start with “now” - which is itself a datetime object - and use the methods available to modify it.
now.plusMinutes(nn) is familiar
now.withHour(nn) perhaps less familiar
There are a whole lot of such methods. Other methods like
x = myDateTime.getHour
would be useful for the other part of your question.

Don’t forget when forcing a time using today’s date that the result may already be in the past.

You might find this a source of inspiration

Yes, here’s how:

item1.sendUpdate(DateTimeItem1.state.format("%tR"))

See:
DateTimeType.format which calls String.format which uses the following Format String

If you want to execute something at a certain time of the day, use the Cron trigger, not a timer.

Thank you for this answer. Inreally like to understand my rules, so can you explain in a simple way what .format(“%tR”) really does?

Please click through those links that I gave you. %tR will give you the HH:MM time that you specified. It’s explained in the format string page. I know it’s a bit long and not the easiest to digest.

I think all the questions have been answered but I wanted to summarize the different ways to schedule a block of code to execute.

Approach Used To When to use
Cron triggers trigger a rule to run periodically when polling, execute something at the same time every day, week, month, etc.
Time triggers (UI only?) trigger a rule to run at certain times every day when wanting to run a rule at the same time(s) every day with a simpler interface than cron
DateTime trigger trigger a rule to run at the date time or time specified in a DateTime Item when wanting to run a rule based on the state of a DateTime Item (the Alarm Clock post @rossko57 linked to is basically this)
Timers schedule a function to be executed at a specified time when an individual rule need to control when it’s code executes independent of triggering events (e.g. send an alert 10 minutes after a door is opened requires a Timer as there is no event to trigger a rule)

As discussed, createTimer takes an instant in time to tell it when to run the passed in function. But that instant in time can be calculated based on now. @rossko57 showed a couple of useful functions on now that you can use. @JimT showed another way to convert a DateTime to just a Time. But, that shows how one might update a String Item with just the time part of a DateTime and it’s not clear from @DivineJimmi’s post if that’s what they are after.

What’s the purpose of item1? If it’s just to show the time in a widget or on the sitemap, you can use the state description metadata on DateTimeItem to only show the time in the UI. You don’t need a rule and a separate Item just to do that.

Finally, in JS Scripting there is something almost like your createTimer(09:00 AM... example. There is a utility in the helper library that can take a time as a String a return a ZonedDateTime at that time with today’s date: time.toZDT("9:00 AM"). So that would look like:

var timer = actions.ScriptExecution.createTimer(time.toZDT("9:00 AM"), () => { 
    // timer code goes here
});

time.toZDT() can take almost anything that could be converted to a ZonedDateTime in some way and give you the ZonedDateTime from it. This includes numbers (treated as number of milliseconds from now), Items, and Strings.

But, as @JimT indicated, there are very few cases where you should be scheduling a Timer with a hard coded time like this. Use a time based trigger instead.

In addition to scheduling based on time, there are a number of time based conditions. There are a series of time and ephemeris conditions that can be used to control when a rule is allowed to run even if otherwise triggered.

Condition Purpose
the current day of week when you want to limit the rule to running on specific days of the week
between times the rule is only allowed to run if it’s between the two chosen times of day
it’s a weekday only run the rule on weekdays as configured in Ephemeris
it’s a weekend only run the rule on weekends as configured in Ephemeris
it’s a holiday only run the rule on a holiday based on the Ephemeris locale configuration
custom dayset Ephemeris allows one to define a custom dayset (e.g. weekly trash day)

Note, when using a time based trigger a rule tagged with “Schedule” will appear on the calendar view in the Schedule settings page in MainUI. I think the DateTime Item trigger does not appear but am not sure.

Thanks for the correction! I was thinking along these lines, but clearly don’t know it well enough to fully explain. I should have just left it at “use a trigger”. :wink:

What i want to do is following:
The openHAB Beta app on my android phone is sending my alarm clock time to an item. Now i want to trigger a rule everytime, that time comes.

This is why i wanted to add a timer with my time (e.g. 9 AM)
Inam trying to reduce the amount of rules, just because i like it the “clean” way.
I initially wanted to make a rule that triggers, everytime my AlarmClock item uldates (it updates everytime i activate my alarm clock on my phone)
I want this rule to create a timer that starts at my alarm time. I think there is no way, than just start a new rule with a trigger.

Maybe you can help me set up a trigger for a rule, whenever my alarm time passes.

So at the moment i am getting an item that stores “2022-12-02T04:45+01:00”
Now i want a rule, that triggers at 04:45 AM (regardless of the day). But i want it dynamically. So when i change the alarm time on my phone, the rule needs to “update” too.

Can you help me please just with the trigger right under “when” in the rules section?

Like
rule “XYZ”
when
(THE part i need to trigger the rule)

Thats everything i need. Would love to hear back from you :slight_smile:

People often go to convoluted lengths to avoid using rules, leaving themselves a system that is difficult to maintain in future. (You can at least add comments in rules for your future self - what is this for, why do it that way).
Rules are free.

You should really look at Rich’s Alarm Clock example.
You will also find other “alarm clock” type suggestions in this forum if you search.

There was some development towards using a DateTime Item as the “variable” part of a rule trigger, I don’t know how far that got.

See the Alarm Clock post @rossko57 posted for more details. In the UI it’s pretty obvious. Just choose a Time based trigger and chose “at the time specified in an item’s state” and select your alarm clock Item. There is an option to only use the time part of the Item and ignore the date but the openHAB Android app will update that Item for every alarm just a few seconds before it goes off, so you don’t need to worry about that. The Item will get updated just before the alarm goes off, with the right date, and the rule will trigger as expected.

In a .rules file see Textual Rules | openHAB.

rule "Alarm Clock"
when
    Time is AlarmClockItem
then
...

I’m not sure how to make it only use the time in a .rules file but, like I’ve already discussed, you don’t need to. The android app will update the Item every day just before the alarm goes off.

Thank you. I am currently not on my PC and have to answer via mobile browser.
I could not believe, that this is so easy. Thank you very much. Will implement this soon. You are a big help to me :heart:

Until recently it wasn’t this easy. In fact, I’m not 100% positive that it’s available on OH 3.3 release. It might be something up and coming in OH 3.4 so you might need to update if you find that the Time is <item> trigger doesn’t work.

DateTime trigger was included in 3.3

1 Like

I introduced the timeOnly keyword for that, so

rule "Alarm Clock"
when
    Time is AlarmClockItem timeOnly
then
...

should work. However, that is a 3.4 feature so you will have to wait just a little bit longer.

1 Like

It’s not in the docs though. I figured there was something but it’s not in the docs and I didn’t have time to look in the code.

Indeed, I’m not entirely sure what happened there and why it wasn’t documented. Anyways, I created a PR for proper documentation. Glad that it was noticed before the release of the new version.

1 Like

so does the timeonly make it work like cron, i.e. it will trigger every day instead of one time? If so, that too needs to be clarified in the docs.

timeOnly makes it ignore the date portion of an item.