Rule not triggered at startup when second trigger is configured

I have a rule which has two triggers. One for startup and one for group item change:

configuration: {}
triggers:
  - id: "2"
    configuration:
      startlevel: 100
    type: core.SystemStartlevelTrigger
  - id: "1"
    configuration:
      groupName: automation_group
    type: core.GroupStateChangeTrigger
conditions: []

The group trigger works but the startup trigger does not. If I remove the group trigger, then the startup trigger works.

Just to be clear, the startup trigger will only ever occur when OH is starting up. If you modify or change the rule it will not trigger. Is this in fact the behavior you are seeing?

Yes exactly, I restart openhab with

sudo systemctl restart openhab.service

The strange thing is: The alarm clock rule from the marketplace does work and that was my starting point for the rule.

Is it possible, that the execution of the rule is blocked if it is already running? I just tried to trigger it from another rule and that did not work either. It is triggered by the GroupChangeStateTrigger as well during startup for those items in the group which are restored on startup, but not for e.g. astro items. (But then “event” is set and it does something else.)

Another thought:
The rule gets triggered twice for one of the restored items. I check this by logging event.itemName
Is it possible that the second call is the startup trigger and the “event” object is just not deleted?

Edit:
This seems to be the problem. I took the Alarm Clock from the marketplace, configured an item which is restored on startup and added this right after the logger is defined:

if(this.event !== undefined) {
  logger.info(event.itemName)
}

When restarting openhab, the rule is triggered twice, but in both cases the itemName is written into the log, thus event there in both cases.

Multiple triggers will be queued, and executed one at a time.

Careful with Group based triggers, you can get multiple Group events from one member event. Not usually with changed event, though.

I’m confused, I thought the complaint was that it did not trigger at startup?

Sorry, I think I’m not clear enough. I have a rule which should do something during startup and something else when an item changes.
I try to find out which trigger it is (startup or change) by checking if “event” is defined, as it should not be defined for the startup trigger. I have three items in the group. ItemA, itemB and ItemC. A and B get restored on startup. If I log event.itemName during startup I get this:
itemA
itemB
itemB

So I thought, the startup event is missing because for all triggers event was defined, hence my complaint that the startup trigger is missing. But now I think, that the startup trigger is working, it is just that “event” is defined there as well. Probably with the value of the last call.
And the same thing happens when using the simple ItemStateChangeTrigger.

That sounds like two rules to me.

Okay, got you now.

I was simplifying a bit. It does similar things, once for all items in the group and once just for the triggered. So I would need to duplicate that code.

The event object shouldn’t exist when the rule is triggered by the startup event but I’ve seen reported in the past where the event from the previous trigger hang around. But that was fixed I think. Are you running the latest release?

This is all getting into an obscure corner of openHAB.
Ideally, Items should get created (and Group memberships sorted out) before rules run.
Ideally, after Items are created but before rules run, we should do any restore-on-startup from persistence.
Ideally, those restores should not trigger Item change events - restore is after all a continuation, not a change.
All’s well there.

But wait - if there is a Group with members getting restored and that is causing the Group state to change … there’s no apparent reason for that not to trigger any listening rules (even if it queues up for a while), and run them ahead of any system started trigger.
openHAB loves to do exactly what you asked of it, but in an order that you don’t expect :wink:

And that’s the idealised case - when we throw in real-life races (how many Items to create? How many rules to load? How many coes working?), and oddities like restores from two different databases etc. etc …

1 Like

I’m running 3.2

You are right, that would be a even more consistent behavior. But was it designed that way and what I see is a bug, or does it just happen to be that way?

I don’t get that point. If it is restored, why should the group change?
And another point: What about items linked to channels? I don’t get any trigger for the astro items. But openhab does not know how long the system was down and if those values have changed since then. So should I get a event there, because it could have changed?

Group states are not restored.
Group states are calculated from some function of member Item states.
Member Item states may be restored, some or all.
So, there’s a logical consequence on the Group to restoring member states.

Bindings should be up and running and updating Item states before rules.
Many bindings are in truth slow and reliant on external services, so that does not often hold true.
But Astro is all internal, waits for no-one else.

“It depends”. Are they restored? Might or might not get an update event, probably will not get a change event across a short reboot. If they are restored, where from - will that happen before or after binding update? In typical openHAB fashion, these are indeterminate.

You don’t often care. Sunup today is 06:00 or whatever, doesn’t matter when or how you find that out.

That is clear, but if the members are restored, the group state should be the same as before the restart, so a rule should not trigger on that change.

I think, that is the main takeaway for me. There is currently no way and probably will never be a way where I can set up a rule to trigger on change and that trigger will always happen on change and never without a change, as there are too many indeterminate things during startup. So I need to factor that in when writing my rules.

But it is NULL when born at startup, like every other Item. The change to a new state is a … change.

The same applies to every Item, of course.
I used to be sure that ‘restore-on-startup’ made its NULL-to-whatever change in some underhand fashion that did not trigger the usual update and change bus events. It was very consistent at that in OH1. Now I’m not so sure that the visible effect was not just some accident of timing, taking place before the logger is working say, that may vary between versions.

But for the Group state, the difference is again timing - the Group update occurs as a result of very different processes that take place after the restore cycle of ‘ordinary’ Items.

I remember looking into that a long long time ago. Remember in OH 1.x there were some properties that controlled how often OH checked for changes to its config files? I remember a time where I messed with those and was able to force the rules to be loaded before restoreOnStartup happened (I think I set the polling time such that rules were loaded first). For lots of reasons, having rules loaded and running first is not desirable so I suspect no one saw this occur unless they were exploring like I was.

In OH 2 the loading and startup switched from polling to file system events and everything was loading at the same time. OH 3 introduced the first forays into start levels (I recently learned though that start levels after 40 are actually not yet implemented :frowning: ). But even when it is fully implemented, what exactly each level means may not be what we expect. What does it really mean “Things Initialized”? I can’t mean that all Things are online because that may never happen.

OH is an event driven system. A Group’s state isn’t updated all at once. It’s done so incrementally in response to one of its members changing. During restore on startup the each Item is updated individually and each of those updated generates an event and the Group’s aggregation function is driven by that event.

Imagine the following scenario. You have two members of a Group:Number:Min which means the Group’s state is the minimum of the two members.

Step Group Item 1 Item 2
1. NULL NULL NULL
2. NULL 5 NULL
3. 5 5 NULL
4. 5 5 3
5. 3 5 3

During this simple startup sequence the Group changed twice in response to restoreOnStartup and it first changed to a state different from the one it had when OH closed down last time.

The event in the script context is set whenever a rule is triggered by an item-based trigger. However, it is not removed after the rule execution finished. If the next execution is triggered e.g. by „Run Rule“ in the UI, the event is still around. I have submitted https://github.com/openhab/openhab-core/pull/2760 for that.

3 Likes