This commit is contained in:
Koen Kanters
2020-09-19 11:07:54 +02:00
parent 7fe3167e97
commit 206f02b200
4 changed files with 72 additions and 4 deletions
+18 -3
View File
@@ -83,6 +83,7 @@ class EntityPublish extends Extension {
let options = {};
let device = null;
let definition = null;
let membersState = null;
assert(resolvedEntity.type === 'device' || resolvedEntity.type === 'group');
if (resolvedEntity.type === 'device') {
@@ -107,6 +108,11 @@ class EntityPublish extends Extension {
d.toZigbee.forEach(converters.add, converters);
}
converters = [...converters];
membersState = {};
for (const member of resolvedEntity.group.members) {
const ieeeAddr = member.getDevice().ieeeAddr;
membersState[ieeeAddr] = this.state.get(ieeeAddr);
}
}
// Convert the MQTT message to a Zigbee message.
@@ -139,12 +145,12 @@ class EntityPublish extends Extension {
* the color temperature. This would lead to 2 zigbee publishes, where the first one
* (state) is probably unecessary.
*/
const deviceState = this.state.get(resolvedEntity.settings.ID) || {};
const entityState = this.state.get(resolvedEntity.settings.ID) || {};
if (settings.get().homeassistant) {
const hasColorTemp = json.hasOwnProperty('color_temp');
const hasColor = json.hasOwnProperty('color');
const hasBrightness = json.hasOwnProperty('brightness');
const isOn = deviceState && deviceState.state === 'ON' ? true : false;
const isOn = entityState && entityState.state === 'ON' ? true : false;
if (isOn && (hasColorTemp || hasColor) && !hasBrightness) {
delete json.state;
logger.debug('Skipping state because of Home Assistant');
@@ -208,7 +214,8 @@ class EntityPublish extends Extension {
message: json,
logger,
device,
state: deviceState,
state: entityState,
membersState,
mapped: definition,
};
@@ -231,6 +238,14 @@ class EntityPublish extends Extension {
this.publishEntityState(resolvedEntity.settings.ID, msg);
}
// Enable after merge: https://github.com/Koenkk/zigbee-herdsman-converters/pull/1531
/* istanbul ignore next */
if (result && result.membersState) {
for (const [ieeeAddr, state] of Object.entries(result.membersState)) {
this.publishEntityState(ieeeAddr, state);
}
}
// It's possible for devices to get out of sync when writing an attribute that's not reportable.
// So here we re-read the value after a specified timeout, this timeout could for example be the
// transition time of a color change or for forcing a state read for devices that don't
-1
View File
@@ -61,7 +61,6 @@ class State {
try {
fs.writeFileSync(this.file, json, 'utf8');
} catch (e) {
console.log(e.message);
logger.error(`Failed to write state to '${this.file}' (${e.message})`);
}
} else {
+52
View File
@@ -1250,4 +1250,56 @@ describe('Publish', () => {
expect(MQTT.publish.mock.calls[2]).toEqual([ 'zigbee2mqtt/bulb_color', stringify({"state":"OFF","brightness":150}), { qos: 0, retain: false }, expect.any(Function)]);
expect(MQTT.publish.mock.calls[3]).toEqual([ 'zigbee2mqtt/bulb_color', stringify({"state":"ON","brightness":150}), { qos: 0, retain: false }, expect.any(Function)]);
});
// Enable after merge: https://github.com/Koenkk/zigbee-herdsman-converters/pull/1531
// it('Scenes', async () => {
// const bulb_color_2 = zigbeeHerdsman.devices.bulb_color_2.getEndpoint(1);
// const bulb_2 = zigbeeHerdsman.devices.bulb_2.getEndpoint(1);
// const group = zigbeeHerdsman.groups.group_tradfri_remote;
// await MQTT.events.message('zigbee2mqtt/bulb_color_2/set', stringify({"state": "ON", "brightness": 50, "color_temp": 290}));
// await MQTT.events.message('zigbee2mqtt/bulb_2/set', stringify({"state": "ON", "brightness": 100}));
// await flushPromises();
// await MQTT.events.message('zigbee2mqtt/group_tradfri_remote/set', stringify({"scene_store": 1}));
// await flushPromises();
// expect(group.command).toHaveBeenCalledTimes(1);
// expect(group.command).toHaveBeenCalledWith('genScenes', 'store', { groupid: 15071, sceneid: 1 }, {});
// await MQTT.events.message('zigbee2mqtt/bulb_color_2/set', stringify({"state": "ON", "brightness": 250, "color_temp": 20}));
// await MQTT.events.message('zigbee2mqtt/bulb_2/set', stringify({"state": "ON", "brightness": 110}));
// await flushPromises();
// MQTT.publish.mockClear();
// group.command.mockClear();
// await MQTT.events.message('zigbee2mqtt/group_tradfri_remote/set', stringify({"scene_recall": 1}));
// await flushPromises();
// expect(group.command).toHaveBeenCalledTimes(1);
// expect(group.command).toHaveBeenCalledWith('genScenes', 'recall', { groupid: 15071, sceneid: 1 }, {});
// expect(MQTT.publish).toHaveBeenCalledTimes(5);
// expect(MQTT.publish).toHaveBeenNthCalledWith(1,
// 'zigbee2mqtt/group_tradfri_remote',
// stringify({"brightness":50,"color":{"x":0.408707336668894,"y":0.39239142575868},"color_temp":290,"state":"ON"}),
// {retain: false, qos: 0}, expect.any(Function)
// );
// expect(MQTT.publish).toHaveBeenNthCalledWith(2,
// 'zigbee2mqtt/bulb_color_2',
// stringify({"brightness":50,"color":{"x":0.408707336668894,"y":0.39239142575868},"color_temp":290,"state":"ON"}),
// {retain: false, qos: 0}, expect.any(Function)
// );
// expect(MQTT.publish).toHaveBeenNthCalledWith(3,
// 'zigbee2mqtt/group_tradfri_remote',
// stringify({"brightness":100,"color":{"x":0.408707336668894,"y":0.39239142575868},"color_temp":290,"state":"ON"}),
// {retain: false, qos: 0}, expect.any(Function)
// );
// expect(MQTT.publish).toHaveBeenNthCalledWith(4,
// 'zigbee2mqtt/bulb_2',
// stringify({"brightness":100,"color":{"x":0.408707336668894,"y":0.39239142575868},"color_temp":290,"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"}),
// {retain: false, qos: 0}, expect.any(Function)
// );
// });
});
+2
View File
@@ -41,7 +41,9 @@ class Endpoint {
this.write = jest.fn();
this.bind = jest.fn();
this.unbind = jest.fn();
this.save = jest.fn();
this.configureReporting = jest.fn();
this.meta = {};
this.binds = binds;
this.getInputClusters = () => inputClusters.map((c) => {
return {ID: c, name: getKeyByValue(clusters, c)};