Creating Capabilities with Rule Templates: Time of Day

Sounds like a good plug-in we should look into.

Not at all. I am frustrated because I’ve already spent a good deal of time here trying to understand what you don’t understand but I’m not fighting against you. I just wish you would give me more details and less complaining. I can’t help you if I don’t know what you don’t understand. No one can. And you’ve given no details, just disconnected questions and complaints about how hard the docs are to understand.

I’m not telling you to just go read the documents.

I’m trying to figure out what I can clarify for you and maybe learn some things that can be improved in the documents. But you are giving me nothing to work with. I could just regurgitate the docs here in a forum reply which probably won’t help you at all, or maybe you could help me to narrow down those key concepts that you don’t understand and that you are having difficulty with so I can provide more detailed or alternative explanations that might be more clear to you.

But there is one thing that is absolutely true about openHAB. You can’t not use the documents. You can’t just jump in and do stuff and hope to figure it out by doing, at least not without some basic understanding of the basics. And that seems to be the big hold up right now.

At some point you posted a question along the lines of “how do I use the DateTime from Astro?” That question shows a significant lack of understanding of what an Item is, what it does, and how it’s used by openHAB. Ideally I’d want to get from you what your understanding of what an Item is as you understand it so I can correct where necessary and fill in the blanks. The same is needed for Things, Channels, and Links.

These are the three core concepts that you need to understand. If you don’t understand those, you won’t be able to understand anything else in the docs.

2 Likes

@rlkoshak I was following along on this post to set this up but when I go to build my rule to instantiate time of day using the schedule a timer to run a script button I don’t get that option I only get the move tagged DateTime items to today’s date see below

I just installed the binding and am running on OH3.2.0.M4.

Any suggestions of troubleshooting paths I can take to get this working?

If it doesn’t show up it didn’t install. Did you watch the logs when you added the Alarm Clock Rule template? Does the Alarm Clock Rule template show as added in Settings → Automation?

@rlkoshak You called it for some reason it didn’t install. Thanks for catching my mistake! Appreciate the work you did on these!

Hi @rlkoshak, I’m finally getting back into OH after a couple of years enforced covid related hiatus and have upgraded my system to OH3.2 and have found my time of day rule needs upgrading to the above.

I’ve followed it all and happy with the process, the question I have is on a way to deal with sunrise v fixed time at certain times of the year.

For example, my ‘DAWN’ starts at sunrise, my ‘DAY’ starts at 7am, and rules fire based on this.

My issue is that for around 4 months of the year here in the UK, Sunrise / DAWN is actually later than 7am so rather than TimeofDay = DAWN and then transitioning onto DAY it is the other way round which plays havoc with my rules.

In OH2.5 rules I had a if(dawn_start.isBefore(day_start)) then else statement which determined whether to have a DAWN or just move straight into DAY. Before I do some re-writing of rules, is there a way in this example to tell the system to do something similar?

TIA

The easiest is to set the latest property on the Astro dawn channel you are using. That will prevent the Item from ever becoming anything later than that time.

You could set the latest to 06:59 and DAWN will occur no later than one minute before DAY. I worry if set it to 07:00 it will be a race condition to see whether DAWN or DAY happens first.

If you want to suppress DAWN entirely when it’s after 07:00, then add that check to the script that is called by the Alarm Clock Rule Template. You can add that as a condition in the but only if on the called script (i.e. don’t run the rule if TimeOfDay is already DAY) (assuming you have a separate rule that’s called per time of day) or you can add the logic to the Script Action of that rule to no do anything.

You wouldn’t be rewriting anything from the rule template. You’d be customizing the code called by the rule template, which is the whole intent.

Note, that I actually recommend using Time Based State Machine to drive time of day for most users since it has built in the ability to have different times of day based on the type of day (e.g. weekends, holidays, etc.). In that case you’d still have this Alarm Clock rule template drive the DAWN state and use the condition to not do anything if TimeOfDay is already DAY.

