Rule Not Triggering On Group Change

Hi

I have a issue where a rule doesn’t seem to be triggering. The rule is configured to trigger on a group receiving an update. The group is the top of a nested tree of groups.

The items are as follows…

Group   gNetwork                (gLocation)
Group   gNet_BRIDGE01           (gNetwork, gControl)
Group   gNet_NAS01              (gNetwork, gControl)
Group   gNet_NAS02              (gNetwork, gControl)
Group   gNet_ROUTER01           (gNetwork, gControl)
Group   gNet_GOOGLEDNS          (gNetwork, gControl)
Switch  BRIDGE01_Online         "BRIDGE01"      (gNet_BRIDGE01)         {channel="network:device:BRIDGE01:online"}
Switch  ROUTER01_Online         "ROUTER01"      (gNet_ROUTER01)         {channel="network:device:ROUTER01:online"}
Switch  GOOGLEDNS_Online        "GOOGLEDNS"     (gNet_GOOGLEDNS)        {channel="network:device:GOOGLE-DNS:online"}
Switch  NAS01_Online            "NAS01"         (gNet_NAS01)            {channel="network:device:NAS01:online"}
Switch  NAS02_Online            "NAS02"         (gNet_NAS02)            {channel="network:device:NAS02:online"}

And the rule is…

rule "Network Alert"
        when
                Item gNetwork received update
        then
                val lastItem = gNetwork.allMembers.sortBy[lastUpdate].last
                logInfo("Rules","Network Alert -> " + lastItem.name + " changed to " + lastItem.state)
                pushNotification("Openhab Notice", "Network Alert -> " + lastItem.name + " changed to " + lastItem.state)
                sNetworkCheck.postUpdate(OFF)
        end

Now I’m sure it’s something simple that I’ve missed but I just can’t see it… Any ideas would be most useful

You have to set the Group Item Type.

Group:Switch  gNetwork                (gLocation)
Group:Switch   gNet_BRIDGE01           (gNetwork, gControl)
Group:Switch   gNet_NAS01              (gNetwork, gControl)
Group:Switch   gNet_NAS02              (gNetwork, gControl)
Group:Switch   gNet_ROUTER01           (gNetwork, gControl)
Group:Switch   gNet_GOOGLEDNS          (gNetwork, gControl)

Please be aware that the rule will trigger multiple times at every update.

Thanks for the info… I’ve updated the group definitions and the rule does indeed trigger now… However, the rule doesn’t seem to work as written… I’ve updated the rule to include a lock to stop it triggering multiple times.

rule "Network Alert"
        when
                Item gNetwork received update
        then
                logInfo("Testing","Lock: " + lock.isLocked)
                if (!lock.isLocked) {
                        lock.lock()
                        try {
                                logInfo("Testing","gNetwork received update")
                                val lastItem = gNetwork.allMembers.sortBy[lastUpdate].last
                                logInfo("Rules","Network Alert -> " + lastItem.name + " changed to " + lastItem.state)
                                pushNotification("Openhab Notice", "Network Alert -> " + lastItem.name + " changed to " + lastItem.state)
                        } finally {
                                lock.unlock()
                        }
                } else {
                        logInfo("Testing","Locked, update ignored")
                }
        end

The log message “gNetwork received update” from line 9 get’s logged into the openhab.log which shows that the rule is triggered and the locking working, but oddly the log message from line 11 never gets logged. I’m presuming something’s not quite right on line 10 but just can’t see it!!

A total stab in the dark here, but on line 10 substitute val with var. val’s are static and can’t be changed where as var’s can change during runtime.

Thanks for the advice… I actually worked out the issue here… It seems that if one of the group members has a last value of Null then the lastUpdate.last seems to fail… Once all group members have a last value it works, sort of.

The issue I’m having now is stopping the rule firing multiple times and therefore sending multiple messages even though the item has NOT updated. I’m thinking I need to change from

Item gNetwork received update

to

Item gNetwork changed

Ideally I’d like to use

Item gNetwork changed from ON to OFF

But it seems when an item in the group changes from ON to OFF the group changes from ON to UNDEF

No, you can’t trigger to changed or at least this would possibly not work as expected. In fact you don’t use any sum function (AND/OR…), so there is no rule how to build the state of the group at all - hence the UNDEF, I guess.

However, within the try {} section, you could use lastItem.state and lastItem.previousState (you have to use a persistence to do this).

if (lastItem.state == OFF && lastItem.previousState().state == ON)

should ensure only to get those events where an item changed from ON to OFF.

You can filter out those Items using

val lastItem gNetwork.allMembers.filter[net | net.lastUpdate != null].sortBy[lastUpdate].last

This is how Groups work unfortunately. Each Group receives multiple updates any time any one of its members is updated. If your Group has N members, an update to one member will cause N-1 updates and your Rule will trigger N-1 times.

As Udo explains, using changed is unlikely to work for you because that will only trigger the Rule when the Group’s state changes. So if all the members are OFF, the Group’s state will be OFF. One Item changes to ON then the Group will change to ON. But if a second Item changes to ON then the Group will not change to ON because it already is ON and therefore the Rule won’t trigger.

However, if you use Group:Number:SUM for your Groups the state of the Group will be the count of the members that are ON. Then you can use changed as your trigger. I’m not 100% certain this will work with your hierarchical Groups but I think it should work.

Just stumbled upon this post and it looks like this could be a solution to my problem as well. However: what would happen if two switches in the group toggled state ‘simultaneously’, assuming that they had unequal values at the start.

Would the above always yield an update (with the value of the sum going from N to N-1 to N) or can’t this be guaranteed?

This is a nearly impossibe thing to occur in a computer. One or the other event will occur milliseconds before or after the other. I think the worst case scenario is that the first SUM calcualted might be wrong (i.e. include the new state of the second Item as well) but the result of the second SUM calculated will be wrong so the Group might be off by one for a dozen milliseconds or so.

1 Like

That is assuming that all state changes are processed individually and not batched or sampled. Clearly this is not the case for openHAB ; perfect. I can live with the couple of milliseconds of ‘false’ state :slight_smile:

I can’t speak to individual bindings. But once the events get published to the Event Bus they are processed individually based on my observations. I’ve not looked at the code to verify though.