[Deprecated] Design Pattern: Time Of Day

Again, the “old” JodaTime is no longer supported, it needs to be ZonedDateTime.

But the new JavaScript is working nicely now, why don’t you try that? You only have to:

  • copy the time_utils and timer_mgr scripts from Rich’s Github page to /etc/openhab/automation/…/
  • Set up items for the times you want with ephemeris metatags
  • manually set the times you want for those items (openhab:send from the console), only the time is needed and it’s only needed once
  • create a new rule from the openhab main ui and copy the ephem_tod script to it.

If you ever need to change a transition time, just send a new command to that time item.

Hi @ all,
like probably a lot of people got startet with the migration to OH3 during the hollidays and since relying on the TOD pattern quite a lot I just have a quick question regarding where to put the needed library folders and automation folders from the git repository.

As I understood it I have to clone the whole repo to my system, check.

Where do I put the modules and scrips I need? In the readme it says: Copy the automation folder under a given capability's folder to $OH_CONF.. Does that mean I put for example a folder called timer_mgr in the $OH_CONF Folder and copy the automation folder from the cloned git repo there? Or do I put erverything in a single folder called automation in the $OH_CONF Folder?

I guess I am being stupid but really want it to work and to learn. Thanks for your help and also @rlkoshak and the others for their tremendous work!

No, you do not need to clone the whole repository.
If you look at the start of the JS script, you’ll see that it loads its helper scripts from a specific directory:

load(OPENHAB_CONF+'/automation/lib/javascript/community/timerMgr.js');
load(OPENHAB_CONF+'/automation/lib/javascript/community/timeUtils.js');

So you’ll just need to copy those two .js files (found in Rich’s repository) to the right location.
For a standard linux, $OPENHAB_CONF resolves to /etc/openhab, so my scripts are here:

/etc/openhab/automation/lib/javascript/community

You maybe should chown the whole automation folder and its subfolders to the openhab user, but its probably not necessary.

Hi thanks for clearing up my question so fast! Now I understand :slight_smile: ! Always amazing how fast the community is! Thanks again!

You’re welcome. Tell us if you got it working.

Oh, btw., you’ll need to put your country/state/whatever in Openhab3/Settings/Ephemeris, otherwise it can’t get the holidays correctly.

EDIT

Ok, got the files in the right place and it seems that something happens since I get a value for the Default Evening item. Now the next questions is comming up … where do I define the start times of my default items? Is ist possible to define fixed time when a time of day is supposed to be starting?

I read in a post that you have to set times in the item itself but how? Just got the Default Day working by linking the Lokal Sun Data - Thing rise#start - Channel to the Default Day Item. Here post #542 it was mentioned to …

  • manually set the times you want for those items (openhab:send from the console), only the time is needed and it’s only needed once

… how do I do this? Is this the part where OH 3 Examples: How to boot strap the state of an Item comes into play?

Thanks again for enlightening input!

:man_facepalming: OK he who reads will get the info he seeks! The solution to the problem ist the boot strapping part!

OK, the boot strapping part probably is the right way but does not work as discribed. Unless I am missing something. Adding the metadata part works but unfortunatly when trying to set a time I need to put date and time in otherwise I get a error. When adding date and time the item state is not changed and remains NULL. Is there a need to uncomment or change something in the .yml rule?

I tried the bootstrapping part, too, and found it didn’t work as expected, either.
But you can easily do it from the karaf console:

The syntax is:
openhab:send <item> <command>

So if you want your Default_Morning item to be set to 5 in the morning, you’d enter:
openhab:send Default_Morning 05:00:00

It’s a DateTime item, but if you omit the date, it will be set to today’s date (and your Timezone). And then the script will move it to the next day every midnight.

You can test if it’s correct by entering:
openhab:items list | grep Default_Morning

For me, that gives back:
Default_Morning (Type=DateTimeItem, State=2020-12-26T05:15:00.000-0600, Label=MORNING, Category=time, Groups=[TimesOfDay])

Or, you can just put the TimeOfDay items in a sitemap and look at them there.

Again, this only needs to be done once (or when you want to change the times).
As you found out, this only applies to the fixed times, the variable ones that come from Astro are populated by the Astro binding.

UPDATE

Thank you for your quick answer!

After trying a couple of times and over and over … HEUREKA … it works as described. Staic times are Set and can be changed through the Widget. Why it startet to work I have no Idea.

Now to the next Part … that is the TimeOfDay item which right now is yet to show anything but NULL.

Run the script manually using that “Play” button. If you watch the logs, it should show something like this:

