Time Based State Machine [4.0.0.0;4.9.9.9]

here is the configuration from code-tab, and a little bit more:

configuration:
  namespace: tsm
  timesOfDayGrp: Tageszeiten
  timeOfDay: Tageszeit
triggers:
  - id: "1"
    configuration:
      groupName: Tageszeiten
    type: core.GroupStateChangeTrigger
  - id: "2"
    configuration:
      startlevel: 100
    type: core.SystemStartlevelTrigger
  - id: "4"
    configuration:
      time: 00:05
    type: timer.TimeOfDayTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/javascript
      script: >
        // Version 0.4

Version number is 0.4

lines 82-85

var getItemsOfType = (type) => {
  const allItems = items[DT_GROUP].members;
  return allItems.filter( item => item.getMetadata()[NAMESPACE].configuration['type'] == type);
};

I’m running exactly the same code and I cannot reproduce the error. I once saw something similar in another rule but it went away without my needing to do anything.

Based on nothing at all, try to replace those lines 82-85 with the following:

var getItemsOfType = (type) => {
  const allItems = items[DT_GROUP].members;
  return allItems.filter( item => { return item.getMetadata()[NAMESPACE].configuration['type'] == type });
};

It does not change anything. The message stays the same.

I’m starting all over again.

  • openHABian image on SD card
  • Have openHAB installed
  • go through setup with JS scripting installation
  • install the openhab_rules_tools in openhabian-config
  • Install the TimeMachine template
  • Create items and rules

then it must work, right?
These are the same steps I took yesterday.

I don’t know because I cannot fathom what could be wrong. If that doesn’t change anything change that function to the following:

var getItemsOfType = (type) => {
  const allItems = items[DT_GROUP].members;
  return allItems.filter( item => { 
    console.info('Item: ' + item.name + ' namespace: ' + NAMESPACE + ' md: ' + item.getMetadata() + ' md[ns]: ' + item.getMetadata()[NAMESPACE]);
    return item.getMetadata()[NAMESPACE].configuration['type'] == type 
  });
};

this is the result

2023-08-30 08:43:43.980 [DEBUG] [omation.rules_tools.TimeStateMachine] - Validating Item types, Item metadata, and Group membership
2023-08-30 08:43:44.026 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Vorabend is valid
2023-08-30 08:43:44.043 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Nacht is valid
2023-08-30 08:43:44.055 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Abend is valid
2023-08-30 08:43:44.065 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Tag is valid
2023-08-30 08:43:44.075 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Morgen is valid
2023-08-30 08:43:44.085 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Tag is valid
2023-08-30 08:43:44.094 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Nacht is valid
2023-08-30 08:43:44.104 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Vorabend is valid
2023-08-30 08:43:44.113 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Tag is valid
2023-08-30 08:43:44.124 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Nacht is valid
2023-08-30 08:43:44.134 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Morgen is valid
2023-08-30 08:43:44.145 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Morgen is valid
2023-08-30 08:43:44.154 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Abend is valid
2023-08-30 08:43:44.163 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Abend is valid
2023-08-30 08:43:44.173 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Vorabend is valid
2023-08-30 08:43:44.195 [INFO ] [omation.rules_tools.TimeStateMachine] - All tsm Items are configured correctly
2023-08-30 08:43:44.261 [INFO ] [omation.rules_tools.TimeStateMachine] - Item: TZ_Woche_Vorabend namespace: tsm md: [object Object] md[ns]: [object Object]
2023-08-30 08:43:44.277 [INFO ] [omation.rules_tools.TimeStateMachine] - Item: Tageszeit namespace: tsm md: [object Object] md[ns]: undefined
2023-08-30 08:43:44.286 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job 'ui.e2ea68fe61.debounce' failed and stopped
org.graalvm.polyglot.PolyglotException: TypeError: Cannot read property "configuration" from undefined
	at <js>.:=>(<eval>:86) ~[?:?]
	at <js>.getItemsOfType(<eval>:84) ~[?:?]
	at <js>.validateAllConfigs(<eval>:124) ~[?:?]
	at <js>.createTimersGenerator(<eval>:205) ~[?:?]
	at <js>.:=>(/etc/openhab/automation/js/node_modules/openhab_rules_tools/timerMgr.js:66) ~[?:?]
	at com.oracle.truffle.polyglot.PolyglotFunctionProxyHandler.invoke(PolyglotFunctionProxyHandler.java:154) ~[?:?]
	at jdk.proxy1.$Proxy202.run(Unknown Source) ~[?:?]
	at org.openhab.automation.jsscripting.internal.threading.ThreadsafeTimers.lambda$0(ThreadsafeTimers.java:85) ~[?:?]
	at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$12(SchedulerImpl.java:189) ~[?:?]
	at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$1(SchedulerImpl.java:88) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]

