Triggering Node Red Flow on a change to any light in a light group

In my house I use light groups (Group - Home Assistant) to group logical areas together. E.g Outside Lights, Downstairs Lights. Some of these are nested - so for example “Downstairs Light Group” actually contains 3 other light groups (sitting room, kitchen, bathroom).

I want to create a Node Red flow that triggers on any of the lights in a group changing. Obviously I could setup my flow with every individual light but as I’ve already got a group I’d prefer to just be able to say “When any light in the downstairs group changes do this…”

Is there a way to do this? Triggering on the light group doesn’t work as that doesn’t fire an event unless it moves from off <-> on. E.g. if one light in the group is on and I turn on a second light it won’t fire an event in Node Red.

Have you looked at the Events: All node?

I know this is not the way the node is supposed to be used, but what happens if you use get entities on the group?
I suspect it won’t work but worth a try.

You could probably use the template node to expand the group, but that is not a trigger so you need something to trigger it.

I believe you need to add all the lights in the group.
Unless they have similar names and you could use starts with or something like that on the entity id.

No need to over complicate things. Simply use the Event State node.
Make sure that current state equals previous state is UNTICKED
Like in the picture below.

When one light of the group changes, you will receive a new event

I did try this but it doesn’t work for me. If I turn on a single light in the group I get a message that the group has turned on. If I then turn a second light on in the group I don’t get a second message… I am using YAML light groups at the moment rather than the Helper ones - not sure if that is relevant.

Can you share your NodeRed Flow?
If your message is only being sent when the group turns on, that means you wouldnt receive a second message. Because the group is already on.

Have you tried using it with a debug message.

Try this simply flow and simply add your light group. (I use yaml groups too)

[{“id”:“be7ae5c8c3f99b41”,“type”:“debug”,“z”:“1486cf5f.cd1781”,“name”:“debug 1”,“active”:true,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“statusVal”:“”,“statusType”:“auto”,“x”:500,“y”:2660,“wires”:},{“id”:“1b9d6beb7174cf0b”,“type”:“server-state-changed”,“z”:“1486cf5f.cd1781”,“name”:“”,“server”:“”,“version”:4,“exposeToHomeAssistant”:false,“haConfig”:[{“property”:“name”,“value”:“”},{“property”:“icon”,“value”:“”}],“entityidfilter”:“light.wohnzimmer”,“entityidfiltertype”:“exact”,“outputinitially”:false,“state_type”:“str”,“haltifstate”:“”,“halt_if_type”:“str”,“halt_if_compare”:“is”,“outputs”:1,“output_only_on_state_change”:false,“for”:“0”,“forType”:“num”,“forUnits”:“minutes”,“ignorePrevStateNull”:false,“ignorePrevStateUnknown”:false,“ignorePrevStateUnavailable”:false,“ignoreCurrentStateUnknown”:false,“ignoreCurrentStateUnavailable”:false,“outputProperties”:[{“property”:“payload”,“propertyType”:“msg”,“value”:“”,“valueType”:“entityState”},{“property”:“data”,“propertyType”:“msg”,“value”:“”,“valueType”:“eventData”},{“property”:“topic”,“propertyType”:“msg”,“value”:“”,“valueType”:“triggerId”}],“x”:270,“y”:2660,“wires”:[[“be7ae5c8c3f99b41”]]}]

You should get in your debug log messages when lights change from the group. To test turn on the group. Then change single lights. You should receive multiple messages.

Doesn’t work. Kitchen Sink Group has the left light and the right light in it:

I turned on the left light - Notified of group and light turning on.
Waited 20 ish seconds turned on the right light - Notified of only the right light turning on.

Hm, just when i tried reproducing i realized that sometime the group debug message takes some time to arrive. I could force it by doing a brightness change of one light.

However, in general it works for me.
What light integration are you using?

image

1 Like

Thanks for helping - I tried with some other groups and I think I’ve figured out the difference (bug?)…

My Kitchen Sink lights are two identical lights with identical colour and brightness. So when I turn them on the brightness/colour of the light group doesn’t change so no notification.

If I set them to different brightness then the group notification is sent as the brightness of the group as a whole changes when the second one comes on.

Created a bug report in case this is a bug and not a feature: Light groups don't fire an event when a light in the group turns on in some cases. · Issue #76547 · home-assistant/core · GitHub

Thanks @stevemann / @Hellis81 - combining both your comments gave me an idea.
I’ve essentially created an “expand” node in Node Red using function nodes and use that to filter the events coming from an “Event: All” node

UPDATED with the regexp suggestion below so we don’t use the “Event: All” node.

