mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2024-11-16 02:18:31 -07:00
Fix optimistic group behavior whenever a device is shared between groups (#2134)
This commit is contained in:
parent
4abafa9527
commit
09b7fe699e
@ -90,21 +90,7 @@ class Groups extends BaseExtension {
|
|||||||
if (entity.type === 'device') {
|
if (entity.type === 'device') {
|
||||||
for (const zigbeeGroup of zigbeeGroups) {
|
for (const zigbeeGroup of zigbeeGroups) {
|
||||||
if (zigbeeGroup.hasMember(entity.endpoint)) {
|
if (zigbeeGroup.hasMember(entity.endpoint)) {
|
||||||
let shouldGroupChange = true;
|
if (!payload || payload.state !== 'OFF' || this.allMembersOff(zigbeeGroup)) {
|
||||||
|
|
||||||
if (payload.state && payload.state === 'OFF') {
|
|
||||||
for (const member of zigbeeGroup.members) {
|
|
||||||
const device = member.getDevice();
|
|
||||||
if (this.state.exists(device.ieeeAddr)) {
|
|
||||||
const state = this.state.get(device.ieeeAddr);
|
|
||||||
if (state.state && state.state === 'ON') {
|
|
||||||
shouldGroupChange = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldGroupChange) {
|
|
||||||
await this.publishEntityState(zigbeeGroup.groupID, payload, reason);
|
await this.publishEntityState(zigbeeGroup.groupID, payload, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +101,9 @@ class Groups extends BaseExtension {
|
|||||||
await this.publishEntityState(member.getDevice().ieeeAddr, payload, reason);
|
await this.publishEntityState(member.getDevice().ieeeAddr, payload, reason);
|
||||||
for (const zigbeeGroup of zigbeeGroups) {
|
for (const zigbeeGroup of zigbeeGroups) {
|
||||||
if (zigbeeGroup.hasMember(member)) {
|
if (zigbeeGroup.hasMember(member)) {
|
||||||
groupIDsToPublish.add(zigbeeGroup.groupID);
|
if (!payload || payload.state !== 'OFF' || this.allMembersOff(zigbeeGroup)) {
|
||||||
|
groupIDsToPublish.add(zigbeeGroup.groupID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,6 +115,19 @@ class Groups extends BaseExtension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allMembersOff(zigbeeGroup) {
|
||||||
|
for (const member of zigbeeGroup.members) {
|
||||||
|
const device = member.getDevice();
|
||||||
|
if (this.state.exists(device.ieeeAddr)) {
|
||||||
|
const state = this.state.get(device.ieeeAddr);
|
||||||
|
if (state && state.state === 'ON') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
async onMQTTMessage(topic, message) {
|
async onMQTTMessage(topic, message) {
|
||||||
let type;
|
let type;
|
||||||
let group;
|
let group;
|
||||||
|
@ -316,7 +316,7 @@ describe('Groups', () => {
|
|||||||
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_2", '{"state":"ON"}', {"retain": false, qos: 0}, expect.any(Function));
|
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_2", '{"state":"ON"}', {"retain": false, qos: 0}, expect.any(Function));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should not publish state change off if any lights within are still on', async () => {
|
it('Should not publish state change off if any lights within are still on when changed via device', async () => {
|
||||||
const device_1 = zigbeeHerdsman.devices.bulb_color;
|
const device_1 = zigbeeHerdsman.devices.bulb_color;
|
||||||
const device_2 = zigbeeHerdsman.devices.bulb;
|
const device_2 = zigbeeHerdsman.devices.bulb;
|
||||||
const endpoint_1 = device_1.getEndpoint(1);
|
const endpoint_1 = device_1.getEndpoint(1);
|
||||||
@ -340,6 +340,32 @@ describe('Groups', () => {
|
|||||||
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function));
|
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should not publish state change off if any lights within are still on when changed via shared group', 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},
|
||||||
|
'2': {friendly_name: 'group_2', retain: false, devices: [device_1.ieeeAddr]},
|
||||||
|
});
|
||||||
|
await controller.start();
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
await MQTT.events.message('zigbee2mqtt/group_1/set', JSON.stringify({state: 'ON'}));
|
||||||
|
await flushPromises();
|
||||||
|
MQTT.publish.mockClear();
|
||||||
|
|
||||||
|
await MQTT.events.message('zigbee2mqtt/group_2/set', JSON.stringify({state: 'OFF'}));
|
||||||
|
await flushPromises();
|
||||||
|
expect(MQTT.publish).toHaveBeenCalledTimes(2);
|
||||||
|
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_2", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function));
|
||||||
|
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", '{"state":"OFF"}', {"retain": false, qos: 0}, expect.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
it('Should publish state change off if all lights within turn off', async () => {
|
it('Should publish state change off if all lights within turn off', async () => {
|
||||||
const device_1 = zigbeeHerdsman.devices.bulb_color;
|
const device_1 = zigbeeHerdsman.devices.bulb_color;
|
||||||
const device_2 = zigbeeHerdsman.devices.bulb;
|
const device_2 = zigbeeHerdsman.devices.bulb;
|
||||||
|
Loading…
Reference in New Issue
Block a user