Hi,
I found the mistake. The TimeOfDay item was also in the TimeOfDays group.
sorry.

1 Like

Aha! I didn’t pick that up when I looked at the Items. I’ll add a check for that in the validation code so it produces a better error message.

It’s still a little weird though because I would have been expected that to have been caught by the call to checkGrpAndMetadata. It should have complained that the time of day Item doesn’t have the metadata. So I might need to add a new check and figure out why it wasn’t caught there in the first place.

But now at least I have something to go on and can improve the template.

Thanks!

Edit: I found the bug (two bugs actually) but it’s in the OHRT library. A fix will be included in the next release but this is low impact so I want to get a few more changes into OHRT before I cut another release.

Hello,
me again.
The template has gone through wonderfully for the last n days and has worked flawlessly. Today I wanted to adjust that so that Friday_night has a different time than weekdays.
I have added the following entry to ephemeris.cfg (and restart openhab):

country=de
region=th
dayset-weekday=Monday,Tuesday,Wednesday,Thursday,Friday
dayset-weekend=Saturday,Sunday
dayset-friday=Friday
dayset-sunday=Sunday

Then I created these items and assigned the appropriate times to the morning and night time:

DateTime  TZ_Freitag_Nacht  "Freitag Nacht"  <time>  (Tageszeiten) { tsm="NIGHT"[type="dayset",set="friday"] }
DateTime  TZ_Freitag_Morgen "Freitag Morgen" <time>  (Tageszeiten) { tsm="MORNING" [type="dayset",set="friday"] }
DateTime  TZ_Freitag_Tag "Freitag Tag"  <time>  (Tageszeiten) { channel="astro:sun:local:rise#start", tsm="DAY"[type="dayset",set="friday"] }
DateTime  TZ_Freitag_Vorabend "Freita Vorabend"  <time>  (Tageszeiten) { channel="astro:sun:local:civilDusk#start", tsm="TWILIGHT"[type="dayset",set="friday"] }
DateTime  TZ_Freitag_Abend "Freitag Abend"  <time>  (Tageszeiten) { channel="astro:sun:local:set#start", tsm="EVENING"[type="dayset",set="friday"] }

Now Rule spits out error messages again:

