Skip to content

Add source to StartLevel event#5189

Open
TheNetStriker wants to merge 1 commit intoopenhab:mainfrom
TheNetStriker:StartlevelEventSource
Open

Add source to StartLevel event#5189
TheNetStriker wants to merge 1 commit intoopenhab:mainfrom
TheNetStriker:StartlevelEventSource

Conversation

@TheNetStriker
Copy link

Title

  • Add source to StartLevel event.

Description

This pull request add's a source to the StartLevel event. With this rules can distinguish between events from the StartLevelService and events from the RuleEngine after a rule was changed.

I had this idea after a discussion in the following issue: #5177

There is also an open question why the org.openhab.core.automation bundle always sends the startlevel event 40 after saving a rule.

@TheNetStriker TheNetStriker requested a review from a team as a code owner December 14, 2025 14:14

private final Map<String, WrappedRule> managedRules = new ConcurrentHashMap<>();

public static final String RULEENGINEIMPL_SOURCE = "org.openhab.core.automation.internal.RuleEngineImpl";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to hardcode this, and that RuleEngineImpl.class.getName() will give the same result.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hint. I've just changed that.


public static final String STARTLEVEL_MARKER_TYPE = "startlevel";

public static final String STARTLEVELSERVICE_SOURCE = "org.openhab.core.service.StartLevelService";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same as above

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hint. I've just changed that.

@TheNetStriker
Copy link
Author

TheNetStriker commented Dec 14, 2025

@Nadahar I just realized that the executeRulesWithStartLevel is also called on startup and send's the startlevel 40 that was missed because the rule engine was not yet initialized. Maybe there should also be a different source for this event so that the rules can distinguish between those two events.

I could just add the name of the method to class.getName() or is there a better way to do this?

I guess this could also explain the problem with multiple events you mentioned in the issue: #5177

Edit: I've just added the method name as a string. This way the rule can distinguish between all the events:

Those are the events after startup with my changes:
17:19:29.718 [ERROR] [org.openhab.core.automation.examples] - Startlevel '40' reached. org.openhab.core.automation.internal.RuleEngineImpl.executeRulesWithStartLevel
17:19:29.719 [INFO ] [e.automation.internal.RuleEngineImpl] - Rule engine started.
17:19:34.351 [ERROR] [org.openhab.core.automation.examples] - Startlevel '70' reached. org.openhab.core.service.StartLevelService
17:19:34.351 [ERROR] [org.openhab.core.automation.examples] - Startlevel '80' reached. org.openhab.core.service.StartLevelService
17:19:34.352 [ERROR] [org.openhab.core.automation.examples] - Startlevel '100' reached. org.openhab.core.service.StartLevelService

And this is the event after saving a rule:
17:20:42.420 [INFO ] [openhab.event.RuleUpdatedEvent      ] - Rule 'test' has been updated.
17:20:42.881 [ERROR] [org.openhab.core.automation.examples] - Startlevel '40' reached. org.openhab.core.automation.internal.RuleEngineImpl.activateRule

This pull request adds an event source to the StartLevel event. With this rules can distinguish between events from the StartLevelService and events from the RuleEngine after a rule was changed.

Signed-off-by: TheNetStriker <david@masshardt.ch>
@Nadahar
Copy link
Contributor

Nadahar commented Dec 14, 2025

As I've said before, I don't have the full overview, but yes, there is a situation where multiple events are sent. They might very well originate from "different sources", but even if one can differentiate the source, I'm not sure that it's a good design to expect the users to handle multiple such events during startup.

@Nadahar
Copy link
Contributor

Nadahar commented Dec 14, 2025

I think somebody else should weigh in here, because I don't know if it's reasonable to expect the user to "know" the difference between the different sources and how to handle them. @florian-h05 @rkoshak ? (please tag others that might "fit")

@rkoshak
Copy link

rkoshak commented Dec 15, 2025

There are a whole bunch of PRs recently, mostly by @ccutrer, which adds the source to the event. This seems like an extension of that work. But I don't know if that work is limited to just Item events.

Having the source of the events is largely something new I think it will open up a lot of opportunities for users (e.g. did the command come from my phone or from a rule?) and the natural expectation would be that they would have similar origin information for the system started events too if these events can come from different sources.

