From a5b959a6d520679bce1586c50f01a57f13d6af01 Mon Sep 17 00:00:00 2001 From: slugzero <2014249+slugzero@users.noreply.github.com> Date: Wed, 20 Dec 2023 19:46:59 +0100 Subject: [PATCH] fix: Clear old Home Assistant discovery topics when exposes are changed (#20313) --- lib/extension/homeassistant.ts | 6 ++++++ test/homeassistant.test.js | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/extension/homeassistant.ts b/lib/extension/homeassistant.ts index 020c83498b..c1555371ca 100644 --- a/lib/extension/homeassistant.ts +++ b/lib/extension/homeassistant.ts @@ -1333,6 +1333,7 @@ export default class HomeAssistant extends Extension { (entity.options.hasOwnProperty('homeassistant') && !entity.options.homeassistant))) { return; } + const lastDiscovered = this.discovered[discoverKey]; this.discovered[discoverKey] = {topics: new Set(), mockProperties: new Set(), objectIDs: new Set()}; this.getConfigs(entity).forEach((config) => { @@ -1543,6 +1544,11 @@ export default class HomeAssistant extends Extension { config.mockProperties?.forEach((mockProperty) => this.discovered[discoverKey].mockProperties.add(mockProperty)); }); + lastDiscovered?.topics?.forEach((topic) => { + if (!this.discovered[discoverKey].topics.has(topic)) { + this.mqtt.publish(topic, null, {retain: true, qos: 1}, this.discoveryTopic, false, false); + } + }); } @bind private onMQTTMessage(data: eventdata.MQTTMessage): void { diff --git a/test/homeassistant.test.js b/test/homeassistant.test.js index f366d333cd..56ccf7a75b 100644 --- a/test/homeassistant.test.js +++ b/test/homeassistant.test.js @@ -2482,4 +2482,17 @@ describe('HomeAssistant extension', () => { expect.any(Function), ); }); -}); \ No newline at end of file + + it('Should remove discovery entries for removed exposes when device options change', async () => { + MQTT.publish.mockClear(); + MQTT.events.message('zigbee2mqtt/bridge/request/device/options', stringify({"id": "0xf4ce368a38be56a1", "options": {"dimmer_1_enabled": "false", "dimmer_1_dimming_enabled": "false"}})); + await flushPromises(); + + expect(MQTT.publish).toHaveBeenCalledWith( + 'homeassistant/light/0xf4ce368a38be56a1/light_l2/config', + null, + { retain: true, qos: 1 }, + expect.any(Function), + ); + }); +});