Hi Rich,
I have recently upgraded from OH2.5 to OH3.2.0 Release Build.
This is running on a Ras PI 4 8gb using Openhabian.
I have influxDB installed.
I implemented ToD rules template and managed to get it all working after a few typos.
Today I rebooted the PI to see if the persistance was working as it should, and received 3 errors in the log referring to three of the ToD managers.

2022-05-02 16:25:05.512 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'todAfternoonMgr' failed: TypeError: Cannot read property "class" from undefined in <eval> at line number 30
2022-05-02 16:25:05.629 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'todDayMgr' failed: TypeError: Cannot read property "class" from undefined in <eval> at line number 30
2022-05-02 16:25:05.629 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'todEveningMgr' failed: TypeError: Cannot read property "class" from undefined in <eval> at line number 30

This is the line of code in the rule at line number 30

if(time.class != type || time.getZonedDateTime().isBefore(ZDT.now())) {

Here is the rule that was generated while implementing Time of Day according to your description/process outlined above.

if(typeof(require) === "function") Object.assign(this, require('@runtime'));
var FrameworkUtil = (FrameworkUtil === undefined) ? Java.type("org.osgi.framework.FrameworkUtil") : FrameworkUtil;
var ScriptExecution = (ScriptExecution === undefined) ? Java.type("org.openhab.core.model.script.actions.ScriptExecution") : ScriptExecution;
var ZDT = (ZDT === undefined) ? Java.type("java.time.ZonedDateTime") : ZDT;

var logger = (logger === undefined) ? Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.rules_tools.Alarm Clock") : logger;

this.timer = (this.timer === undefined) ? null : this.timer;
var time = items['LocalSun_StartTime'];
var item = 'LocalSun_StartTime';
var script = 'todTransition';
var callScriptGenerator = function(data, script) {

  return function() {
    logger.debug("About to call script action");
    
    // Get the RuleManager
    this.ScriptHandler = Java.type("org.openhab.core.automation.module.script.rulesupport.shared.ScriptedHandler");
    var _bundle = FrameworkUtil.getBundle(ScriptHandler.class);
    var bundle_context = _bundle.getBundleContext()
    var classname = "org.openhab.core.automation.RuleManager"
    var RuleManager_Ref = bundle_context.getServiceReference(classname);
    var RuleManager = bundle_context.getService(RuleManager_Ref);
    RuleManager.runNow(script, true, data);
  }
}

// No alarm scheduled
var type = (typeof(require) === "function") ? DateTimeType : DateTimeType.class;
if(time.class != type || time.getZonedDateTime().isBefore(ZDT.now())) {
  logger.info("No alarm scheduled for " + item);
  if(this.timer !== null) {
    this.timer.cancel();
  }
}
// create or schedule a timer to run at the configured time
else {
  logger.info("Scheduling alarm at " + time + " for " + item);
  
  if(this.timer !== null) {
    logger.debug("Rescheduling alarm for " + time);
    this.timer.reschedule(time.getZonedDateTime());
  }
  else {
    logger.debug("Setting a new alarm for " + time);
    var map = new java.util.HashMap();
    map.put("triggeringItem", item)
    this.timer = ScriptExecution.createTimer(time.getZonedDateTime(), callScriptGenerator(map, script));
  }
}

Would you have any idea what I could have done wrong here as my level of javascript is still at beginners?

This is my first post and first attempt at using code fences etc. so please let me know if I have made any fundamental errors?

Add a logging statement to the rule to log out time. I suspect that for some reason LocalSun_StartTime doesn’t exist at the time when the rule ran. Did the rules run again a few seconds later?

Thanks very much for your valuable input.
I traced through the logs and found that the three items relating to the errors were missing from a certain point in time which related to me removing them from the ‘model’ and adding them again with the ToD_DAY format to get the transition rule to work as it had been splitting the item incorrectly as per the entries below.

[openhab.event.ItemStateChangedEvent ] - Item 'TimeOfDay' changed from BED to Rise
[openhab.event.ItemStateChangedEvent ] - Item 'TimeOfDay' changed from Rise to StartTime
[openhab.event.ItemStateChangedEvent ] - Item 'TimeOfDay' changed from StartTime to Set

I am presuming that all worked after changing the items as the timers were all running and I only noticed the issue in the log after the reboot.

I am wondering if adding the local sun as equipment into the model messed with the item names.

I will now go through your setup process after removing and adding the local sun again without using the model.
I will post an update once I have finished.

On another topic, in the UI rules, how would I do a replace on multiple special characters, a [ and ] (I want to remove them). I can do it using regex with normal characters but couldn’t find anywhere to assist with these characters. My rule has a replace line for each of the characters which works fine but would love to simplify it. I am using a tag in a proxy timer item to give me a link to the correct item to process.

Once again, thanks for your assistance, greatly appreciated.

The names of Item are independent from the model. The model only works with tags and Group membership.

To use a regex on characters that have special meaning to the regex, you need to escape the character: \[, \], etc. But, because you are running a script and these characters also have special meaning in the script, sometimes you have to double escape them: \\[, \\], etc.

Or you can just use mystring.replace('[', '');.

Hi Rich, thanks for your input.
I found that the three manager rules for the astro events had the incorrect items so deleted them and added them again and the ran the rules without any errors. I now have to wait until tomorrow to see if they are working ok.

Regarding the regex, I tried all types of combinations to get it to work, either side of the square bracket, [ or ], and any other character worked ok but the moment I added both sides of the square brackets it only did the one. I’ll stick to the 2 step as it does the job just as well.

I will pop an update tomorrow as to how things went.

Once again, really appreciate the time and effort that you put into the openHAB community. You have been providing me with solutions from the very beginning of my time with home automation.
Thanks
Gordy

Hi Rich, The time of day rules are working as expected now. I ended up deleting the ToD manager rules for the astro items and re-adding them and all has worked ok since then.

Thanks again
Gordy

Hi

I’m run OH 3.3 on ubunut 22.04

I have followed this tutorial.
My astro item (rlkoshak’s ToD_EVENING item) works perfect with astro time.

My night item (rlkoshak’s ToD_BED item) with a fixed time works but when I restart my computer, it becomes NULL. I use the built in calendar that popup and set a new fixed time, restart, the item becomes NULL again.

The item I’m using is a date/time item with rlk_datetime_standalone widget.

Second
I have a second item, a alarm clock, which is date/time item with rlk_datetime_standalone widget. The popup calendar works on a computer, but on iPhone/iPad, the calendar will not popup (the calendar icon does not appear). What do I have to do, to set time on my alarm clock item with my iPhone/iPad?

Thanks!

Is that Item configured to be restored on startup from Persistence? It would appear that it isn’t. See Persistence | openHAB for more details.

What renders the date time picker is the browser. There is nothing I have control over there. There might be something the devs of MainUI can do so file an issue.

In the mean time, you can manually type the date time in instead of using the date time picker.

Hi

I followed the instructions above as best I could. If I follow the values of the ToD items for a few days now they work as expected except the Item “Time of day”. This one remains “NULL”.
image

What could be the cause of this?

Which approach did you follow, No Code or Fewer Rules?

Note, this tutorial is a little bit out of date. The Alarm Clock Rule is no longer required. You can trigger a rule now with the state of a Date Time Item. So when you follow the “Crete the Transition Rules” section, also add a trigger to those Rules using a Time trigger with “at a time specified in a given Item’s state” and select the DateTime Item that specifies when that time of day should start.

You can choose whether to ignore the date part of the DateTime which frees you from needing the To Today rule template too.

Then you don’t need to instantiate any rules using the templates. No Alarm Clock nor To Today rules are required any more.

Hi Rich,

I use No Code.

Do you mean the “mgr” rules are no longer needed?

Should the word AFTERNOON at Command be placed in between quotation marks: “AFTERNOON”?

Correct. All those rules do is call the rules you created in the first step at the right time. That’s now built into OH with the new(ish) time trigger that uses the DateTime Item’s state. All you need to do is add a trigger to rules in the first step.

No, quotes are not required.

Like this:

(My english is probably not good enough to understand you completely)

Nov-01-2022 07-15-11