But I don't know from a practical perspective how easy that will be to use and understand by the end users.

@Nadahar
Copy link
Contributor

Nadahar commented Dec 15, 2025

Having the source of the events is largely something new I think it will open up a lot of opportunities for users (e.g. did the command come from my phone or from a rule?) and the natural expectation would be that they would have similar origin information for the system started events too if these events can come from different sources.

I absolutely see the usefulness of having a source with events, as long as there's an easy way to anticipate how to identify a given source. If this is to be based on whatever string the individual implementer chooses, and basically has to be tested to know what the values will look like, I think it might be of limited worth, and potentially cause much frustration both when things change or when different "regimes" clash. But, if the identifiers are easily resolvable/deducible and unique, I think it could be great.

@ccutrer
Copy link
Member

ccutrer commented Dec 15, 2025

But I don't know from a practical perspective how easy that will be to use and understand by the end users.

(usefully) populating source is useful in two areas:

  • in events.log, so you can see what caused something in that log (not applicable to StartLevel events, since it's not logged by default)
  • in rules, the source is available on the event object, and can be used to behave differently depending on the cause of the event. this seems like it could be useful for StartLevel events.

As I've said before, I don't have the full overview, but yes, there is a situation where multiple events are sent. They might very well originate from "different sources", but even if one can differentiate the source, I'm not sure that it's a good design to expect the users to handle multiple such events during startup.

Agreed. If a rule is being triggered multiple times for the same start level (without other oddness like purposely lowering and then raising the start level somehow), I would consider that a bug in core, and not something a user should be working around by checking the event source.

EDIT:

I absolutely see the usefulness of having a source with events, as long as there's an easy way to anticipate how to identify a given source. If this is to be based on whatever string the individual implementer chooses, and basically has to be tested to know what the values will look like, I think it might be of limited worth, and potentially cause much frustration both when things change or when different "regimes" clash. But, if the identifiers are easily resolvable/deducible and unique, I think it could be great.

They should be, to some extent. See the guidelines.

runNow(rule.getUID(), true,
Map.of(SystemTriggerHandler.OUT_STARTLEVEL, StartLevelService.STARTLEVEL_RULES, "event",
SystemEventFactory.createStartlevelEvent(StartLevelService.STARTLEVEL_RULES,
RuleEngineImpl.class.getName() + ".activateRule")));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

event sources should generally be the package name, not the class name. so just org.openhab.core.automation here...

scheduler.submit(() -> {
StartlevelEvent startlevelEvent = SystemEventFactory.createStartlevelEvent(level);
StartlevelEvent startlevelEvent = SystemEventFactory.createStartlevelEvent(level,
StartLevelService.class.getName());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and org.openhab.core here

Map.of(SystemTriggerHandler.OUT_STARTLEVEL, StartLevelService.STARTLEVEL_RULES, "event",
SystemEventFactory.createStartlevelEvent(StartLevelService.STARTLEVEL_RULES))));
SystemEventFactory.createStartlevelEvent(StartLevelService.STARTLEVEL_RULES,
RuleEngineImpl.class.getName() + ".executeRulesWithStartLevel"))));
Copy link
Member

@ccutrer ccutrer Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and here (and don't add the method name; users shouldn't know or care, as commented on the PR itself) ...

@Nadahar
Copy link
Contributor

Nadahar commented Dec 15, 2025

They should be, to some extent. See the guidelines.

It says in the guidelines should be more than just the source package: <sending package>[$<actor>] or [=><sending package[$<actor>]]+ (not that I know how to interpret that syntax). How do you decide what actor is? I understand a bit more from the examples, but I think this definition is a big too vague and is likely to result in quite different "interpretations".

How often is the user known/relevant? That's probably first and foremost when things are triggered from myopenhab.org? Users in OH itself lacks so much implementation that I doubt anybody actually use it. I'd also say that just having org.openhab.core as a source is so generic that the value might be questionable.

@ccutrer
Copy link
Member

ccutrer commented Dec 15, 2025

Yes, there is some amount of interpretation. Feel free to open a PR in docs to refine it, if you think you can do so without being able to predict the future :). Those docs were written before much of the actual implementation was done, so at the least it may be useful to update some of the examples to more closely match what was implemented. The structure is still the same.