I have two parts to the flow:

  1. Subscribes to the actual group I want. It will then expand the entities and save it to a flow variable. This will be checked any time the state of the light group is changed.

  2. The second part of the flow uses the “state changed” node with a regular expression to limit it to just lights (this is just to reduce the number of events we need to process). It will then check if the light that
    changed is a light in our list of lights in the group. If it is then it will forward on the payload.

This then allows me to detect any changes in the light group.

[{"id":"2b79b1c358a510e2","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"a1919913755ef30d","type":"function","z":"2b79b1c358a510e2","name":"Filter out lights not in the light group","func":"var d = msg[\"data\"]\nif (d === undefined) {\n    node.error(\"Data was undefined: \" + msg);\n    return null;\n}\n\nvar changed_entity_id = d[\"entity_id\"]\n\nvar new_state = d[\"new_state\"]\nif (new_state === undefined) {\n    node.error(\"New State was undefined: \" + changed_entity_id);\n    return null;\n}\n\nvar entity_attributes = new_state[\"attributes\"]\nif(entity_attributes === undefined) {\n    node.error(\"Attributes was undefined: \" + changed_entity_id);\n    return null;\n}\n\nvar group_entity_ids = entity_attributes[\"entity_id\"]\nif(!(group_entity_ids === undefined)) {\n    // If we have entities this is a group so ignore it\n    // we are only insterested in actual lights\n    return null;\n}\n\n// Get the previously created list of lights\nvar valid_entity_ids = flow.get(\"lights_in_group\")\n// If the variable isn't set yet we don't let anything through\n// This is preferable for my situation.\nif (valid_entity_ids === undefined) {\n    node.error(\"Lights in group not set yet\");\n    return null;\n}\n\nif(valid_entity_ids.includes(changed_entity_id)) {\n    // Make the payload look the same as the state_changed node would produce\n    // var newMsg = {\n    //     payload: msg.payload.event.new_state.state,\n    //     data: msg.payload.event\n    // }\n    // return newMsg;\n    return msg\n} else {\n    return null;\n}\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":220,"wires":[["a8ca976a162c4234"]]},{"id":"a98a8ce84e87e90c","type":"server-state-changed","z":"2b79b1c358a510e2","name":"","server":"f71a28fc.c73d58","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.all_downstairs_lights_group","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":220,"y":120,"wires":[["acc60331edae4e77"]]},{"id":"2a7708567efd0da0","type":"change","z":"2b79b1c358a510e2","name":"","rules":[{"t":"set","p":"lights_in_group","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":850,"y":120,"wires":[[]]},{"id":"acc60331edae4e77","type":"function","z":"2b79b1c358a510e2","name":"Get all lights in light group","func":"var light_group_entity_id = msg.topic\nvar list_of_valid_entities = get_entities_in_group(light_group_entity_id)\n\nvar newMsg = { payload: list_of_valid_entities }\nreturn newMsg;\n\n\nfunction get_entities_in_group(entity_id) {\n    var return_list = []\n    var seen_before = []\n    _get_entities_in_group(entity_id, return_list, seen_before)\n    return return_list\n}\n\nfunction _get_entities_in_group(entity_id, return_list, seen_before) {\n    var states = global.get('homeassistant.homeAssistant.states');\n    // Get the state of the light we are checking\n    var light_group_entity = states[entity_id];\n    if(!(light_group_entity === undefined)) {\n        var array_of_entities_in_group = light_group_entity[\"attributes\"][\"entity_id\"];\n\n        // IF no entity_id this is an actual light in our group\n        // Add it to the list\n        if (array_of_entities_in_group === undefined || array_of_entities_in_group.length == 0) {\n            return_list.push(entity_id)\n        } else {\n            // If we have entity_ids - loop through them.\n            for (let index = 0; index < array_of_entities_in_group.length; index++) {\n                const element = array_of_entities_in_group[index];\n                if (!seen_before.includes(element)) {\n                    seen_before.push(element)\n                _get_entities_in_group(element, return_list, seen_before);\n                }\n            }\n        }\n    }\n\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":120,"wires":[["2a7708567efd0da0"]]},{"id":"a8ca976a162c4234","type":"debug","z":"2b79b1c358a510e2","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":890,"y":220,"wires":[]},{"id":"6b180f7f5023543a","type":"server-state-changed","z":"2b79b1c358a510e2","name":"","server":"f71a28fc.c73d58","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"^light.","entityidfiltertype":"regex","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":140,"y":220,"wires":[["a1919913755ef30d"]]},{"id":"f71a28fc.c73d58","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]
1 Like

You don’t need to use an events all and a switch. The event state has a regex option for the entity.

image

1 Like

Good point!