OH4: rule "when system started" starts, if rules or items became modified

a rule, which should be executed after OH-restart gets executed as well, if I modify (other) rules or edit items.
Why is that happening (since OH4)? With OH3.4.4 this never happened.

rule:

rule "System restart"
when System started
then
	logInfo("Restart", "Restart-Script is running...")
       ..do some stuff..

Is there a way to find out why this rule starts although OH is already up for hours or days?

log:

2023-07-31 10:38:31.211 [INFO ] [rg.openhab.core.model.script.Restart] - Restart-Script is running...
2023-07-31 10:42:54.750 [INFO ] [rg.openhab.core.model.script.Restart] - Restart-Script is running...
2023-07-31 10:44:36.404 [INFO ] [rg.openhab.core.model.script.Restart] - Restart-Script is running...

Because the behavior changed in OH 4. With the old behavior depending on the timing during startup, some rules would be missed. For example, if the rules engine was not available until startlevel 70, any rule with startlevel < 70 would never trigger. So the behavior was returned to the old OH 2.x behavior.

When the rule is loaded, if the startlevel has passed (no matter how long ago) the rule triggers. This results in a more deterministic and reliable startup behavior.

I think this was mentioned in the breaking changes. If not it definitely was included in the list of changes for OH 4.

Thanks for your answer Rich. Appreciated.
I read all releas notes (and the breaking chages) but maybe I missed something.

My problem is, that that this rule (“when System started”) is executed more than once.
The rule starts when OH is booting. That’s ok and intended.
But it’s weird for me that rule is executed again, when I just save an *.items or *.rules file in the (VisualStudio-) Editor.
This is by purpose as well? :roll_eyes:

Technically it is only executed once. When the rule is reloaded the old rule is destroyed and the new rule is created.

You can only have one or the other.

Either you can have the rule only trigger zero or one time based on the timing or have the rule trigger every time the rule is reloaded if the start level has already passed.

When you change a .items file, that forces a reload of the rules because when a .items file is reloaded, all the the Items defined by file are destroyed and then created anew which causes a reload of the rule. Otherwise the rule would not pick up the new Items to use as triggers.

The same goes for .rules files. Everything defined in the file gets destroyed and created anew.

1 Like

That explains it.
Thanks for that explanation, Rich! :smiley:

I have a rule with condition

System reached start level 50

which sends me an email.

In OH3 it was only executed once. Now it’s executed often. I didn’t change item files, I didn’t change rule files, I only deleted items I created interactively.

Is there a solution available that my mail is only sent after startup?

Is it being disabled and reenabled?

It should only run once unless there is something happening to cause the rule to be reloaded.

The rule is implemented in a rule file. And this file didn’t change. And I didn’t disable/reenable anything.
The only thing I did is removing interactively created items and a thing and I unistalled a binding.

Removing the Items would trigger the rule no matter how they are defined. And because they are removed individually the rule would be triggered once for each Item removed.

1 Like

I’m not 100% sure this is a technically correct description but it helps to think of when dealing with those startlevel rules.
Normal rules execute when there is a trigger upon an event i.e. some state variable changes value from A to B.
Startup rules “system started” or “System reached start level 70” are special they evaluate states. The runlevel didn’t change to 70, it is 70 by the time the system decides to run that rule (or evaluate the run condition, actually) which happens at startup and on items or rules files changes.

PS worth investigating If you can easily rewrite them to event triggered ones, haven’t tried myself

2 Likes

My OH 4.0.1 has I suspect a similar issue but please correct me if I’m mistaken.
When I’m editing rules in the UI normally when you click on “Execute a given script”
it opens the script so you can edit it.

This behaviour is different when the rule has the trigger “when the system has reached level 70”. In that case it runs the rule and you need to click several times to be able to open the scrip to edit, when you save it, it runs the rule again.
Removing the trigger will solve the problem so I made a work around with an extra item that sendsCommand ON to start my boot script to avoid editing the run with the “when the system reached level 70”. The extra rule to kick the full script rule has the same issue so hope reproducible.
Ps. The script is JS 11)

I’ve seen a similar behavior but have not had time to investigate further.

I would say this is a regression. The rule shouldn’t trigger unit a save. Merely clicking on a trigger, action, or condition to open it should not trigger the rule. An issue should be filed. I’d start with openhab-webuis.

1 Like

Hi Rich, Thanks I will.do that.

For me the behavior is a bit different (on oh 4.0.2), rule with “system started” executes only when I modify that .rules file where it was, if I edit other rules files or items, nothing.
So I’ve created a separate startup.rules file just for this one rule so it doesn’t trigger randomly when I’m editing some other rules.

hey guys, does this behavior only affect text files based rules? DSL only?
every time you edit a file, rules with “system started” triggers get executed?

what about rules created in UI? I have created a UI rule that executes my proxy DSL rule “system startup”. DSL text based proxy rule has a dummy trigger. it will never get executed, except when UI based rule runs it ( I have set the UI rule not to consider conditions of the targeted rule.
so far I think it does not “fire at will”. i have saved few files, and nothing happened.
is it a good workaround? for people who only want to run the rule once the system really started?

this is the code of the UI rule

configuration: {}
triggers:
  - id: "1"
    configuration:
      startlevel: 80
    type: core.SystemStartlevelTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      considerConditions: false
      ruleUIDs:
        - scenes-3
    type: core.RunRuleAction

No, it’s just less pronounced when using managed rules.

All rules languages.

Yes, same behavior. However it’s less pronounced because there are no files. So you won’t have a case where you change the label of one Item in a file and all of the Items in that file get destroyed and recreated meaning all the rules in any file with just one rule that uses any of those Items in that file also need to be reloaded. And because figuring out which files reference which Items is not a trivial task, I think OH just reloads everything.

With managed configs, each entity stands on it’s own. So if you change one Item, only stuff that directly interact with that Item are impacted. And because the Item isn’t destroyed and recreated any rules or widgets that use that Item do not need to be reloaded.

But, if you modify a system started rule in the UI, that rule will be reloaded when you save and it will immediately run because the system runlevel has passed.

Probably not because I think any change to the .items file will cause that rule to reload too.

Using managed Items would probably work though. Modifying those won’t trigger a reload of the rules since the Items are not being destroyed and recreated in mass like they are with file based Items. If Items and Rules are managed, in my experience, the system started rules only run again when you mess with them (i.e. on a save) and if you’ve changed the rule you probably want it to run again anyway.