not that I know how to interpret that syntax

🤷 . Square brackets denote optional parts, + denotes one-or-more (similar to a regex), and angle brackets denote placeholders. It could probably be a proper regex, but I doubt that would help many people. Knowing how to name capture groups isn't exactly common knowledge. And there's not really any restrictions on characters for any of the placeholders, though that might be useful, but if we were to do that we'd want to update the source helper methods to escape disallowed characters.

How often is the user known/relevant?

Right now, any authenticated REST API request (so if a user is created in openHAB, and you log in with it), and anything coming through myopenhab.org.

There's a work-in-progress to identify the device or user for commands coming through via the HomeKit integration, but it's unclear if that would actually be useful.

Other use cases for actor:

  • The ESPHome binding (not in the main distro) allows end-devices to trigger commands in openHAB, and the actor is set to the name of the device triggering it.
  • The Android app is hopeful they'll be able to include a device ID as the actor, which will be included in the source string along with the myopenhab.org and/or REST API components when it gets to the rule.
  • The JRuby helper library includes the rule ID when triggering commands.

Users in OH itself lacks so much implementation that I doubt anybody actually use it

I don't disagree there, but chicken-and-egg. The more openHAB leverages users (the objects), the more users (the actual people) will use users (the objects). I've also kept in the back of my mind the possibility that this work on sources (with actors!) can be the basis of proper ACLs for items, which would make users far more useful. This is a long shot, and not fully thought through or vetted with others, so take it with a grain of salt.

For me personally, I only have one openHAB user, but I do have separate myopenhab.org users for each person in my household that their personal devices use to log in. I don't yet have a use for this in my rules, but at the least it's useful in event.log to see who triggered something.

I'd also say that just having org.openhab.core as a source is so generic that the value might be questionable.

Keep in mind that org.openhab.core is a specific package, and isn't the entire openhab-core repository. It's like the core-of-core. So it's more specific than you think. In the context of this PR, it's probably useful to document somewhere what sources are possible for the StartLevel event. I'm not sure where, though... can the event object be accessed in DSL rules? Otherwise, in the documentation for the respective languages helper libraries is probably best.

@Nadahar
Copy link
Contributor

Nadahar commented Dec 15, 2025

Feel free to open a PR in docs to refine it, if you think you can do so without being able to predict the future :). Those docs were written before much of the actual implementation was done, so at the least it may be useful to update some of the examples to more closely match what was implemented.

I'm not suggesting that I have a better definition, certainly not when only being aware of the topic for a few minutes. My observation was more about it actually being predictable, and perhaps also parsable. Such things are never easy to define, but at the same time, shortcomings in the initial definition can often limit what it can be used for down the road. I'm thinking that maybe it could be a "tagging system" within the string that allowed defining different kind of (optional) "identifiers", like rule ID, user ID, device ID etc. in a way that would make them possible to parse from the string. It could also make it possible to only match the "part" you're interested in when reacting to an event source.

Square brackets denote optional parts, + denotes one-or-more (similar to a regex), and angle brackets denote placeholders. It could probably be a proper regex, but I doubt that would help many people. Knowing how to name capture groups isn't exactly common knowledge. And there's not really any restrictions on characters for any of the placeholders, though that might be useful, but if we were to do that we'd want to update the source helper methods to escape disallowed characters.

Expressing such syntax is always difficult IMO, regex simply isn't a suitable tool (because it's designed for matching, not for defining), but at the same time, it's often the closest thing we have that is somewhat familiar. But, regex isn't familiar to everybody, and I'd call it quite "hostile" to anybody that doesn't already know it. These descriptions are close enough in syntax to regex that I "try to read them as regex", but that fails, so I end up being confused. In particular, I'm confused by => and $ and don't know if they are literals or should be interpreted.

There does exist formalized notations for such things, but I've never found them very easy to read either. I think EBNF is what I've come across most often, since it's used in ISO/IEC standards.

Other use cases for actor:

Yes, this makes "actor" somewhat of a "free for all", where it can represent a user, a device, a rule etc. This might end up being a problem when peope want to parse/react to sources, both because you can have overlap/potential collision, and because there's no way to e.g specify both a user and a device, should the need arise.

