Unable to use forEach consistent on groups,

Hi all!

I have been somewhat migrating from OH1 to OH2 (actually started with OH while OH2 was released, so jumped a bit back and forth to learn the platform). So I am quite a newbie, and forgive me for that.

But I cannot get the forEach logic to run as expected. If I use the following code, all goes well:

rule "Update light status in Kitchen" 
when
        Item Kitchen_All received update
then
	postUpdate(Kitchen_Table, Kitchen_All .state.toString) //Dimmer
	postUpdate(Kitchen_Roof, Kitchen_All .state.toString) //Dimmer
	postUpdate(Kitchen_Wall_lamp, Kitchen_All .state.toString) //Switch
end

But if I try to reduce the lines of code, some of the items does not get updated, as well as items go on and off in a somewhat random pattern:

rule "Update light status in Kitchen"
when
        Item Kitchen_All received update
then
   	gKitchen?.members.forEach[ item | postUpdate(item, Kitchen_All.state.toString)]
end

Can anybody see what I am doing wrong?
All items are in the group, and the group is not by mistake nested. Items are Nexa devices, with RFXCOM if relevant.

What I want to achieve, is to update light status in app, when someone press a physical “group button”.

Any help would be very much appretiated!

If all you are doing is passing the state from the Group, why not just use the Group?

Assuming you are doing switches here, if you define your group as Group:Switch gKitchen and put gKitchen on your sitemap as Switch item=gKitchen when ever you toggle the switch on gKitchen all the members of gKitchen will receive the command.

As to your specific code, I’d do the following:

  • Remove the ?. If for some reason gKitchen has no members this will cause that statement to silently be skipped over. You want an error because clearly you always expect gKitchen to have members. Failing silently us often a bad choice.

  • Don’t use the postUpdate Action, use the method on the Item itself instead. It is much better able to translate and convert the various sorts of things one might pass as state to the proper format. item.postUpdate(Kitchen_All.state). Because we are using the method we no longer need to call toString

  • Finally, and this is the real problem, you need to use sendCommand. postUpdate only changes the internal state inside of OH. You must use sendCommand in order for the binding to go out and do the action.

  • One other minor thing is to avoid using variable names that are really close to reserved words, like “item” which is really close to “Item”. It just helps one avoid problems caused by typos more than anything.

So your line would become:

gKitchen.members.forEach[ i | i.sendCommand(Kitchen_All.state)]

Thanks a bunch for your review. I’ll test the changes later today.

The only thing I do not want to do, is to use the sendCommand, as this is a post update. I pair all my Nexa items with a physical button, as well as one virtual “room code”. I find this usefull to be able to send on and off commands to entire rooms, instead of updating one and one. Saves the scripts up to 20 seconds of execution in user observed time. It’s when I press the group code that I want all the individual updates to be replicated, as these are not linked. It also has the benefit to be able to avoid group buttons to start individual dimming. This is kinda Nexa specific I guess.

I’m not 100% certain I understand what you are describing.

But I can say this.

If you want the command to go to the Binding and get sent to your devices and cause the lights to turn on or off, you MUST use sendCommand. postUpdate only changes the state internal to openHAB and so the commands never go out to the devices.