From f9c4b4e92614e772b849303ccac15daae65df725 Mon Sep 17 00:00:00 2001 From: Valentin Date: Sat, 5 Feb 2022 10:12:13 +0100 Subject: [PATCH] HA Discover when user change option (#11210) * HA Discover when user change option * Fix unit tests * Update homeassistant.ts * Update homeassistant.ts Co-authored-by: Koen Kanters --- lib/extension/homeassistant.ts | 6 ++++-- test/homeassistant.test.js | 20 +++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/extension/homeassistant.ts b/lib/extension/homeassistant.ts index c9a66b77a..d991d7e3c 100644 --- a/lib/extension/homeassistant.ts +++ b/lib/extension/homeassistant.ts @@ -95,6 +95,7 @@ export default class HomeAssistant extends Extension { this.eventBus.onDeviceJoined(this, this.onZigbeeEvent); this.eventBus.onDeviceInterview(this, this.onZigbeeEvent); this.eventBus.onDeviceMessage(this, this.onZigbeeEvent); + this.eventBus.onEntityOptionsChanged(this, (data) => this.discover(data.entity, true)); this.mqtt.subscribe(this.statusTopic); this.mqtt.subscribe(defaultStatusTopic); @@ -896,8 +897,9 @@ export default class HomeAssistant extends Extension { let configs: DiscoveryEntry[] = []; if (isDevice) { - for (const expose of entity.exposes()) { - configs.push(...this.exposeToConfig([expose], 'device', entity.definition, entity.exposes())); + const exposes = entity.exposes(); // avoid calling it hundred of times/s + for (const expose of exposes) { + configs.push(...this.exposeToConfig([expose], 'device', entity.definition, exposes)); } for (const mapping of legacyMapping) { diff --git a/test/homeassistant.test.js b/test/homeassistant.test.js index d3181d51c..196a81aff 100644 --- a/test/homeassistant.test.js +++ b/test/homeassistant.test.js @@ -58,7 +58,12 @@ describe('HomeAssistant extension', () => { configs.forEach((c) => { const id = c['type'] + '/' + c['object_id']; if (cfg_type_object_ids.includes(id)) { - duplicated.push(d.model); + if (typeof d.exposes == 'function') { + // A dynamic function must exposes all possible attributes for the docs + console.warn(`${d.model} dynamic exposes contains duplicated ${id}`) + } else { + duplicated.push(d.model); + } } else { cfg_type_object_ids.push(id); } @@ -993,6 +998,19 @@ describe('HomeAssistant extension', () => { await flushPromises(); }); + it('Should discover when options change', async () => { + const device = controller.zigbee.resolveEntity(zigbeeHerdsman.devices.bulb); + MQTT.publish.mockClear(); + controller.eventBus.emitEntityOptionsChanged({entity: device, from: {}, to: {'test': 123}}); + await flushPromises(); + expect(MQTT.publish).toHaveBeenCalledWith( + `homeassistant/light/${device.ID}/light/config`, + expect.any(String), + expect.any(Object), + expect.any(Function), + ); + }); + it('Should send all status when home assistant comes online (default topic)', async () => { data.writeDefaultState(); extension.state.load();