I don't disagree there, but chicken-and-egg. The more openHAB leverages users (the objects), the more users (the actual people) will use users (the objects). I've also kept in the back of my mind the possibility that this work on sources (with actors!) can be the basis of proper ACLs for items, which would make users far more useful. This is a long shot, and not fully thought through or vetted with others, so take it with a grain of salt.

I'm not arguing that it shouldn't be part of the source, I'm just pointing out that it probably has very limited value as of now. I've also had some thoughts on how to do things with users and permissions, but it's a large undertaking, and it can be so difficult to get consensus on much simpler things in OH, so I'm not overly eager to attempt one of these larger ones.

For me personally, I only have one openHAB user

It's the same with me, and I suspect, for almost everybody else. I did look at what's there some years ago, and basically decided that it was too much hassle for too little gain to try to operate with users in OH as it is now.

Keep in mind that org.openhab.core is a specific package, and isn't the entire openhab-core repository. It's like the core-of-core. So it's more specific than you think.

I'm well aware of that, but that package contains a lot of stuff. This isn't consistent either, Things have their own package, Items don't, and they, together with auth, events, types, dimensions, units++ live in org.openhab.core. I'm not saying that everything there is relevant as event sources, I'm just saying that this specific package doesn't tell you that much about "where it came from", even if you know the codebase quite well. If you don't, it certainly won't tell you much.

@ccutrer
Copy link
Member

ccutrer commented Dec 15, 2025

Some attempt at clarifying and updating docs (I avoided any sort of "grammar" at all for the format): openhab/openhab-docs#2611

Yes, this makes "actor" somewhat of a "free for all", where it can represent a user, a device, a rule etc. ... there's no way to e.g specify both a user and a device, should the need arise.

Indeed. Which is fully intended - the actor only makes any sense within the scope of the bundle using it. In other words, the bundle portion of the source itself is the "tag" you're referring to. For the "both a user and a device" case, that would be up to that particular bundle to define it. In the updated examples, you can see that BasicUI uses : in the actor to separate the sitemap name from the particular page you're on.

The intention is that at some point if someone wants to parse these things, you first split on => to get each component, then for each component split on the first $ to separate bundle from actor. Then look through for the bundle you care about, and look at its actor if you care about actor.

Also keep in mind that up to this point source has always existed on Event, and some things have sent it (like AutoUpdateManager), and there have never been any guidelines at all.

@TheNetStriker
Copy link
Author

@ccutrer The reason I did include the method name in the source was because I wanted to distinguish between an event from activateRule and executeRulesWithStartLevel. (activateRule gets called only on startup after the automation system has started up and executeRulesWithStartLevel is executed when a rule is saved)

Let me explain the problem I'm having there:

  • executeRulesWithStartLevel always send's the fixed startlevel 40. But because this event is only sent on startup right after the automation system has started up this is fine.
  • activateRule also always send's startlevel 40 for some reason. I suppose when this was implemented with Fix rule startlevel trigger executes during initialization #3717 this startlevel was simply copied from executeRulesWithStartLevel. But this makes no sense to me because when I'm changing a rule after startup it always gets triggered with startlevel 40 as payload although OpenHab is already at startlevel 100.
  • In the DSL rules after changing such a rule it get's trigged once for every configured startlevel from 20 up to 100.

I don't know if the fixed startlevel in activateRule was set intentionally, but I don't see a reason for this behaviour. Maybe you can explain this.

In my opinion, this should work exactly the same way as the DSL rules. I already did some testing and came up with the following method to send the startlevel there:

// check if we have to trigger because of the startlevel
List<Trigger> slTriggers = rule.getTriggers().stream().map(WrappedTrigger::unwrap)
        .filter(t -> SystemTriggerHandler.STARTLEVEL_MODULE_TYPE_ID.equals(t.getTypeUID())).toList();
