Fix state of members from group incorrect when toZigbee converter reads a member state. #7038

This commit is contained in:
Koen Kanters
2021-04-22 20:28:54 +02:00
parent 2c44f4ede9
commit 366c5fcb4d
4 changed files with 13 additions and 17 deletions
+1 -5
View File
@@ -4,7 +4,6 @@ const EventBus = require('./eventBus');
const State = require('./state');
const logger = require('./util/logger');
const settings = require('./util/settings');
const objectAssignDeep = require('object-assign-deep');
const utils = require('./util/utils');
const stringify = require('json-stable-stringify-without-jsonify');
const assert = require('assert');
@@ -281,12 +280,9 @@ class Controller {
}
let messagePayload = {...payload};
const currentState = this.state.exists(resolvedEntity.settings.ID) ?
this.state.get(resolvedEntity.settings.ID) : {};
const newState = objectAssignDeep.noMutate(currentState, payload);
// Update state cache with new state.
this.state.set(resolvedEntity.settings.ID, newState, stateChangeReason);
const newState = this.state.set(resolvedEntity.settings.ID, payload, stateChangeReason);
if (settings.get().advanced.cache_state) {
// Add cached state to payload
+1 -1
View File
@@ -86,7 +86,7 @@ class Groups extends Extension {
const payload = {};
let endpointName;
for (let [prop, value] of Object.entries(data.changed)) {
for (let [prop, value] of Object.entries(data.update)) {
const endpointNameMatch = utils.getEndpointNames().find((n) => prop.endsWith(`_${n}`));
if (endpointNameMatch) {
prop = prop.substring(0, prop.length - endpointNameMatch.length - 1);
+6 -9
View File
@@ -75,23 +75,20 @@ class State {
return this.state[ID];
}
set(ID, state, reason=null) {
const toState = objectAssignDeep.noMutate(state);
const fromState = this.state[ID];
const changed = {};
set(ID, update, reason=null) {
const fromState = this.state[ID] || {};
const toState = objectAssignDeep.noMutate(fromState, update);
const result = {...toState};
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];
}
}
this.state[ID] = toState;
this.eventBus.emit('stateChange', {ID, from: fromState, to: state, reason, changed});
this.eventBus.emit('stateChange', {ID, from: fromState, to: toState, reason, update});
return result;
}
removeKey(ID, path) {
+5 -2
View File
@@ -1064,6 +1064,7 @@ describe('Publish', () => {
it('Home Assistant: should not set state when color temperature is also set and device is already on', async () => {
settings.set(['homeassistant'], true);
const device = zigbeeHerdsman.devices.bulb_color;
controller.state.remove(device.ieeeAddr);
controller.state.set(device.ieeeAddr, {state: 'ON'})
const endpoint = device.getEndpoint(1);
const payload = {state: 'ON', color_temp: 100};
@@ -1079,6 +1080,7 @@ describe('Publish', () => {
it('Home Assistant: should set state when color temperature is also set and device is off', async () => {
settings.set(['homeassistant'], true);
const device = zigbeeHerdsman.devices.bulb_color;
controller.state.remove(device.ieeeAddr);
controller.state.set(device.ieeeAddr, {state: 'OFF'})
const endpoint = device.getEndpoint(1);
const payload = {state: 'ON', color_temp: 100};
@@ -1097,6 +1099,7 @@ describe('Publish', () => {
it('Home Assistant: should not set state when color is also set', async () => {
settings.set(['homeassistant'], true);
const device = zigbeeHerdsman.devices.bulb_color;
controller.state.remove(device.ieeeAddr);
controller.state.set(device.ieeeAddr, {state: 'ON'})
const endpoint = device.getEndpoint(1);
const payload = {state: 'ON', color: {x: 0.41, y: 0.25}};
@@ -1396,12 +1399,12 @@ describe('Publish', () => {
);
expect(MQTT.publish).toHaveBeenNthCalledWith(4,
'zigbee2mqtt/bulb_2',
stringify({"brightness":100,"color":{"x":0.408707336668894,"y":0.39239142575868},"state":"ON"}),
stringify({"brightness":100,"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},"state":"ON"}),
stringify({"brightness":100,"state":"ON"}),
{retain: false, qos: 0}, expect.any(Function)
);
});