2023-09-01 16:52:23.388 [DEBUG] [omation.rules_tools.TimeStateMachine] - Starting state machine in ten seconds...
2023-09-01 16:52:33.416 [DEBUG] [omation.rules_tools.TimeStateMachine] - Validating Item types, Item metadata, and Group membership
2023-09-01 16:52:33.462 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Freitag_Abend is valid
2023-09-01 16:52:33.474 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Freitag_Nacht is valid
2023-09-01 16:52:33.483 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Vorabend is valid
2023-09-01 16:52:33.492 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Nacht is valid
2023-09-01 16:52:33.501 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Abend is valid
2023-09-01 16:52:33.511 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Tag is valid
2023-09-01 16:52:33.520 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Morgen is valid
2023-09-01 16:52:33.529 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Freitag_Vorabend is valid
2023-09-01 16:52:33.538 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Tag is valid
2023-09-01 16:52:33.546 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Nacht is valid
2023-09-01 16:52:33.551 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Vorabend is valid
2023-09-01 16:52:33.558 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Tag is valid
2023-09-01 16:52:33.564 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Freitag_Tag is valid
2023-09-01 16:52:33.570 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Nacht is valid
2023-09-01 16:52:33.576 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Freitag_Morgen is valid
2023-09-01 16:52:33.582 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Morgen is valid
2023-09-01 16:52:33.588 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Morgen is valid
2023-09-01 16:52:33.593 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Woche_Abend is valid
2023-09-01 16:52:33.599 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Wochenende_Abend is valid
2023-09-01 16:52:33.606 [DEBUG] [omation.rules_tools.TimeStateMachine] - TZ_Default_Vorabend is valid
2023-09-01 16:52:33.622 [INFO ] [omation.rules_tools.TimeStateMachine] - All tsm Items are configured correctly
2023-09-01 16:52:34.021 [DEBUG] [omation.rules_tools.TimeStateMachine] - All tsm Items are configured correctly
2023-09-01 16:52:34.023 [DEBUG] [omation.rules_tools.TimeStateMachine] - Cancelling existing timers
2023-09-01 16:52:34.026 [DEBUG] [omation.rules_tools.TimeStateMachine] - Acquiring today's state start times
2023-09-01 16:52:34.128 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job 'ui.ba18028dd1.debounce' failed and stopped
org.graalvm.polyglot.PolyglotException: TypeError: (intermediate value).getMetadata is not a function
	at <js>.:=>(<eval>:161) ~[?:?]
	at <js>.getTodayItems(<eval>:161) ~[?:?]
	at <js>.createTimersGenerator(<eval>:211) ~[?:?]
	at <js>.:=>(/etc/openhab/automation/js/node_modules/openhab_rules_tools/timerMgr.js:66) ~[?:?]
	at com.oracle.truffle.polyglot.PolyglotFunctionProxyHandler.invoke(PolyglotFunctionProxyHandler.java:154) ~[bundleFile:?]
	at jdk.proxy1.$Proxy230.run(Unknown Source) ~[?:?]
	at org.openhab.automation.jsscripting.internal.threading.ThreadsafeTimers.lambda$0(ThreadsafeTimers.java:85) ~[bundleFile:?]
	at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$12(SchedulerImpl.java:189) ~[?:?]
	at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$1(SchedulerImpl.java:88) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]

If I delete the Friday items, the rule runs correctly again.
What am I doing wrong?

This time the door is occurring in a different place. I’ll have to run some tests and I might need to have you add another logging statement if I can’t reproduce it.

Hello Rich,
first of all thank you very much for the rule-template. It does what it’s supposed to.
But unfortunately it doesn’t work the way I would like it to. It would be nice if a little more “intelligence” found its way into it. You focus on exactly one day and then use a few criteria to decide which time of day should start at what time.
My focus is a little different. I would look what day is today, what day is tomorrow.
If tomorrow is a holiday or weekend, then today is to be taken as night time on the weekend rate. If it is a weekend or holiday and tomorrow is a work day, then the night time of the weekday should be used. Also, I’m missing a check to see if the time for the morning is after the time for the day. Then of course the time of day should not change from day to morning like today.
On weekdays, my morning starts at 5:30 am and turns on appropriate lights. After sunrise, the lighting is switched off again. On the weekend my morning is at 7:30am, sunrise was 6:15am. So 6:15 was switched to day and 7:30 to morning and the lights stayed on.
In my production system, this works with modified scripts from you, but unfortunately not with the TimeStateMachine.
I will now have to learn JS scripting in order to be able to implement my requirements. A home automation system should be able to do something like this by itself.
I am grateful for ideas and am available for tests and brainstorming. :wink:

I went down that path for a bit once. This rule template is already super complicated all things considered. To implement all of these additional requirements would require an overall completely different approach and the complexity in both the template code and the configuration on the end user will explode.