slTriggers.stream()
        .filter(t -> ((BigDecimal) t.getConfiguration().get(SystemTriggerHandler.CFG_STARTLEVEL))
                .intValue() <= startLevelService.getStartLevel())
        .sorted(Comparator.comparingInt(
                t -> ((BigDecimal) t.getConfiguration().get(SystemTriggerHandler.CFG_STARTLEVEL)).intValue()))
        .forEach(t -> {
            int triggerStartLevel = ((BigDecimal) t.getConfiguration().get(SystemTriggerHandler.CFG_STARTLEVEL))
                    .intValue();
            runNow(rule.getUID(), true,
                    Map.of(SystemTriggerHandler.OUT_STARTLEVEL, triggerStartLevel, "event",
                            SystemEventFactory.createStartlevelEvent(triggerStartLevel,
                                    "org.openhab.core.automation")));
        });

This method iterates through every startlevel trigger of the rule, sorts them ascending and executes the rule with the specific startlevel as payload in the right order. After a short test this worked fine, but I guess there should also be a check if the configured startlevel is a legit startlevel.

But even with this method it would still be nice to distinguish between those two methods because I e.g. use those events to set the current startlevel to an Item. After saving the rule the startlevel does not really change and it would be nice if there was a way to just ignore those events.
Maybe the event in executeRulesWithStartLevel could also be triggered with org.openhab.core as a source because the reason this method exists is that the automation bundle get's loaded after startlevel 40 and this just seems to be the way to forward this missed event to the rule.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a source parameter to StartLevel events to enable rules to distinguish between events originating from the StartLevelService and events from the RuleEngine (e.g., after a rule is modified). This addresses the issue discussed in #5177.

