Problem with Group Iteration in JavaScript Rule: Item Not Found

Hi everyone,

I’m encountering an issue with my openHAB JS rule where I’m trying to iterate through the members of a group item. Here’s a rule extract:

rules.JSRule({  
    name: "activate deConz Scene",  
    description: "Controls various scenes using a numeric scene switch.",  
    triggers: [triggers.ItemStateChangeTrigger("Sensor_GF_Livingroom_NumberLightScene")],  
    execute: (event) => {  
        try {  
            const lightSwitchMap = {  
                "Sensor_GF_Livingroom_NumberLightScene": ["Group_GF_Livingroom_SwitchLight"]  
            };  
            let lightSwitchGroupItem = lightSwitchMap[event.itemName];  

            if (items.existsItem(lightSwitchGroupItem)) {  
                lightSwitchGroupItem.members.forEach(function (member) {  
                    console.log('Name: ' + member.name + ', State: ' + member.state);  
                });  
            } else {  
                actions.Log.logWarn("activate deConz Scene", "Item " + lightSwitchGroupItem + " does not exist");  
            }  
            actions.Log.logInfo("activate deConz Scene", `Scene Off activated for ${event.itemName}.`);  
        } catch (err) {  
            console.error("Error executing rule: ", err);  
        }  
    }  
});  

The error I’m getting is:

[e.model.script.activate deConz Scene] - Item Group_GF_Livingroom_SwitchLight does not exist  

However, my item is defined as:

Group:Switch:OR(ON, OFF) Group_GF_Livingroom_SwitchLight "Wohnzimmer Licht Schalter" <lightbulb>  

I suspect the issue might be related to how I reference the group item in my rule. How can I fix this error and make the rule work?

Thanks for your help!

Move Group_GF_Livingroom_SwitchLight out of the array

But if I want to use the function with different triggers


triggers: [
                triggers.ItemStateChangeTrigger("Sensor_GF_Bedroom_NumberLightScene"),
                triggers.ItemStateChangeTrigger("Sensor_GF_Livingroom_NumberLightScene")
        ],


const lightSwitchMap = {
                                "Sensor_GF_Bedroom_NumberLightScene": ["Group_GF_Bedroom_SwitchLight"],
                                "Sensor_GF_Livingroom_NumberLightScene": ["Group_GF_Livingroom_SwitchLight"]
                        };

This is what I meant:

const lightSwitchMap = {
  "Sensor_GF_Bedroom_NumberLightScene": "Group_GF_Bedroom_SwitchLight",
  "Sensor_GF_Livingroom_NumberLightScene": "Group_GF_Livingroom_SwitchLight"
};

Also, not related to the issue, you could just write it like this:

const lightSwitchMap = {
  Sensor_GF_Bedroom_NumberLightScene: "Group_GF_Bedroom_SwitchLight",
  Sensor_GF_Livingroom_NumberLightScene: "Group_GF_Livingroom_SwitchLight"
};

What are you hoping to accomplish? This might be an XY problem.

Beyond that @jimtng has the answer. items.existsItem() only supports checking to see if a single Item exists by name, but you are passing it an array. If you do in fact have more than one Group Item per key in your map, you’ll have to account for that when checking if the Items exist.

if(lightSwitchGroupItem.every(name => items.existsItem(name)) {
  lightSwitchGroupItem.forEach( name => {
    items[name].members.forEach( member => {
      console.log('Name: ' + member.name + ', State: ' + member.state);
    });
  } )

.every() will return true only if every member of the array exists. Once you are inside the if you need to treat each element of the array individually through a loop.

I am confused…

I changed it to

const lightSwitchMap = {
                                Sensor_GF_Bedroom_NumberLightScene: "Group_GF_Bedroom_SwitchLight",
                                Sensor_GF_Livingroom_NumberLightScene: "Group_GF_Livingroom_SwitchLight"
                        };
let lightSwitchGroupItem = lightSwitchMap[triggerItem];
console.log("fff"+lightSwitchGroupItem)
if(lightSwitchGroupItem.every(name => items.existsItem(name))) {
                                                lightSwitchGroupItem.forEach( name => {
                                                        items[name].members.forEach( member => {
                                                                console.log('Name: ' + member.name + ', State: ' + member.state);
                                                        });
                                        })
                                        }

output is

fffGroup_GF_Livingroom_SwitchLight
2025-02-07 21:57:17.088 [ERROR] [openhab.core.model.script.scene rule] - Some bad stuff happened in "scene rule": TypeError: lightSwitchGroupItem.every is not a function

What I try to accomplish is …depending on the trigger I want to select a group of light switches and than chek if the items existing than I want to send the command off to them.

The problem is that lightSwitchGroupItem is

string

I solved it by

const lightSwitchMap = {
                                Sensor_GF_Bedroom_NumberLightScene: "Group_GF_Bedroom_SwitchLight",
                                Sensor_GF_Livingroom_NumberLightScene: "Group_GF_Livingroom_SwitchLight"
                        };
let lightSwitchGroupItem = items.getItem(lightSwitchMap[event.ItemName

lightSwitchGroupItem.members.forEach(function(member) {
                                                if (items.existsItem(member.name)) {
                                                        member.sendCommand("OFF");
                                                }else{
                                                        actions.Log.logWarn("activate deConz Scene", "Item " + member + " does not exist");
                                                }
                                        });
);

There are two separate solutions presented above. @jimtng’ s solution stoves your original probably problem by eliminating the array. My solution keeps the array.

You’ve combined the two to create a broken version.

Which is @jimtng 's solution which eliminates the array.

9"
Syntax error there.

Checking for the existence of members is unnecessary.

Just do lightSwitchGroupItem.sendCommmand(“OFF”)

Also, catching the exception of the whole rule might also be unnecessary