Nested Group Updates Triggering Rules

Hi

I’m really hoping someone out there can offer some useful help/advice on an issue I’ve been struggling with for over a week now… Basically, I’m trying to dynamically update the membership of a group whenever an item in another group changes. The idea is that an item is added to a group called fgDownNetDevices whenever the item, which is a member of the group fgNetDevices changes from a state of ON to OFF. I’ve used some examples from this site to construct this but I just cannot get it to work as wanted but can’t see why…

Here’s my item file

Group:Switch:OR(ON,OFF)	gRoot
Group:Switch:OR(ON,OFF)	gFunction			(gRoot)
Group					gLocation			(gRoot)
Group:Switch:OR(ON,OFF)	gInformation		(gFunction)
Group:Switch:OR(ON,OFF)	fgNetDevices		(gInformation)
Group					gNetwork			(gLocation)
Group					fgDownNetDevices	(gInformation)

Switch					sRefreshON
Switch					sTest_Network		(gNetwork)

And my rule file

import java.util.concurrent.locks.ReentrantLock

var Timer Ontimer = null
var ReentrantLock lock = new ReentrantLock()

rule “Startup Timer”
	when
		System started
	then
		ONtimer = createTimer(now.plusSeconds(20)) [| sRefreshON.sendCommand(ON)]
	end

rule “Populate Functional Groups”
	when
		System started
	then
		gRoot.allMembers.filter(s | s.name.endsWith(“Network”)).forEach[ item | fgNetDevices.addMember(item)]

rule “gRoot Update”
	when
		Item gRoot received update
	then
		if (!lock.isLocked) {
			lock.lock()
			try {
				if (ONtimer.hasTerminated()) {
					ONtimer = createTimer(now.plusSeconds(10)) [| sRefreshON.sendCommand(ON)]
				}
			} finally {
				lock.unlock()
			}
		}
	end

rule “fgDownNetDevices - Update”
	when
		Item sRefreshON received update
	then
		logInfo(“Rules”,”Group fgDownNetDevices about to be refreshed”)
		fgDownNetDevices.members.forEach[ item | fgDownNetDevices.removeMember(item)]
		fgNetDevices.allMembers.filter(s | s.state == OFF).forEach[ item | fgDownNetDevices.addMembers(item)]
	end

The basic principal is that any update to any item should filter up through the hierarchical tree of the groups until the group gRoot receives an update. This should then trigger the rule “gRoot Update” which sends the command ON to the item sRefreshON. sRefreshON receiving an update should then trigger the rule fgDownNetDevices - Update” which should remove all members from the group fgDownNetDevices and then add any members of the group fgNetDevices whose state is OFF to the group fgDownNetDevices.

There is also a rule, “Populate Functional Groups”, that executes on startup that pre-populates the group fgNetDevices with any items where their name ends with the word Network. I’m pretty sure this rule is working fine as I can see the correct items within the group on my sitemap.

I have a test switch item called sTest_Network but when I change this switch item from ON to OFF on a sitemap it doesn’t appear in the group fgDownNetDevices.

If anyone can see what I’ve missed or done wrong I’d greatly appreciate the help

I’ve not reviewed the code very closely but from what you describe you may be facing the issue in OH where it doesn’t always handle Group updates very well. I know that whenever I add or remove an Item from a Group in a .items file I often am required to restart OH for the change to be picked up.

Also, I’m not sure that BasicUI/ClassicUI was designed with the idea of supporting changing Group membership while you are actively looking at a Group. Does the Item appear if you refresh the page?

Finally, this whole approach seems really complicated to me and were it me, I would be looking for a different approach, one that does not depend on dynamic Group membership. For example, if you are using this to drive the sitemap so only those Items that are offline are shown I’d use the visibility tag.

So add some logging to see if your rule is executing. Add some more logging to see what the contents of fgDownNetDevices is when the rule is done executing.

There are lots of steps between when your gRoot receives an update and you see changes reflected in the sitemap. You need to narrow down the problem to one of those steps.