Only publish changed properties for groups and its members. #6718

This commit is contained in:
Koen Kanters
2021-03-17 21:44:29 +01:00
parent 144fdb43da
commit 1acccc002a
4 changed files with 39 additions and 8 deletions
+2 -2
View File
@@ -86,8 +86,8 @@ class Groups extends Extension {
const payload = {};
properties.forEach((prop) => {
if (data.to.hasOwnProperty(prop)) {
payload[prop] = data.to[prop];
if (data.changed.hasOwnProperty(prop)) {
payload[prop] = data.changed[prop];
}
});
+7 -4
View File
@@ -77,18 +77,21 @@ class State {
set(ID, state, reason=null) {
const toState = objectAssignDeep.noMutate(state);
const fromState = this.state[ID];
const changed = {};
for (const property of Object.keys(toState)) {
if (dontCacheProperties.find((p) => property.match(p))) {
delete toState[property];
}
if (!fromState || toState[property] !== fromState[property]) {
changed[property] = toState[property];
}
}
const fromState = this.state[ID];
this.state[ID] = toState;
this.eventBus.emit('stateChange', {ID, from: fromState, to: state, reason});
this.eventBus.emit('stateChange', {ID, from: fromState, to: state, reason, changed});
}
removeKey(ID, path) {
+28
View File
@@ -505,6 +505,34 @@ describe('Groups', () => {
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_1", stringify({"state":"OFF"}), {"retain": false, qos: 0}, expect.any(Function));
});
it('Should only update group state with changed properties', async () => {
const device_1 = zigbeeHerdsman.devices.bulb_color;
const device_2 = zigbeeHerdsman.devices.bulb;
const endpoint_1 = device_1.getEndpoint(1);
const endpoint_2 = device_2.getEndpoint(1);
const group = zigbeeHerdsman.groups.group_1;
group.members.push(endpoint_1);
group.members.push(endpoint_2);
settings.set(['groups'], {
'1': {friendly_name: 'group_1', devices: [device_1.ieeeAddr, device_2.ieeeAddr], retain: false}
});
await controller.start();
await flushPromises();
MQTT.publish.mockClear();
await MQTT.events.message('zigbee2mqtt/bulb_color/set', stringify({state: 'OFF', color_temp: 200}));
await MQTT.events.message('zigbee2mqtt/bulb/set', stringify({state: 'ON', color_temp: 250}));
await flushPromises();
MQTT.publish.mockClear();
await MQTT.events.message('zigbee2mqtt/group_1/set', stringify({color_temp: 300}));
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(3);
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", stringify({"color":{"x":0.415211980162654,"y":0.395434886759171},"color_temp":300,"state":"OFF"}), {"retain": false, qos: 0}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", stringify({"color":{"x":0.415211980162654,"y":0.395434886759171},"color_temp":300,"state":"ON"}), {"retain": true, qos: 0}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_1", stringify({"color":{"x":0.415211980162654,"y":0.395434886759171},"color_temp":300,"state":"ON"}), {"retain": false, qos: 0}, expect.any(Function));
});
it('Should publish state change off even when missing current state', async () => {
const device_1 = zigbeeHerdsman.devices.bulb_color;
const device_2 = zigbeeHerdsman.devices.bulb;
+2 -2
View File
@@ -1377,12 +1377,12 @@ describe('Publish', () => {
);
expect(MQTT.publish).toHaveBeenNthCalledWith(4,
'zigbee2mqtt/bulb_2',
stringify({"brightness":100,"color":{"x":0.408707336668894,"y":0.39239142575868},"color_temp":290,"state":"ON"}),
stringify({"brightness":100,"color":{"x":0.408707336668894,"y":0.39239142575868},"state":"ON"}),
{retain: false, qos: 0}, expect.any(Function)
);
expect(MQTT.publish).toHaveBeenNthCalledWith(5,
'zigbee2mqtt/group_with_tradfri',
stringify({"brightness":100,"color":{"x":0.408707336668894,"y":0.39239142575868},"color_temp":290,"state":"ON"}),
stringify({"brightness":100,"color":{"x":0.408707336668894,"y":0.39239142575868},"state":"ON"}),
{retain: false, qos: 0}, expect.any(Function)
);
});