mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-07-23 12:01:43 +00:00
Updates for scenes. https://github.com/Koenkk/zigbee-herdsman-converters/pull/1531
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
// );
|
||||
// });
|
||||
});
|
||||
|
||||
@@ -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)};
|
||||
|
||||
Reference in New Issue
Block a user