[Deprecated] Design Pattern: Time Of Day

Many thanks! I did not understand if set120 was an offset option or the name of the actual channel… Anyway, it seems to be working now.

You are absolutely right, I could have been more informative from the beginning.

TimeOfDay is not included in the TimesOfDay group.
I changed default peristence from rrd4j to MapDB in the settings section - persistence as i read that MapDb woul be a better choice than rrd4j and that a benfit of using MapDB woul be that it will not grow in size. I alreadey use influxDB for other purposes so I can easily use it for this purpose. And since you say that MapDB is not a good choice for this i’ll make that change to influxDB.
Yes i am aware that TimeOfDay is a string, thanks for clearifying it further.

I’ll take your good advice and clearifying information and go ahead with the change.

Thank you for valuable information.

Thank you for clearyfing that MapDB is not a good choice in this case. I will switch over to influxDB instead.
I have no unusual arrangements in this case so using influxDB instead eliminates one component.

Me, neither. As I would have no use to know the last state of the item, I do not persist it at all. Works flawlessly without that.

Neither MapDB nor rrd4j grow in size. MapDB only saves the most recent value. rrd4j decimates the data as it ages.

So MapDBit will never be able to tell you the previous value. rrd4j only saves numbers so it will never be able to tell you the previous state of a String Item.

I’m sure there is a good reason, but a quick scan of the rule didn’t show what that’s used for. I’m sure I could determine what it’s used for if I studied the rule a bit closer. I just don’t have time to do so for now.

I made a typo. What I should say was that I read in the MapDB documentation that MapDB was a better choice than mysql and infuxDB since they both require complex installs and that rrdj4 can’t stor all item types.

But since I already have influxDB installed it is a good choice to use it even for this. Somtimes one shoots over the goal and make things more complicated than they need to be.

Once again thank you for your assitance.

They all have a place.
If you want historical data, Mapdb is useless.
For the specific purpose of restore-on-startup, Mapdb cannot be beaten.
Choose accordingly, and for many people choose more than one, configuring each service for particular purposes.

Like I do. MapDB as default for restore-on-startup, influxdb not for all items but only for the stuff I really want to track. Additionally, I’ve setup my influxdb to be sort of a round-robin-database, so it doesn’t really grow in size, either.

I need a little bit of help because I thought that I did everything as described here and in the repo but I keep getting this error when I run the yml rule:

2021-04-24 02:16:09.872 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘5167f5ff4d’ failed: Default_Morning’s state is undefined
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 at line number 255 at column number 6