Some considerations:

  • how is the rule supposed to know that it’s supposed to pay attention to tomorrow or not? Which “tomorrow’s” are important? How does the end user tell this to the rule?
  • how is the rule supposed to know the order you intend the events to occur and skip one? All it knows now is the date time. It doesn’t know the order of the events outside the date times.

It probably wouldn’t be too complex to start the state machine at noon instead of midnight. But that would potentially be a breaking change. I’d have to think about that.

Hi,
I would integrate an “advanced mode” switch into the template. If this switch is not activated, the template works as before.
If the switch is activated, the times would have to be preprocessed. All times are copied accordingly into the default items and the template now only works with the times of the default items.
Copying and sorting from weekday and weekend in default will be the challenge.

I’ll check if the template works reliably when only the default items are present. If this works, I’ll build a script that copies the times into the items according to my wishes. Then you wouldn’t have to change anything.
If all this doesn’t work properly, I’ll try to port my current script to JS scripting.
Many thanks for your effort.

PS
Can you please post me an example of items.replace related to TSM? I’d like to try something, but I’m failing because of the meta data for the TSM items.
Or how can I change the value tsm=“DAY” to tsm=“MORNING” and vice versa using JS script? That would help me a lot.
Thank you very much.

One challenge that occurred to me is you can’t really rely on any datetimes from Astro for tomorrow. Astro only calculates the times for the current day around midnight. So that has to be taken into account too. Especially as one gets closer to the poles, the difference in sunrise/sunset from day to day can be significant.

See Expire Updater [4.0.0.0;4.9.9.9] only you’ll use tsm instead of expire.

However based on what you describe you don’t need that. Just have the one set of default Items and in your rule update their states. Leave the metadata alone.

Thank you. I would like to adjust the metadata if the morning time is after the daytime.
I’m currently building the script, which inserts the times into the default items according to my requirements. It is then checked whether the morning time is later than the day time. If so, tsm should be set to day, otherwise to morning. Then your TSM will be executed with the default values. Let’s see if that works.

With the metadata it would/could work.
Sunrise sets the time of day to day for me. The morning time sets the time of day to morning (week 05:30 and weekend 07:30). How can I prevent the morning status of the time of day from being/can be set after the day status?
Idea 1:
If the time for morning is later than the time for day, then set the metadata for morning to Day_Late and include that value in the evaluation script that starts the actions by time of day, or
Idea 2:
Set the time for morning to 2s before the time for the day and build a timer of 5s into the evaluation rule, which prevents unnecessary actions.

What would be the better approach for you?

This is my Rule for idea 2 for the weekend-test :wink:

var RuleName = 'Zeiten';
var debugLevel = 2;

console.loggerName = 'org.openhab.automation.rules.' + RuleName;

if (debugLevel == 1 )
  {
    osgi.getService('org.apache.karaf.log.core.LogService').setLevel(console.loggerName, 'DEBUG');
  }
else if ( debugLevel == 2)
  {
    osgi.getService('org.apache.karaf.log.core.LogService').setLevel(console.loggerName, 'TRACE');
  }
else
  {
    osgi.getService('org.apache.karaf.log.core.LogService').setLevel(console.loggerName, 'INFO');
  }  

console.debug("***** Rule '" + RuleName + "' gestartet *****");

if (actions.Ephemeris.isBankHoliday() == true) {
  console.debug('Heute ist Feiertag');
  items.TZ_Default_Morgen.postUpdate(items.TZ_Wochenende_Morgen.state.toString());
}
else if (actions.Ephemeris.isWeekend() == true) {
  console.debug('Heute ist Wochenende');
  items.TZ_Default_Morgen.postUpdate(items.TZ_Wochenende_Morgen.state.toString());
}
else {
  console.debug('Heute ist ein Wochentag');
  items.TZ_Default_Morgen.postUpdate(items.TZ_Woche_Morgen.state.toString());
}
if (actions.Ephemeris.isBankHoliday(1) == true) {
  console.debug('Morgen ist Feiertag');
  items.TZ_Default_Nacht.postUpdate(items.TZ_Wochenende_Nacht.state.toString());
}
else if (actions.Ephemeris.isWeekend(1) == true) {
  console.debug('Morgen ist Wochenende');
  items.TZ_Default_Nacht.postUpdate(items.TZ_Wochenende_Nacht.state.toString());
}
else {
  console.debug('Morgen ist ein Wochentag');
  items.TZ_Default_Nacht.postUpdate(items.TZ_Woche_Nacht.state.toString());
}

