mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-07-09 05:21:38 +00:00
fix: Only republish changed scenes to Home Assistant when changed (#20248)
This commit is contained in:
committed by
GitHub
parent
2c5d3e14f7
commit
e0f50218d7
@@ -1615,6 +1615,7 @@ export default class HomeAssistant extends Extension {
|
||||
@bind async onScenesChanged(): Promise<void> {
|
||||
// Re-trigger MQTT discovery of all devices and groups, similar to bridge.ts
|
||||
const entities = [...this.zigbee.devices(), ...this.zigbee.groups()];
|
||||
const clearedEntities = new Set<Device|Group>();
|
||||
|
||||
// First, clear existing scene discovery topics
|
||||
entities.forEach((entity) => {
|
||||
@@ -1622,6 +1623,7 @@ export default class HomeAssistant extends Extension {
|
||||
this.discovered[this.getDiscoverKey(entity)]?.topics.forEach((topic) => {
|
||||
if (topic.startsWith('scene')) {
|
||||
this.mqtt.publish(topic, null, {retain: true, qos: 1}, this.discoveryTopic, false, false);
|
||||
clearedEntities.add(entity);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1633,7 +1635,7 @@ export default class HomeAssistant extends Extension {
|
||||
|
||||
// Re-discover all entities (including their new scenes).
|
||||
logger.debug(`Re-discovering entities with their scenes.`);
|
||||
entities.forEach((entity) => {
|
||||
clearedEntities.forEach((entity) => {
|
||||
this.discover(entity, true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2160,21 +2160,27 @@ describe('HomeAssistant extension', () => {
|
||||
});
|
||||
|
||||
it('Should rediscover scenes when a scene is changed', async () => {
|
||||
const device = controller.zigbee.resolveEntity(zigbeeHerdsman.devices.bulb_color_2);
|
||||
MQTT.publish.mockClear();
|
||||
controller.eventBus.emitScenesChanged();
|
||||
await flushPromises();
|
||||
|
||||
// Discovery messages for scenes have been purged.
|
||||
expect(MQTT.publish).toHaveBeenCalledWith(
|
||||
`homeassistant/scene/${device.ID}/scene_1/config`,
|
||||
`homeassistant/scene/0x000b57fffec6a5b4/scene_1/config`,
|
||||
null,
|
||||
{retain: true, qos: 1},
|
||||
expect.any(Function),
|
||||
);
|
||||
expect(MQTT.publish).toHaveBeenCalledWith(
|
||||
`homeassistant/scene/1221051039810110150109113116116_9/scene_4/config`,
|
||||
null,
|
||||
{retain: true, qos: 1},
|
||||
expect.any(Function),
|
||||
);
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
await flushPromises();
|
||||
|
||||
const payload = {
|
||||
let payload = {
|
||||
'name': 'Chill scene',
|
||||
'command_topic': 'zigbee2mqtt/bulb_color_2/set',
|
||||
'payload_on': '{ "scene_recall": 1 }',
|
||||
@@ -2192,13 +2198,40 @@ describe('HomeAssistant extension', () => {
|
||||
'origin': origin,
|
||||
'availability': [ { 'topic': 'zigbee2mqtt/bridge/state' } ]
|
||||
}
|
||||
|
||||
expect(MQTT.publish).toHaveBeenCalledWith(
|
||||
`homeassistant/scene/${device.ID}/scene_1/config`,
|
||||
`homeassistant/scene/0x000b57fffec6a5b4/scene_1/config`,
|
||||
stringify(payload),
|
||||
{retain: true, qos: 1},
|
||||
expect.any(Function),
|
||||
);
|
||||
|
||||
payload = {
|
||||
'name': 'Scene 4',
|
||||
'command_topic': 'zigbee2mqtt/ha_discovery_group/set',
|
||||
'payload_on': '{ "scene_recall": 4 }',
|
||||
'json_attributes_topic':'zigbee2mqtt/ha_discovery_group',
|
||||
'object_id': 'ha_discovery_group_4_scene_4',
|
||||
'unique_id': '9_scene_4_zigbee2mqtt',
|
||||
'device': {
|
||||
'identifiers': [ 'zigbee2mqtt_1221051039810110150109113116116_9' ],
|
||||
'name': 'ha_discovery_group',
|
||||
'sw_version': 'Zigbee2MQTT 1.34.0-dev',
|
||||
'model': 'Group',
|
||||
'manufacturer': 'Zigbee2MQTT',
|
||||
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae'
|
||||
},
|
||||
'origin': origin,
|
||||
'availability': [ { 'topic': 'zigbee2mqtt/bridge/state' } ]
|
||||
}
|
||||
expect(MQTT.publish).toHaveBeenCalledWith(
|
||||
`homeassistant/scene/1221051039810110150109113116116_9/scene_4/config`,
|
||||
stringify(payload),
|
||||
{retain: true, qos: 1},
|
||||
expect.any(Function),
|
||||
);
|
||||
|
||||
// Only discovery entries for entities with scenes need to be republished.
|
||||
expect(MQTT.publish).toHaveBeenCalledTimes( 16 );
|
||||
});
|
||||
|
||||
it('Should not clear bridge entities unnecessarily', async () => {
|
||||
|
||||
Reference in New Issue
Block a user