2020-12-26 00:01:00.863 [INFO ] [openhab.model.script.Rules.TimeOfDay] - Cancelling any existing timers
2020-12-26 00:01:00.866 [INFO ] [openhab.model.script.Rules.TimeOfDay] - Existing timers have been cancelled
2020-12-26 00:01:00.867 [INFO ] [openhab.model.script.Rules.TimeOfDay] - FUTURE: MORNING scheduleing timer for 2020-12-26T05:15-06:00
2020-12-26 00:01:00.871 [INFO ] [openhab.model.script.Rules.TimeOfDay] - FUTURE: DAY scheduleing timer for 2020-12-26T07:02-06:00
2020-12-26 00:01:00.873 [INFO ] [openhab.model.script.Rules.TimeOfDay] - FUTURE: EVENING scheduleing timer for 2020-12-26T17:05-06:00
2020-12-26 00:01:00.875 [INFO ] [openhab.model.script.Rules.TimeOfDay] - FUTURE: NIGHT scheduleing timer for 2020-12-26T21:00-06:00
2020-12-26 00:01:00.876 [INFO ] [openhab.model.script.Rules.TimeOfDay] - FUTURE: BED scheduleing timer for 2020-12-26T22:00-06:00
2020-12-26 00:01:00.878 [INFO ] [openhab.model.script.Rules.TimeOfDay] - Created 4 time of day timers
2020-12-26 00:01:00.878 [INFO ] [openhab.model.script.Rules.TimeOfDay] - The current time of day is BED

Then it should update the TimeOfDay item.
(Don’t ask me why I have five times, but it schedules only four of them. We have not figured that out, yet. But all timers fire, so it doesn’t really matter).

Finally … made it!
Problem occured because the .yml script that I pasted was somehow not pasted in the correct format so that I got loads of errors. Deleting and Pastzing the code part again didn’ work. Finally I just deleted the rule and pasted from notepad++ this did the trick. Unfortunately some static times went missing but since I implemented them with the boot strap thing it was no problem getting them back.
Will look if everything works as it should!

I have my items in .item files, so they can’t get lost in there.
For copying the script, in Github it’s usually best to get it in raw-mode. That usually eliminates errors due to improper pasting.

But I’m glad you got it working.

ok so ive created the rule in oh3 ui pasted the raw /ephemTimeOfDay.yml into the code section but when I click on the play button I get the following error in the logs.

2020-12-27 00:58:34.484 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '96b7b0f9d3' failed: TypeError: Cannot load script from /etc/openhab/automation/lib/javascript/community/timerMgr.js in <eval> at line number 27

And I suppose you triple-checked that both of the necessary helper scripts are in the correct place, have you?

I cant see a ect/openhab share for openhabian? where is it?

ok so you have to create all the folders yourself. ive done that and now its throwing anther error.

2020-12-27 03:34:34.931 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '96b7b0f9d3' failed: The TimeOfDay Item is not defined! in <eval> at line number 239 at column number 4

where are you meant to define a time of day thing? ive looked at line 239 and cant see anything?

First: if you are accessing the files on your openhabian installation from a windows box, I would strongly advise against it. That’s almost a guarantee to mess things up, as Windows uses a different kind of linefeed character (and most likely a different locale) than your openhabian. So don’t edit scripts via a Windows share.
Second, if you read through the instructions, you’ll see that the script needs several items to work:

  1. an item named TimeOfDay, that is the one that will be updated as the transitions happen and which is what you will want to use for your own rules. This is a string item.
  2. a DateTime item for each time you want to transition to. Morning, Day, Evening, etc. Two or more for each time if you want to use weekday/weekend/holiday etc. Those need to have the ephemeris metatags.
  3. a group named TimesOfDay of the DateTime type that all the items belong to. This has to be a DateTime group.
    Third, there’s a difference between an item and a thing in Openhab.

Best put all of these in an items file under /etc/openhab/items. Be sure to edit this file on the openhabian system itself, by using an editor. Vi, emacs, whatever suits you.

For example, my items file looks like this:

Group:DateTime TimesOfDay <time>
String TimeOfDay "Current time of day [%s]" <time>
DateTime Default_Morning "MORNING [%s]" <time> (TimesOfDay) { etod="MORNING"[type="default"] }
DateTime Default_Day "DAY [%s]" <time> (TimesOfDay) { channel="astro:sun:local:rise#start", etod="DAY"[type="default"] }
DateTime Default_Evening "EVENING [%s]"<time> (TimesOfDay) { channel="astro:sun:local:set#end", etod="EVENING"[type="default"] }
DateTime Default_Night "NIGHT [%s]" <time> (TimesOfDay) { etod="NIGHT"[type="default"] }
DateTime Default_Bed "BED [%s]" <time> (TimesOfDay) { etod="BED"[type="default"] }

The “<time>” in there is just the clock icon, that’s not important. But the rest is.

sweet thanks, got that. ive just got the following item file.

Group:DateTime TimesOfDay
String TimeOfDay "Current time of day [%s]"

// Default day, initialization for JavaScript should be done thgrough MainUI. See https://community.openhab.org/t/oh-3-examples-how-to-boot-strap-the-state-of-an-item/108234
DateTime Default_Morning (TimesOfDay) { etod="MORNING"[type="default"] }
DateTime Default_Day (TimesOfDay) { channel="astro:sun:21bf543921:rise#start", etod="DAY"[type="default"] }
DateTime Default_Evening (TimesOfDay) { channel="astro:sun:21bf543921:set#start", etod="EVENING"[type="default"] }
DateTime Default_Night (TimesOfDay) { etod="NIGHT"[type="default"] }
DateTime Default_Bed (TimesOfDay) { etod="BED"[type="default"] }

// Weekend day, notice that not all the states are listed, the unlisted states are skipped
DateTime Weekend_Day (TimesOfDay) { channel="astro:sun:set120:set#start", etod="DAY"[type="weekend"] }
DateTime Weekend_Evening (TimesOfDay) { channel="astro:sun:local:set#start", etod="EVENING"[type="weekend"] }
DateTime Default_Bed (TimesOfDay) { etod="BED"[type="weekend"] }

// Custom dayset
DateTime Trash_Morning (TimesOfDay) { etod="MORNING"[type="dayset", set="trash"] }
DateTime Trash_Trashtime (TimesOfDay) { etod="TRASH"[type="dayset", set="trash"]}
DateTime Trash_Day (TimesOfDay) { channel="astro:sun:set120:set#start", etod="DAY"[type="dayset", set="trash"] }
DateTime Trash_Evening (TimesOfDay) { channel="astro:sun:local:set#start", etod="EVENING"[type="dayset", set="trash"] }
DateTime Trash_Night (TimesOfDay) { etod="NIGHT"[type="dayset", set="trash"] }
DateTime Trash_Bed (TimesOfDay) { etod="BED"[type="dayset", set="trash"] }

// Default holiday
DateTime Weekend_Day (TimesOfDay) { channel="astro:sun:set120:set#start", etod="DAY"[type="holiday"] }
DateTime Weekend_Evening (TimesOfDay) { channel="astro:sun:local:set#start", etod="EVENING"[type="holiday"] }
DateTime Default_Bed (TimesOfDay) { etod="BED"[type="holiday"] }

// Custom holiday
DateTime Weekend_Day (TimesOfDay) { channel="astro:sun:set120:set#start", etod="DAY"[type="custom", file="/openhab/conf/services/custom1.xml"] }
DateTime Weekend_Evening (TimesOfDay) { channel="astro:sun:local:set#start", etod="EVENING"[type="custom", file="/openhab/conf/services/custom1.xml"] }
DateTime Default_Bed (TimesOfDay) { etod="BED"[type="custom", file="/openhab/conf/services/custom1.xml"] }

ive set the item times in the ui for the fixed times and used the channel for the ones that I want to change with sunrise and sunset and it looks like they should be working.

now I get this error.

2020-12-27 05:25:36.791 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '96b7b0f9d3' failed: Default_Bed has type custom which requires a 'file' value to be defined.
Invalid metadata for Item! Expected metadata in the form of etod="STATE"[type="daytype", set="dayset", file="uri"] where set is required if type is dayset and file is required if type is custom. in <eval> at line number 255 at column number 6

Well, yeah, you defined the “Default_Bed” several times. I just see that that’s an error in Rich’s item definitions.
If you want to use weekends/holidays (trash day - really?), every time needs to have its own item. So if you want to have a Bed Time for weekends, call it Weekend_Bed.
Also, did you configure the ephemeris.cfg accordingly? That’s the main reason you get that error message, because ephemeris does not yet know which days are regular days or weekends.

And did you put your country’s settings in Settings/Ephemeris in Openhab?

My advice: stick with Default Days at first, and add the weekends/holidays later when it’s working correctly. Just put a double slash “//” in front of the items below the Default day to deactivate them.

I’ll take a bite to try and remember to fix that when I get back to a computer in a few days.

1 Like

I wouldn’t have noticed it either, as I don’t use weekends. Just stumbled on it when Rick tried to use the items file verbatim.