I added the item and group definition including the meta data:

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:set120:set#start", etod="DAY"[type="default"] }
DateTime Default_Evening (TimesOfDay) { channel="astro:sun:local: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 Weekend_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 Holiday_Day (TimesOfDay) { channel="astro:sun:set120:set#start", etod="DAY"[type="holiday"] }
DateTime Holiday_Evening (TimesOfDay) { channel="astro:sun:local:set#start", etod="EVENING"[type="holiday"] }
DateTime Holiday_Bed (TimesOfDay) { etod="BED"[type="holiday"] }

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

The astro times show up correctly in the TimesOfDay group but the rest is at NULL.

Any ideas what I may have missed?

Looks like your “Default morning” is just undefined. To get started, you’ll need to set it to the time you want.
If you go into karaf console, do a “items list | grep Default_Morning”

That should give you something like this:

Default_Morning (Type=DateTimeItem, State=2021-04-23T05:15:00.000-0500, Label=MORNING, Category=time, Groups=[TimesOfDay])

If the state is NULL, just issue “openhab:send hh:mm Default_Morning” (with the time of your choice, obviously) to send the time to the item.

That obviously applies to other items you have defined. The astro items populate automatically, you don’t need to do that for them.

1 Like

After migrating to OH3 and implemented the DSL TimeOfDay rule i got it to work thanks to good advice from the forum. Thanks for that.

I thought I should take OH 3 a step further and implement the JavaScript MainUI Rule to replace the DSL rule.

System is:

  • Ubuntu 20.04 LTS
  • InfluxDB database

Astro Things and Items are defined

I have the following items:

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:set120:rise#start", etod="DAY"[type="default"] }
DateTime Default_Evening   (TimesOfDay)    { channel="astro:sun:local: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_Morning (TimesOfDay)    { etod="MORNING"[type="weekend"]}
DateTime Weekend_Day     (TimesOfDay)    { channel="astro:sun:set120:rise#start", etod="DAY"[type="weekend"] } 
DateTime Weekend_Evening (TimesOfDay)    { channel="astro:sun:local:set#start", etod="EVENING"[type="weekend"] }
DateTime Weekend_Bed     (TimesOfDay)    { etod="BED"[type="weekend"] }

I copied timerMgr.js and timeUtils.js to openhab\automation\lib\javascript.
Initilaized the “static” time items as described above in this thread with, “openhab:send Default_Morning 05:00”.

The items are initialized and the rule is working as it should, but if I stop the OH service and restart it again all the “static” items are set to NULL. and I have to manually initialize them again. As I understand this is correct behavior but I want them to automatically initialize on startup and I cannot find out how to solve this.

I tried to use the syntax described for the Python rule:

DateTime Default_Morning { init="2021-05-01T05:00:00", etod="MORNING"[type="default"] }

I copied “300_item_init.py” to openhab\automation\lib\python and installed Python Scripting Method. Restarting OH, I get this in the log file so I assume that the scripting engina has started correctly:

17:49:34.656 [DEBUG] [ript.internal.ScriptEngineManagerImpl] - Initialized a custom ScriptEngineFactory for jython (2.7.2): supports python (2.7) with file extensions [py], names [python, jython], and mimetypes [text/python, application/python, text/x-python, application/x-python]

But the item is not initialized.

I have influxDB as default persistance database and listing the database information for Default_Morning i get the following result:

> select * from Default_Morning
name: Default_Morning
time                     item            value
----                     ----            -----
2021-04-25T11:46:33.917Z Default_Morning 14400000
2021-04-25T11:47:08.382Z Default_Morning 1619301600000
2021-04-25T12:30:40.28Z  Default_Morning 14400000
2021-04-25T12:31:09.619Z Default_Morning 1619301600000
2021-04-25T13:39:16.019Z Default_Morning 14400000
2021-04-25T13:39:42.222Z Default_Morning 1619319600000
2021-04-27T14:55:35.592Z Default_Morning 1619492460000
2021-04-27T22:00:30.392Z Default_Morning 1619578860000
2021-04-28T16:35:57.321Z Default_Morning 1619578740000
2021-04-28T22:00:31.111Z Default_Morning 1619665140000
>

Converting the timstamp in the last line i get this date & time: 2021-05-01 15:58:14.
I have created a rule to run at startup:

rule "System Startup"
when
  System started
then
  Default_Morning.previousState(true).state as DateTimeType
end

In the log file I can see that the startup rule is executed.

From the log file:

18:01:15.995 [DEBUG] [ript.internal.ScriptEngineManagerImpl] - Added ScriptEngine for language 'application/vnd.openhab.dsl.rule' with identifier: fee00939-989c-4d9b-9a16-dbe827900aae
18:01:16.155 [DEBUG] [re.automation.internal.RuleEngineImpl] - The rule 'systemStartup-1' is executed.
18:01:16.157 [INFO ] [re.automation.internal.RuleEngineImpl] - Rule engine started.

but the item is not initialized.

So now I have run out of ideas and hope for som help to describe what I am missing.

I’m not clear why you don’t use on of the persistence services to do a restore-on-startup?

Well, it has completely passed my mind. I have read a lot of posts to understand the java script and how to setup.
I will try it right now.

Updating the infuxdb.cfg file to

Strategies {
    everyMinute : "0 * * * * ?"
    everyHour   : "0 0 * * * ?"
    everyDay    : "0 0 0 * * ?"
}

Items {
    gIrrFront*,
    TimeOfDay*   : strategy = everyChange, everyMinute, restoreOnStartup
}

But the result is the same. item is still set to NULL after restart.

That looks like xx.persist file contents?

Note that persistence services do not read persist configuration files except at startup (so it may not have been persisting before the reboot/)

This looks like a typo, does not match your given Items.

I don’t think there is much point in persisting these Items every minute.

Yes it should be influxdb.persist instead of influxdb.cfg.
And you where right it was a typo, TimeOfDay is a string item and the groups name is TimesOfDay.

And yes, it is not much point of persisting every minute,. This is just my test setup and when implementing in the production system I will set it differently, onEveryChange would be enough I think.

After correcting the typo and performing a completely reboot it works as it should.

Many thanks for your help.

It is now working as it should.

1 Like

Good to hear.
Even so, I for one also use influxdb, but only for the stuff that I actually want to track and plot. Temperatures around the house and outside, that kind of thing. TimesOfDay, not so much. Neither the status of all the switches around the house.

So for persisting all items to restore on startup I use MapDB. Small, lightweight, and does exactly that: persists the last status of all items, nothing more.

1 Like

Thanks for the tip of a more sutible database for TimesOfDay and similar types of more static items, I will implement it and differentiate historical data and persistence for last state.

I should mention that currently in OH3 the call for requesting historical data from influxdb in a rule results in an error if you’ve changed the default retention policy name (which I have, I use influxdb more like a round-robin database). So I even have to resort to a third persistance service (rrd4j) for that one. Not sure if that’ll ever be fixed, but just wanted you to be aware of it in case you want to extract historical data.

That is good to know. I will have that in mind as I go on.
Thank you!