var Morgen = items.TZ_Default_Morgen.state;
var Tag = items.TZ_Default_Tag.state;

if (time.toZDT(Morgen).isAfterTime(time.toZDT(Tag))) {
  console.debug('Morgen-Zeit ist nach Sonnenaufgang');
  var NewTime=time.toZDT(Tag).MinusSeconds(3);
  items.TZ_Default_Morgen.postUpdate(NewTime.toString);
  console.debug('Setze neue Morgen-Zeit auf : ' + NewTime.toString());
}
else {
  console.debug('Morgen-Zeit ist vor Sonnenaufgang')
}

console.debug("***** Rule '" + RuleName + "' beendet *****");

There could be other options too.

  • set the config of the Astro Channel so that Channel that’s linked to the DAY Items with an “earliest” and “latest” properties to prevent it from occurring before the MORNING event (probably doesn’t work in this specific use case but it can work in others)

  • Handle the MORNING state in some other rule based on some other event. For example, I don’t have MORNING in my Time State Machine Items. I have a separate rule that is triggered by my alarm time and it will only set the state to MORNING if it’s appropriate to do so (i.e. current state is BED or NIGHT). No alarm or if it’s after DAY, there will be no MORNING state in the first place.

I might suggest that handling MORNING outside the state machine rule might be the easiest approach over all.

One of my overall philosophies for rule templates is that these are merely building blocks. Many of them don’t even do anything useful on their own and depend on some custom script that gets called to do the actual work.

Maybe this could be a similar case. Let this template handle most of the time states but because MORNING is complicated, just move that into a separate rule. Writing a rule that handles MORNING independently is easier than trying to change metadata or adjust the DateTime Item’s states on the fly.

Here is my MORNING state rule:

configuration: {}
triggers:
  - id: "2"
    configuration:
      thingUID: mqtt:topic:broker:sleepasandroid
      event: alarm_alert_start
      channelUID: mqtt:topic:broker:sleepasandroid:event
    type: core.ChannelEventTrigger
conditions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/javascript
      script: |-
        var curr = items.TimeOfDay.state;

        curr == 'NIGHT' || curr == 'BED'
    type: script.ScriptCondition
actions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/javascript;version=ECMAScript-2021
      script: >-
        var { Deferred } = require('openhab_rules_tools');


        var hour = time.toZDT().hour();

        var currToD = items.TimeOfDay.state;


        console.debug('Current ToD = {} Current Hour = {}', currToD, hour);


        // Puppy lights

        if(currToD == 'NIGHT' || time.toZDT().isBefore(time.toZDT('04:45'))) {
          console.info("The alarm went off and it's night time, turning on the lights for five minutes");
          items.TOD_Lights_ON_MORNING.sendCommand('ON');
          Deferred().defer('TOD_Lights_ON_MORNING', 'OFF', 'PT5M', true);
        }

        // MORNING TIME

        else if(currToD == 'BED'){
          console.info('Good morning!');
          items.TimeOfDay.sendCommand('MORNING');
        }

        // Should never reach this becuase of the rule template

        else {
          console.warn("The alarm went off but it's not BED or NIGHT")
        }
    type: script.ScriptAction

It’s a little more complex than it needs to be because when I wrote I we had a puppy who needed to go out to potty in the middle of the night so I’d only keep the lights on for five minutes instead of transitioning to MORNING in those cases. I don’t need that anymore and probably should remove it.

