Design Pattern: Working with Groups in Rules

Yes you can simplyfy that. Just use triggeringItem to access the item that triggered the rule

1 Like

I think that is essentially correct, but I’d put any if-condition in brackets
if ( i.memberOf(sceneGroup) ) {
What happens when you try it?

Rule ‘Update lights’: ‘memberOf’ is not a member of ‘org.eclipse.smarthome.core.items.Item’; line 37, column 8, length 22

That works, I assume its a bit slow if you have big groups…

group.members.forEach[ i |
    if (i.getGroupNames.contains("sceneGroup") {
        i.sendCommand(ON)
    else {
        i.sendCommand(OFF)
    }
]

So after several testing now, here is the conclusion:

  1. if i.memberOf( sceneGroup) { FAILS
  2. sceneGroup.members.filter[ j | j.name == i.name].size > 0 SLOW
  3. if (i.getGroupNames.contains(sceneGroup.name) { FAST

@5iver thanks for the tip, however you had a small typo:

 if (i.getGroupNames.contains("sceneGroup") {

should be

 if (i.getGroupNames.contains(sceneGroup.name) {

@rlkoshak maybe you can add this method to your orginal post of how to find out if an item is a member of a group.

1 Like

Huh? sceneGroup.name equals “sceneGroup”.

Not quite: sceneGroup.name can be like this…

Group Group_Livingroom_Lights_Kitchen
Group Group_Livingroom_Lights_Lounge

See my design pattern for more info.

The former should be: all the direct members of the Group. In other words, if you define:

Group grpA
Group grpB (grpA)
Group grpC (grpA)

String strA (grpA)
String strB (grpB)
String strC (grpC)

Then grpA.members returns the following items:

  • grpB
  • grpC
  • strA

And grpA.allMembers returns only non-group items by resolving all groups into their items. In the example above, grpA.allMembers returns the following items:

  • strA
  • strB
  • strC
1 Like

How would you archive this in Jython?

Im trying to get all members of a GroupA which are also members of GroubB.
Without Iterating over 100 of items.

=> Say All “gTemperatures” in “gLivingroom” - Same as the Doc Group Example from “Items”.

// Example Item
Number Livingroom_Temperature "Temperature [%.1f °C]" (Livingroom, Temperatures)

I never used Jython myself (although I will probably start to in the near future), but I think you can just use two list comprehensions to achieve this (somebody correct me if I am wrong with this :slight_smile: ):

temperature_list = [i.name for i in ir.getItem('gTemperatures').members]
livingroom_temperatures = [i for i in ir.getItem('gLivingroom').members if i.name in temperature_list]

you could also make two sets out of your groups and intersect them.

I answered someone else a couple days ago (I’ll add this to the docs)…

Here are a couple more examples that will be in the helper library docs…

        list_of_items = [item for item in itemRegistry.getItem("gDS_FamilyRoom").members if "gMotion_Sensor" in item.groupNames]

        # or
        list_of_items = [item for item in itemRegistry.getItem("gDS_FamilyRoom").members if item in itemRegistry.getItem("gMotion_Sensor").members]

        # or
        list_of_items = [item for item in itemRegistry.getItem("gMotion_Sensor").members if item in itemRegistry.getItem("gDownstairs").allMembers]
2 Likes

Hello,

thanks for Pattern!
I have put all items in test.items file and unfortunatly i get error

2019-12-05 12:44:50.050 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'test.items' has errors, therefore ignoring it: [7,57]: missing EOF at '('

It goes away only if i delete all the “(gDoorsTimers)” from file.
Pi4 OH2.5 M5
What can it be?
Thanks!

There’s something wrong in your rules file that we cannot see from here. I’ll guess it may be a copy-paste problem about quotemarks

Spot the difference in highlighting -

fred=“some text”
mary="more text"

You must use the correct type of “plain” quotemarks in xxx.items files.

I have copy-pasted the items from the top

Group:Contact:OR(OPEN, CLOSED) gDoorSensors "The doors are [%s]"
Group:DateTime:MAX gDoorsLast "The last door event was [%1$tm/%1$td %1$tH:%1$tM]" 
Group:Switch:OR(ON, OFF) gDoorsTimers

Contact vGarageOpener1 "Garage Door Opener 1 is [%s]" (gDoorsSensors)
DateTime vGarageOpener1_LastUpdate "Garage Door Opener 1 [%1$tm/%1$td %1$tH:%1$tM]" (gDoorsLast)
Switch vGarageOpener1_Timer { expire="1h,command=OFF" } (gDoorsSensors)

Contact vGarageOpener2 "Garage Door Opener 2 is [%s]" (gDoorsSensors)
DateTime vGarageOpener2_LastUpdate "Garage Door Opener 2 [%1$tm/%1$td %1$tH:%1$tM]" (gDoorsLast)
Switch vGarageOpener2_Timer { expire="1h,command=OFF" } (gDoorsTimers)

Contact vFrontDoor "Front Door is [%s]" (gDoorsSensors)
DateTime vFrontDoor_LastUpdate "Front Door [%1$tm/%1$td %1$tH:%1$tM]" (gDoorsLast)
Switch vFrontDoor_Timer { expire="1h,command=OFF" } (gDoorsTimers)

Contact vBackDoor "Back Door is [%s]" (gDoorsSensors)
DateTime vBackDoor_LastUpdate "Back Door [%1$tm/%1$td %1$tH:%1$tM]" (gDoorsLast)
Switch vBackDoor_Timer { expire="1h,command=OFF" } (gDoorsTimers)

Contact vGarageDoor "Garage Door is [%s]" (gDoorsSensors)
DateTime vGarageDoor_LastUpdate "Garage Door [%1$tm/%1$td %1$tH:%1$tM]" (gDoorsLast)
Switch vGarageDoor_Timer { expire="1h,command=OFF" } (gDoorsTimers) 

they looks good

It seems to be a wrong Syntax in item definition (at least in 2.5 M5). Should be chaned in the top of the post!

Error:

Switch vGarageOpener1_Timer { expire="1h,command=OFF" } (gDoorsSensors)

OK:

Switch vGarageOpener1_Timer (gDoorsSensors) { expire="1h,command=OFF" }

Well, it’s only an example, you’ll probably need to work your own up. But -

This wrong format. The (groups) need to be placed before the {bindings}.
It’s always been that way, but I expect the Items file parser has incorporated more checks since 2017

Switch vGarageOpener1_Timer (gDoorsSensors) { expire="1h,command=OFF" }

EDIT - okay you found it. @rlkoshak for info

1 Like

One more small mistake with whitch iэму spent half an hour (((
Better to correct, so other can use the pattern.

And in Rules also

This construction

val lastChange=gDoorsSensors.members.findFirst[ t | t.name == "DoorEntranceLastChange" ] as DateTimeItem
logInfo("Door", "val opened at:  " + lastChange + "check: " +  DoorEntranceLastChange.state)

seems not ot work on OH 2.5M5 or i made smth wrong?

i get

2019-12-05 18:22:16.089 [INFO ] [.eclipse.smarthome.model.script.Door] - val opened at:  nullcheck: 2019-12-05T18:22:14.957+0100

Why null, item has DateTime and not null at this time

DateTime  DoorEntranceLastChange "Door Entrance Last Change [%1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS]"

Thank you for pointing out the errors. As rossko57 points out, the example never was intended to be copied from the posting and used. It shows how to use the operations discussed but you would be expected to apply those operations to your own Items and Groups.

In some cases, there are better ways to achieve the same thing, sometimes without Rules at all, e.g. there is a Profile to update the LastUpdate Items.

Please don’t double post. I’ve answered on the other thread.