diff --git a/lib/extension/groups.js b/lib/extension/groups.js index ab50e2184..511bcc506 100644 --- a/lib/extension/groups.js +++ b/lib/extension/groups.js @@ -85,14 +85,21 @@ class Groups extends Extension { const properties = ['state', 'brightness', 'color_temp', 'color', 'color_mode']; const payload = {}; - properties.forEach((prop) => { - if (data.changed.hasOwnProperty(prop)) { - payload[prop] = data.changed[prop]; + let endpointName; + for (let [prop, value] of Object.entries(data.changed)) { + const endpointNameMatch = utils.getEndpointNames().find((n) => prop.endsWith(`_${n}`)); + if (endpointNameMatch) { + prop = prop.substring(0, prop.length - endpointNameMatch.length - 1); + endpointName = endpointNameMatch; } - }); + + if (properties.includes(prop)) { + payload[prop] = value; + } + } if (Object.keys(payload).length) { - const resolvedEntity = this.zigbee.resolveEntity(data.ID); + const resolvedEntity = this.zigbee.resolveEntity(`${data.ID}${endpointName ? `/${endpointName}` : ''}`); const zigbeeGroups = this.zigbee.getGroups().filter((zigbeeGroup) => { const settingsGroup = settings.getGroup(zigbeeGroup.groupID); return settingsGroup && settingsGroup.optimistic; diff --git a/test/group.test.js b/test/group.test.js index ccfca44bf..2262a4874 100644 --- a/test/group.test.js +++ b/test/group.test.js @@ -26,6 +26,7 @@ describe('Groups', () => { data.writeDefaultConfiguration(); settings.reRead(); MQTT.publish.mockClear(); + zigbeeHerdsman.groups.gledopto_group.command.mockClear(); zigbeeHerdsmanConverters.toZigbeeConverters.__clearStore__(); }) @@ -387,6 +388,20 @@ describe('Groups', () => { expect(group.command).toHaveBeenCalledWith("genOnOff", "on", {}, {}); }); + it('Should publish state of group when specific state of specific endpoint is changed', async () => { + const group = zigbeeHerdsman.groups.gledopto_group; + await controller.start(); + await flushPromises(); + + MQTT.publish.mockClear(); + await MQTT.events.message('zigbee2mqtt/GLEDOPTO_2ID/set', stringify({state_cct: 'ON'})); + await flushPromises(); + expect(MQTT.publish).toHaveBeenCalledTimes(2); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/GLEDOPTO_2ID", stringify({"state_cct":"ON"}), {"retain": false, qos: 0}, expect.any(Function)); + expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/gledopto_group", stringify({"state":"ON"}), {"retain": false, qos: 0}, expect.any(Function)); + expect(group.command).toHaveBeenCalledTimes(0); + }); + it('Should publish state change of all members when a group changes its state, filtered', async () => { const device = zigbeeHerdsman.devices.bulb_color; const endpoint = device.getEndpoint(1);