Without that logic it’s a simple one-liner to send MORNING to TimeOfDay. The Condition handles making sure it only sends MORNING when it’s appropriate (i.e. not when it’s already DAY.

The rule template already has a timer built in so that it waits for it’s Items to stop updating before actually running. This ensures, for example, that when Astro updates all its Items around midnight the rule doesn’t run more than once all the way through.

Be careful setting the log level every time a rule runs. If another rule happens to be setting it’s level at the same time you can end up with an empty log4j2.xml file.

This seems awfully convoluted. Why create a separate “debugLevel” with an if/else if and not just set the logging level directly?

There is an implicit variable ruleUID which is the unique identifier for the rule. It’s often more useful to use that because you can actually search for that on the Rules and Scripts pages in MainUI.

You don’t need to have == true. If the function returns true the == true is understood.

You don’t need to call toString() on .state, it’s already a String.

I prefer a 1-2-3 structure for code like this.

// 1. determine if there is anything to do, in this case always do the steps

// 2. calculate what to do
var dayType = 'Woche';
if(actions.Ephemeris.isBankHolidaty() || actions.Ephemeris.isWeekend()) {
  dayType =  = 'Wochenende';
}

// 3. do it
items.TZ_Default_Morgen.postUpdate(items['TZ_'+dayType+'_Morgen'].state);
items.TZ_Default_Nacht.postUpdate(items['TZ_'+dayType+'_Nacht'].state);

You just potentially updated this Item. It might not yet have become the updated state yet.

The whole script as I would write it…

// By default the logger name will be `org.openhab.automation.rules.ruleUID`

// Uncomment and change the level to change the logging level. Comment back out  after the rule runs.
// osgi.getService('org.apache.karaf.log.core.LogService').setLevel(console.loggerName, 'DEBUG'); 

console.debug("***** Rule '" + ruleUID + "' gestartet *****");

// 1. Determine if there is anything to do
// Often it's appropriate to add this part as a script condition to the rule

// 2. Calculate what to do
var dayType = 'Woche';
if(actions.Ephemeris.isBankHolidaty() || actions.Ephemeris.isWeekend()) {
  dayType =  = 'Wochenende';
}

var morningTime = time.toZDT(items['TZ_'+dayType+'_Morgen]); // converts Item to ZDT
var dayTime = time.toZDT(items['TZ_Default_Tag']);
if(morningTime.isAfter(dayTime)) {
  console.debug('Morgen-Zeit ist nach Sonnenaufgang');
  morningTime = dayTime.minusSeconds(3);
  console.debug('Setze neue Morgen-Zeit auf : ' + morningTime.toString());
}
else {
  console.debug('Morgen-Zeit ist vor Sonnenaufgang');
}

// 3. Do it
items.TZ_Default_Nacht.postUpdate(items['TZ_'+dayType+'_Nacht].state);
items.TZ_Default_Morgen.postUpdate(morningTime.toString());

console.debug("***** Rule '" + ruleUID + "' beendet *****");

Hi, thank you very much for your very interesting input. I will take your suggestions and modify the rules accordingly. Especially when I see how much shorter and clearer your code is. I will remove the morning time from the TSM and set the timer for it according to my requirements using a separate rule.
Thank you again for your patience.

I am getting the following error when the rule executes.

2023-10-04 20:01:34.032 [DEBUG] [omation.rules_tools.TimeStateMachine] - All tsm Items are configured correctly
2023-10-04 20:01:34.034 [DEBUG] [omation.rules_tools.TimeStateMachine] - Cancelling existing timers
2023-10-04 20:01:34.038 [DEBUG] [omation.rules_tools.TimeStateMachine] - Acquiring today’s state start times
2023-10-04 20:01:34.664 [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

What does it mean?

If you look above someone else had a similar problem which was caused by including the TineOfDay String Item into the TimesOfDay Group.

However, I added additional checking to test for that since then. Are you running with the latest OHRT?

I do not have the string in the TimesOfDay group.

I have update the openhab-js and the openhab_rules_tools below is the versions I am running.

It would not work at all until I got the helper packages update.

{
  "dependencies": {
    "openhab": "^4.6.0",
    "openhab_rules_tools": "^2.0.3"
  }
}

Any other thoughts?