Key changes:

  • Modified SystemEventFactory.createStartlevelEvent() to accept an optional source parameter
  • Updated all call sites to provide appropriate source values

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
bundles/org.openhab.core/src/main/java/org/openhab/core/events/system/SystemEventFactory.java Added @Nullable String source parameter to createStartlevelEvent() factory method
bundles/org.openhab.core/src/main/java/org/openhab/core/service/StartLevelService.java Updated to pass StartLevelService.class.getName() as the source when creating start level events
bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/internal/RuleEngineImpl.java Updated two call sites to pass descriptive source values (RuleEngineImpl.class.getName() + ".activateRule" and RuleEngineImpl.class.getName() + ".executeRulesWithStartLevel")
bundles/org.openhab.core.automation/src/test/java/org/openhab/core/automation/internal/module/handler/SystemTriggerHandlerTest.java Updated test cases to pass null for the source parameter

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -42,10 +42,10 @@ public SystemEventFactory() {
* @param startlevel Startlevel of system
* @return Created start level event.
*/
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking API change to a public static method. The method signature has been changed to add a required parameter, which will break any external code calling this method. Consider maintaining backward compatibility by either:

  1. Creating a new overloaded method with the source parameter while keeping the old method and marking it as @deprecated
  2. Making the source parameter have a default value by creating an overload that calls this method with null

This would allow existing code to continue working while providing the new functionality.

Suggested change
*/
*/
@Deprecated
public static StartlevelEvent createStartlevelEvent(Integer startlevel) {
return createStartlevelEvent(startlevel, null);
}

Copilot uses AI. Check for mistakes.
@ccutrer
Copy link
Member

ccutrer commented Dec 17, 2025

@TheNetStriker it definitely sounds like a bug to me that if you save a rule after openHAB is already started, that it triggers with start level 40 instead of the current start level. I do know that StartLevelTrigger has historically been buggy (both because of the linked PR, and also working around issues with it in the JRuby Helper library).

But this still seems like a code smell to me. I know there's some amount of subjectivity to this, and work in earnest to having source carry any meaning at all is relatively immature still, but it still feels like the (non-named) bundle portion of a structured source is meant to be a relatively broad idea to know what part of the system is triggering an event, and the actor portion is supposed to be the "who." And that the bundle is essentially setting the namespace for how to interpret the actor. It sounds like you're saying "I want to distinguish between the system booting right now, and saving the rule into an already-booted system." Which to me means the event itself is not conveying enough information. Though I also used file-based Ruby rules, and if I need to execute something when the rule loads, and not necessarily on start level, I just write the code outside the rule and it does!

Does your suggestion of sending the current start level (and all lower levels?) when a rule loads address your use case without needing to resort to tagging the specific method that triggers it in the event source?

@Nadahar
Copy link
Contributor

Nadahar commented Dec 17, 2025

It sounds like you're saying "I want to distinguish between the system booting right now, and saving the rule into an already-booted system." Which to me means the event itself is not conveying enough information.

I agree, which is why I've suggested that maybe both the "triggering startlevel" and the "actual startlevel" should be part of the event. As I understand it, as it is now, it's aways the "triggering startlevel" that is sent (the startlevel for which the trigger is set to react), not the actual startlevel. It seems to me that both pieces of information can be of interest in some circumstances.

@TheNetStriker
Copy link
Author

@ccutrer Yes this would work for my use case. This is also how I'm using this now with the DSL rules, but it would be nice if I could convert all my rules to automation rules. Having the source would be a nice to have, but not necessary.

@TheNetStriker
Copy link
Author

@ccutrer I noticed that there was a change in #5177.

With this change is only the current startlevel is sent to the automation rules when the automation system is initialized.

I just tested this with starting/stoppting the latest Docker snapshot image multiple times and the behaviour is that sometimes I only get the startlevel 100 event and sometimes I also get level 70 and 80. Also sometimes I get a startlevel event twice. It all seems to depend on the timing of the startup routine.

Here is a log of a startup where I got multiple events. I also included the DSL rule events for comparison:

2026-01-28 12:39:21.445 [ERROR] [openhab.core.model.script.StartLevel] - DSL Rule: System reached start level 20
2026-01-28 12:39:21.448 [ERROR] [openhab.core.model.script.StartLevel] - DSL Rule: System reached start level 40
2026-01-28 12:39:21.449 [ERROR] [openhab.core.model.script.StartLevel] - DSL Rule: System reached start level 50
2026-01-28 12:39:21.450 [INFO ] [e.automation.internal.RuleEngineImpl] - Rule engine started.
2026-01-28 12:39:21.466 [INFO ] [ort.loader.AbstractScriptFileWatcher] - (Re-)Loading script '/openhab/conf/automation/js/systemStartLevel2.js'
2026-01-28 12:39:21.468 [ERROR] [openhab.core.model.script.StartLevel] - DSL Rule: System reached start level 70
2026-01-28 12:39:24.265 [INFO ] [.openhab.automation.openhab-js.rules] - Adding rule: System Start Level 2
2026-01-28 12:39:24.340 [ERROR] [sscripting.file.systemStartLevel2.js] - JSScripting System Start Level: 70 (UI is active) {event=Startlevel '70' reached., startlevel=40}
2026-01-28 12:39:26.469 [ERROR] [openhab.core.model.script.StartLevel] - DSL Rule: System reached start level 100
2026-01-28 12:39:26.469 [ERROR] [openhab.core.model.script.StartLevel] - DSL Rule: System reached start level 80
2026-01-28 12:39:26.471 [ERROR] [sscripting.file.systemStartLevel2.js] - JSScripting System Start Level: 80 (All things initialized) {aaa85e43-f24d-4221-957e-cfb04f3dcb4a.event=Startlevel '80' reached., aaa85e43-f24d-4221-957e-cfb04f3dcb4a.startlevel=70, event=Startlevel '80' reached., startlevel=70, module=aaa85e43-f24d-4221-957e-cfb04f3dcb4a}
2026-01-28 12:39:26.473 [ERROR] [sscripting.file.systemStartLevel2.js] - JSScripting System Start Level: 80 (All things initialized) {708d037e-2f2e-4ea0-8a60-1d44ef655840.event=Startlevel '80' reached., 708d037e-2f2e-4ea0-8a60-1d44ef655840.startlevel=80, event=Startlevel '80' reached., startlevel=80, module=708d037e-2f2e-4ea0-8a60-1d44ef655840}
2026-01-28 12:39:26.475 [ERROR] [sscripting.file.systemStartLevel2.js] - JSScripting System Start Level: 100 (Startup complete) {a8a887c9-e2eb-479e-8392-2dd1bbc6a2ca.event=Startlevel '100' reached., a8a887c9-e2eb-479e-8392-2dd1bbc6a2ca.startlevel=100, event=Startlevel '100' reached., startlevel=100, module=a8a887c9-e2eb-479e-8392-2dd1bbc6a2ca}

For me this behaviour is ok because I only need to know that startlevel 100 has been reached to prevent my rules from being executed before the whole system has started up. But maybe this could be a problem for other users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments