Time Based State Machine [4.0.0.0;4.9.9.9]

This is the log from the last manual run.

2023-10-05 13:11:23.229 [DEBUG] [omation.rules_tools.TimeStateMachine] - Starting state machine in ten seconds...
2023-10-05 13:11:33.280 [DEBUG] [omation.rules_tools.TimeStateMachine] - Validating Item types, Item metadata, and Group membership
2023-10-05 13:11:33.487 [DEBUG] [omation.rules_tools.TimeStateMachine] - Default_Bed is valid
2023-10-05 13:11:33.527 [DEBUG] [omation.rules_tools.TimeStateMachine] - Holiday_Afternoon is valid
2023-10-05 13:11:33.560 [DEBUG] [omation.rules_tools.TimeStateMachine] - Default_Afternoon is valid
2023-10-05 13:11:33.587 [DEBUG] [omation.rules_tools.TimeStateMachine] - Holiday_Evening is valid
2023-10-05 13:11:33.612 [DEBUG] [omation.rules_tools.TimeStateMachine] - Weekend_Night is valid
2023-10-05 13:11:33.633 [DEBUG] [omation.rules_tools.TimeStateMachine] - Default_Day is valid
2023-10-05 13:11:33.660 [DEBUG] [omation.rules_tools.TimeStateMachine] - Weekend_Afternoon is valid
2023-10-05 13:11:33.682 [DEBUG] [omation.rules_tools.TimeStateMachine] - Weekend_Bed is valid
2023-10-05 13:11:33.697 [DEBUG] [omation.rules_tools.TimeStateMachine] - Weekend_Evening is valid
2023-10-05 13:11:33.708 [DEBUG] [omation.rules_tools.TimeStateMachine] - Default_Evening is valid
2023-10-05 13:11:33.719 [DEBUG] [omation.rules_tools.TimeStateMachine] - Default_Morning is valid
2023-10-05 13:11:33.729 [DEBUG] [omation.rules_tools.TimeStateMachine] - Weekend_Morning is valid
2023-10-05 13:11:33.741 [DEBUG] [omation.rules_tools.TimeStateMachine] - Trash_Evening is valid
2023-10-05 13:11:33.752 [DEBUG] [omation.rules_tools.TimeStateMachine] - Trash_Afternoon is valid
2023-10-05 13:11:33.763 [DEBUG] [omation.rules_tools.TimeStateMachine] - Default_Night is valid
2023-10-05 13:11:33.779 [DEBUG] [omation.rules_tools.TimeStateMachine] - Trash_Morning is valid
2023-10-05 13:11:33.800 [DEBUG] [omation.rules_tools.TimeStateMachine] - Trash_Bed is valid
2023-10-05 13:11:33.819 [DEBUG] [omation.rules_tools.TimeStateMachine] - Holiday_Bed is valid
2023-10-05 13:11:33.838 [DEBUG] [omation.rules_tools.TimeStateMachine] - Holiday_Morning is valid
2023-10-05 13:11:33.854 [DEBUG] [omation.rules_tools.TimeStateMachine] - Holiday_Day is valid
2023-10-05 13:11:33.867 [DEBUG] [omation.rules_tools.TimeStateMachine] - Trash_Trashtime is valid
2023-10-05 13:11:33.877 [DEBUG] [omation.rules_tools.TimeStateMachine] - Holiday_Night is valid
2023-10-05 13:11:33.888 [DEBUG] [omation.rules_tools.TimeStateMachine] - Weekend_Day is valid
2023-10-05 13:11:33.900 [DEBUG] [omation.rules_tools.TimeStateMachine] - Trash_Night is valid
2023-10-05 13:11:33.915 [DEBUG] [omation.rules_tools.TimeStateMachine] - Trash_Day is valid
2023-10-05 13:11:33.930 [INFO ] [omation.rules_tools.TimeStateMachine] - All tsm Items are configured correctly
2023-10-05 13:11:36.114 [DEBUG] [omation.rules_tools.TimeStateMachine] - All tsm Items are configured correctly
2023-10-05 13:11:36.116 [DEBUG] [omation.rules_tools.TimeStateMachine] - Cancelling existing timers
2023-10-05 13:11:36.117 [DEBUG] [omation.rules_tools.TimeStateMachine] - Acquiring today's state start times
2023-10-05 13:11:36.500 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job 'ui.TOD_Rule.debounce' failed and stopped
org.graalvm.polyglot.PolyglotException: TypeError: (intermediate value).getMetadata is not a function
        at <js>.:=>(<eval>:160) ~[?:?]
        at <js>.getTodayItems(<eval>:160) ~[?:?]
        at <js>.createTimersGenerator(<eval>:210) ~[?:?]
        at <js>.:=>(/etc/openhab/automation/js/node_modules/openhab_rules_tools/timerMgr.js:66) ~[?:?]

That doesnā€™t really tell me what version is installed. But itā€™s a pretty good indication you have the latest release since thatā€™s 2.0.3.

Iā€™m on my phone and wonā€™t be back on a computer for a few days. Can you open the Script Action and tell me what line 160 is?

I think itā€™s the line that starts with

{ 'type': 'dayset'

If so I think there is a bug on that line. Change ā€œitems.getMetadataā€ to ā€œitem.getMetadataā€.

Thatā€™s something I need to fix anyway but it might but be your error.

This is the line

    { 'type': 'dayset',  'times' : getItemsOfType('dayset').filter(item => actions.Ephemeris.isInDayset(items.getMetadata()[NAMESPACE].configuration['set'])) },

I changed the code based on your suggestion and it appears to work.

2023-10-05 14:00:31.175 [DEBUG] [omation.rules_tools.TimeStateMachine] - All tsm Items are configured correctly
2023-10-05 14:00:31.175 [DEBUG] [omation.rules_tools.TimeStateMachine] - Cancelling existing timers
2023-10-05 14:00:31.176 [DEBUG] [omation.rules_tools.TimeStateMachine] - Acquiring today's state start times
2023-10-05 14:00:31.997 [INFO ] [omation.rules_tools.TimeStateMachine] - Today is a default day.
2023-10-05 14:00:31.999 [DEBUG] [omation.rules_tools.TimeStateMachine] - Creating timers for times that have not already passed
2023-10-05 14:00:32.572 [DEBUG] [omation.rules_tools.TimeStateMachine] - Creating timer for Evening at 2023-10-05T16:43-04:00
2023-10-05 14:00:32.673 [DEBUG] [omation.rules_tools.TimeStateMachine] - Creating timer for Night at 2023-10-05T18:42-04:00
2023-10-05 14:00:32.740 [DEBUG] [omation.rules_tools.TimeStateMachine] - Creating timer for Bed at 2023-10-05T22:00-04:00
2023-10-05 14:00:32.847 [INFO ] [omation.rules_tools.TimeStateMachine] - The current state is Afternoon

1 Like

Thanks for your help

Hi @rlkoshak ,

Upgrade to 4.1M2 from 4.1M1 reverts a problem we discussed in March, Time Based State Machine gives the error:

2023-10-09 23:06:36.576 [WARN ] [omation.rules_tools.TimeStateMachine] - require TimerMgr instead of timerMgr and use TimerMgr() instead of new timerMgr.TimerMgr().
2023-10-09 23:06:36.595 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: Error: "2023-10-09T23:06:46.582+02:00[SYSTEM]" is an unsupported type for conversion to time.ZonedDateTime

With 4.1M1 there is no error and downgrade from 4.1M2 resolves the issue for me.
Additionally, there is a warning in both releases in the first line above but I donā€™t expect itā€™s crucial to the error.
I donā€™t know if the warning appeared after upgrade or existed before and I wasnā€™t aware of it.
The warning remains after downgrade but your rule runs with no error.
I tried to resolve the issue by upgrading openhab_rules_tools so maybe this caused the warning to appear.

I use rule template from marketplace.
Iā€™ve upgraded and downgraded OH several times to confirm.

1 Like

The first warning is what I would expect to see. I changed how the TimerMgr is imported in the latest version of OHRT. You can ignore that warning.

Please post the full stack trace so I can confirm which lines are throwing the error. Also please post that line and the lines around it so I can confirm itā€™s running with the latest version of the template.

Please confirm your JS Scripting add-on settings and version. From a scratchpad script run:

var {helpers} = require('openhab_rules_tools');
console.info('openhab-js version: ' + utils.OPENHAB_JS_VERSION);
console.info('OHRT version: ' + helpers.OHRT_VERSION);

Watch the logs and report what versions of the library you are running.

Thanks for quick reply.
Iā€™ve resolved the error in the meantime by reinstalling JavaScripting and TSM rule so above code gives following logs:

2023-10-10 19:08:10.293 [INFO ] [nhab.automation.script.ui.scratchpad] - openhab-js version: 4.5.1
2023-10-10 19:08:10.294 [INFO ] [nhab.automation.script.ui.scratchpad] - OHRT version: 2.0.3

Now I have no error or warning so sorry for false alert.

I have some problems with Add-ons UI, featured add-ons in the Store Automation group are doubled. In case of JavaScripting one of the doubled is installed and second is for adding. If I try to remove this installed, Install pop-up appear and do something but donā€™t remove anything or reinstall suppose. The second add-on remains for adding state even after install. I tried different browsers so I donā€™t think that is cache related problem. 4.1M1 behaves the same.

Thanks and have good one

Good because I just upgraded to 4.1 M2 myself and the rule worked without error with those versions of the library. I was going to be at a loss for what to do.

Itā€™s probably worth opening a new thread to explore that one.

Have you cleared the cache of OH: Clear the Cache

Yes, I cleared the cache exactly following this topic.

Hi @rlkoshak,
first of all, thanks for your amazing rule template(s), they really make things a lot easier.
However, I noticed some minor issue lately.

Iā€™m not sure, if this works correctly. I noticed last week, that for items which are set to a static time only via timepicker widget (and thus have a state like 1970-01-01T22:00:00.000+0100) were off an hour since not transformed to current date/time. So I had to re-implement your to_today rule to fix times. This seems to be an issue with daylight saving time (which was switched this weekend in Austria, so it is again working correctly now).

And one more thing: would you consider adding to more day types, one for days before weekend or holidays and one for the last weekend day/holiday before a workday? This would make it more flexible for days with ā€œmorning timesā€ treated like weekends/holidays and ā€œevening/night timesā€ like weekdays. I think this is similar to what @LukaNoah requested above.
Should be as easy as adding preworkay and predayoff (naming can be discussed):

          // type.
          const startTimes = [
            { 'type': 'custom',  'times' : getItemsOfType('custom').filter(item => actions.Ephemeris.isBankHoliday(0, item.getMetadata()[NAMESPACE].configuration['file'])) },
            { 'type': 'preworkday', 'times' : (!(actions.Ephemeris.isBankHoliday(1) || actions.Ephemeris.isWeekend(1)) && (actions.Ephemeris.isBankHoliday() || actions.Ephemeris.isWeekend())) ? getItemsOfType('preworkday') : [] },
            { 'type': 'holiday', 'times' : (actions.Ephemeris.isBankHoliday()) ? getItemsOfType('holiday') : [] },
            { 'type': 'dayset',  'times' : getItemsOfType('dayset').filter(item => actions.Ephemeris.isInDayset(items.getMetadata()[NAMESPACE].configuration['set'])) },
            { 'type': 'weekend', 'times' : (actions.Ephemeris.isWeekend()) ? getItemsOfType('weekend') : [] },
            { 'type': 'predayoff', 'times' : (actions.Ephemeris.isBankHoliday(1) || actions.Ephemeris.isWeekend(1)) ? getItemsOfType('predayoff') : [] },
            { 'type': 'weekday', 'times' : (!actions.Ephemeris.isWeekend()) ? getItemsOfType('weekday') : [] },
            { 'type': 'default', 'times' : getItemsOfType('default') }
          ];

and

var DAY_TYPES   = ['custom', 'preworkday', 'holiday', 'dayset', 'weekend', 'predayoff', 'weekday', 'default'];

BR Hans

1 Like

If there is a problem, itā€™s going to be in core and an issue should be filed. But Iā€™m guessing that the problem is itā€™s using ISO8601 format instead of RFC format (i.e. +0100 instead of Europe/Vienna).

At least in rules, the RFC format is used but maybe not for DateTimeTypes.

The proper fix for this would be to fix this in OH core to make sure that it handles the DST change over properly. The fact that a problem occurred with this rule template is just symptom of a wider problem. It will be a problem for anyone using a Time is <item> triggered rule.

But in the mean time, something like To Today can be a work around, though it doesnā€™t need to run every day. Just on the DST changeover dates.

Iā€™ll also look to see if itā€™s feasible to call toToday in getItemsOfType as a work around. In the Helper Library, toToday was monkey patched onto ZonedDateTime so time.toZDT(items.MyDateTimeItem).toToday() should handle DST changeovers. But Iā€™ve not tested toToday with an Item like that yet.

Iā€™m already calling toToday on the date times, so apparently that isnā€™t working right.

If you want to have more day types, you can configure them through Ephemeris: see Actions | openHAB. You have full control over defining day types and holidays. Define a predayoff dayset in Ephemeris and use dayset as the type for recurring days (i.e. days that occur every week) and a custom Ephemeris XML file and custom as the type.

Stuff like this is the whole reason I included the dayset and custom day types.

Also, as I showed above, handling those time of day states that are slightly different outside this rule template is almost always going to be simpler to implement and/or configure and use. Using the example from above, itā€™s easier to set up a separate rule for BEDTIME than it would be to set up two or more sets of separate DateTime Items just to handle the case where BEDTIME is different the night before the weekend or a holiday.

Iā€™m not certain it is that easy. For example, Iā€™d have to think about how that will work for those who, for example, do not have every holiday off work.

{ 'type': 'preworkday', 'times' : (!(actions.Ephemeris.isBankHoliday(1) || actions.Ephemeris.isWeekend(1)) && (actions.Ephemeris.isBankHoliday() || actions.Ephemeris.isWeekend())) ? getItemsOfType('preworkday') : [] },

I donā€™t think this condition is correct. Shouldnā€™t the ! be on the second clause? We want this to match if today is a workday (i.e. not a weekend or holiday) and tomorrow is a weekend or a holiday.

Iā€™m not sure predayoff is needed. It seems highly unlikely and relatively rare that one would need a whole different set of times of day if itā€™s already a day off and tomorrow is a day off too.

Logically, I think preworkday would best be put between weekend and weekday. It doesnā€™t actually change how it works functionally, but it makes sense to put it close to weekday since itā€™s a special type of weekday.

Not sure what you mean with the issue being in core and I have to admit that Iā€™m not really looking through the different time formats and conversions. I just noticed that the conversion to local time didnā€™t work correctly for the time-based states, but did when manually running your to_today rule (had to adapt it a bit to get items by group membership instead of tag). So I guessed the conversion in your rule didnā€™t work correctly.
Therefore, I wouldnā€™t even know how to describe the issue with regard to core.

Would have hoped so, but I donā€™t get how to define daysets on such conditional rulesā€¦

Of course this canā€™t cover all cases and probably the naming could be improved. But with your argument the whole differentiation between holidays, weekend and weekdays would be mostly obsolete.

Maybe Iā€™m missing something but seems correct to me:

(TOMORROW is NOT a holiday OR weekend day) AND (TODAY IS a holiday OR weekend day)

But it actually represents a day that is NOT a day off but next day is. And thatā€™s actually the tricky part as, for example, I canā€™t set it to Friday (as the last workday) as it would need to be Thursday if Friday was a holiday.

According to this comment in the code:

// Go through startTimes in order and choose the first one that has a non-empty list of Items

I was thinking that the first matching type is used. Therefore, preworkday would always match holiday or weekend first. But maybe I was misinterpreting somethingā€¦

If there is an easy way to add these conditional daysets through ephemeris directly. Iā€™m absolutely fine with that, and actually I can also live with not having them available. I just thought it would be a nice, easy and non-breaking addition that could be of general use. (And unfortunately it seems to be not possible to have rule templates without adding them to the marketplace, which Iā€™d consider improper and confusing for every minor deviation from the original.)

Java, upon which OH is built, supports both ISO8601 formatting which has a fixed timezone of + or - hours from GMT. That format does not handle DST. Something needs to go in and adjust that timezone offset when DST changes.

However, Java also supports RFC formatting which uses region/city for the timezone. When that formatting is used, I think that handling the DST change is automatic.

The problem is in core because this problem affects more than just this rule template. It impacts all Time is item triggered rules and anything else that uses the state of DateTime Items but only look at the time.

End users should not have to go and adjust all their DateTime Items every time DST changes. OH should handle that for us.

Unfortunately there isnā€™t a way to do this through the UI yet. But itā€™s pretty simple.

Letā€™s say you want a different set of times for Friday. Then create the file $OH_CONF/services/ephemeris.cfg with the following contents:

country=de
region=nw
dayset-workday=[MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY]
dayset-weekend=[SATURDAY,SUNDAY]
dayset-preweekend=[FRIDAY]

Replace the country and regionā€™s value with what ever is appropriate for you. And if your workday and weekend are different you can change those values there as well.

Then in the metadata for the DateTime Items youā€™d use ā€œdaysetā€ for the type and ā€œpreweekendā€ for the ā€œsetā€.

value: MORNING
config:
  type: dayset
  set: preweekend

For holidays youā€™ll need to create an XML file following the example here with the pre-holiday days defined. Then the metadata for the DateTime Items would be type ā€œcustomā€ and file the full path to the XML file. For example:

value: MORNING
config:
  type: custom
  file: /etc/openhab/preholiday.xml

I think I was misunderstanding the purposes of the types. The order and conditions are correct I think. preworkday needs to be before holiday and it needs to check that today is a holiday or weekend and tomorrow is a workday. And predayoff needs to check that today is a workday and tomorrow is a holiday or weekend.

Iā€™m not sure though now whether dayset should be before holiday or not. Ideally custom stuff should take precedence over built in stuff.

Iā€™ve created an issue and commented on relevant issues and PRs to make it so itā€™s possible to create rule templates locally.

But based on the rules of the marketplace having separate entries for minor updates to an already published template are not allowed.

All-things-considered, there are a lot of combinations to consider which need to be considered to make sure we donā€™t break too many use cases.

And unfortunately rather limitedā€¦ I was aware of these opportunities for configuration, but setting fixed days (or dates) is far from the proposed dynamic determination based on current and next day (as outlined above: if Friday is a holiday, preweekend or predayoff, respectively, would be on Thursday already).
Looking at the XSD that defines the structures of the XML it may be possible to build a custom XML file, which is based on relative dates, but I donā€™t think Iā€™m able to do that.

It depends on how the holidays are defined.

If I took Thanksgiving in the US which is the fourth Thursday in November, Iā€™d use the following in my custom XML file:

<tns:FixedWeekday which="FOURTH" weekday="WEDNESDAY" month="NOVEMBER" descriptionPropertiesKey="Day Before Thanksgiving"/>

The days around Easter are a bit more challenging but there is a RelativeToEasterSunday element, and most of the week before Easter has itā€™s own holiday entry anyway.

Looking at the Austria holidays list I donā€™t see anything tricky where youā€™d need anything more than Fixed and RelativeToEasterSunday.

For example, I would expect your entry for the day before Ascension Day would be something like:

<tns:RelativeToEasterSunday descriptionPropertiesKey="Day Before Ascension Day">
  <tns:chronology>GREGORIAN</tns:chronology>
  <tns:days>39</tns:days>
</tns:RelativeToEasterSunday

Going through this also raises a concern. I wonder how many people actually get off for all of the holidays listed in Jolly Day. I certainly donā€™t. I donā€™t get half of them off.

Hello everybody,
Iā€™ve been using the old ToD State Machine on OH3 for years and just loved it.
I tried to switch to this new state machine and need a little startup help.

Iā€™m running OH 4.0.3 - Release Build
I installed JS scripting and openhab_rules_tools (I donā€™t know how to check the versions but folders are present)

I created a Group (gTimesOfDay) that hold two DateTime items to start with. Both have the following meta data:

value: BED
config:
  type: default

value: MORNING
config:
  type: default

Namespace is tsm

I also have a String item TimeOfDay

The I tried to install the ā€œTime Based State Machineā€ Template from market place. But nothing happend. I guess there should some script or something else after installation. But I canā€™t find anything. What is supposed to happen?
How can I debug this?
Do I need more DateTime items to start with?
Are there any other prerequisites?

Thanks in advance!!

Martin

Run a script (Scratchpad from the Developer Sidebar is a good place to do this) with the following:

console.info('openhab-js version: ' + utils.OPENHAB_JS_VERSION);
console.info('OHRT version: ' + helpers.OHRT_VERSION);

That will log out the versions of both to openhab.log.

If you just installed both you are almost certainly running recently enough versions of both.

See https://www.openhab.org/docs/concepts/rules.html#rule-templates and https://www.openhab.org/docs/tutorial/rules_basic.html#rule-templates.

Once the rule template is installed, you have to instantiate one or more rules based on the template and configure it with the required properties. The template is just that, a template. Itā€™s not a rule unto itself.

Once instantiated, running a rule generated from any of my templates manually will test the configuration and generate logs if there are errors.

Thanks a lot.

Itā€™s working

Hi,

Donā€™t know if I should post this here or start a new topic, but Iā€™ll go with this :slight_smile:

I just upgraded to OH stable 4.1 and after that I get an error when I run the Time Based State Machine rule (there are a lot more text in the log if thatā€™s interesting). It was working fine before the upgrade. I upgraded via apt-get so got other Linux packages updated at the same time. I didnā€™t take any snapshot before upgrading (I know that Iā€™ve shouldā€™ve) so canā€™t roll back.

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'd6e4539529' failed: org.graalvm.polyglot.PolyglotException: Error: "2024-01-04T20:29:13.804+01:00[SYSTEM]" is an unsupported type for conversion to time.ZonedDateTime

Where does the ā€œ[SYSTEM]ā€ part of the datetime come from?

Iā€™m running OH on a Promox Debian Container (Bookworm), donā€™t know if that has something to do with it since I canā€™t find anyone else on the forum with this error when searching.

From the Item. When you update a DateTime Item and donā€™t provide the timezone, [SYSTEM] means use the default timezone of the system.

Do you have the helper library installed separately or are you using the built in library? This looks like an old bug in the helper library that has been fixed.

Updating OH will not update the helper library if youā€™ve installed it separately.

The error is almost certainly coming from this line:

              var mapped = startTimes.map(i => { return { 'state': i.getMetadata()[NAMESPACE].value,
                                                          'time' : time.toZDT(i.state).toToday() } });

You can try changing that to just time.toZDT(i).toToday() but that too had a bug in older versions of the helper library.