Group gRoom (gHouse)
Group gBlueRoom "Blueroom" (gRoom)
Group gBathroom "Bathroom" (gRoom)
Group gMotionDetector "Motion Detector"
And have a rule with the following trigger:
rule "Motion Detected"
when
Member of gMotionDetector received update
then
I have a zwave motion detector that is a member of gBlueRoom and also a member of gMotionDetector. I would the rule to be able to determine the group directly below gRoom that contains the item that triggered the rule. I can find the groups in gRoom but I can’t seem to find the correct syntax to iterate through these groups and in turn check whether any of the members of these groups contain the triggeringItem. My code so far:
In the third line I’m attempting to filter the members of i with the condition that their name must match that of the triggeringItem. However, this code produces a syntax error:
Rule 'Motion Detected': 'members' is not a member of 'org.eclipse.smarthome.core.items.GroupItem';
Much googling has not revealed the answer to me, I bet it’s something really simple too!
You can get a list of all the direct members of a Group using:
MyGroup.members
You can get a list of all the members of the Group including subgroups using:
MyGroup.allMembers
You can get a list of all the Groups an Item is immediately a member of using:
triggeringItem.getGroupNames
But there is no way I know of it get the list of ALL groups up hierarchy the Item may be a member of.
So assuming that triggeirngItem is directly a member of gBlueRoom
if(triggeringItem.getGroupNames.contains("gBlueRoom")) {
// member of gBlueRoom code
}
However, if triggeringItem is NOT a direct member of gBlueRoom (i.e. it is a member of a Group under gBlueRoom) I know of no way to discover that short of:
if(gBlueRoom.allMembers.findFirst[ i | i.name == triggeringItem.name] !== null) {
// triggeringItem is a member of gBlueRoom or a subgroup of gBlueRoom
}
The problem is filter returns a List even if there is only one match. There is no members method on a List. You would need to do something like:
gRoom.members.filter[i| i instanceof GroupItem]forEach[g as GroupItem | g.members.filter[device | device.name == triggeringItem.name].forEach[device | sb.append(", " + device.name) ]]
The last piece of code you posted is just what I’m trying to do but it gives a syntax error:
Configuration model 'lighting.rules' has errors, therefore ignoring it: [18,73]: no
viable alternative at input '|'
I was thinking that it would help if I could cast the results of the members list to an object of type GroupItem and then continue filtering. Character 73 is the character after the second pipe in the line:
gRoom.members.filter[i| i instanceof GroupItem].forEach[g as GroupItem | g.members.filter[device | device.name == triggeringItem.name].forEach[device | sb.append(", " + device.name) ]]
I.e., between GroupItem and g.members.filter. I shall continue investigating…
logInfo("Rules", "NG: Motion detector triggeringItem = (" + triggeringItem.name + ")." )
gRoom.members.forEach[roomGroup|
if (roomGroup instanceof GroupItem)
{
roomGroup.members.forEach[roomMember|
if (roomMember.name == triggeringItem.name)
{
logInfo("Rules", "NG: Triggering item was (" + triggeringItem.name + "), in room group (" + roomGroup.name + ")")
}
]
}]
Giving the following log entries:
NG: Motion detector triggeringItem = (PIRMotionSensor3_BinarySensor).
NG: Triggering item was (PIRMotionSensor3_BinarySensor), in room group (gBlueRoom)