diff --git a/lib/eventBus.js b/lib/eventBus.js index 1dee91a27..499c70f79 100644 --- a/lib/eventBus.js +++ b/lib/eventBus.js @@ -3,6 +3,8 @@ const assert = require('assert'); const allowedEvents = [ 'deviceRemoved', // Device has been removed + 'deviceRenamed', // Device has been renamed + 'groupRenamed', // Group has been renamed 'publishEntityState', // Entity state will be published ]; diff --git a/lib/extension/bridgeConfig.js b/lib/extension/bridgeConfig.js index 22c6bb5d3..ffd8a2216 100644 --- a/lib/extension/bridgeConfig.js +++ b/lib/extension/bridgeConfig.js @@ -218,6 +218,9 @@ class BridgeConfig extends BaseExtension { const isGroup = settings.getGroup(from) !== null; settings.changeFriendlyName(from, to); logger.info(`Successfully renamed - ${from} to ${to} `); + const entity = this.zigbee.resolveEntity(to); + const eventData = isGroup ? {group: entity.group} : {device: entity.device}; + this.eventBus.emit(`${isGroup ? 'group' : 'device'}Renamed`, eventData); this.mqtt.log(`${isGroup ? 'group' : 'device'}_renamed`, {from, to}); } catch (error) { logger.error(`Failed to rename - ${from} to ${to}`); diff --git a/lib/extension/homeassistant.js b/lib/extension/homeassistant.js index 796a96b8a..6d4999ca6 100644 --- a/lib/extension/homeassistant.js +++ b/lib/extension/homeassistant.js @@ -1331,6 +1331,7 @@ class HomeAssistant extends BaseExtension { this.eventBus.on('deviceRemoved', (data) => this.onDeviceRemoved(data.device)); this.eventBus.on('publishEntityState', (data) => this.onPublishEntityState(data)); + this.eventBus.on('deviceRenamed', (data) => this.onDeviceRenamed(data.device)); } onDeviceRemoved(device) { @@ -1377,6 +1378,12 @@ class HomeAssistant extends BaseExtension { } } + onDeviceRenamed(device) { + const mappedModel = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID); + logger.info(`Refreshing Home Assistant discovery topic for '${device.ieeeAddr}'`); + this.discover(device, mappedModel, true); + } + async onMQTTConnected() { this.mqtt.subscribe(this.statusTopic); diff --git a/test/homeassistant.test.js b/test/homeassistant.test.js index c59089d46..314b9c898 100644 --- a/test/homeassistant.test.js +++ b/test/homeassistant.test.js @@ -688,6 +688,40 @@ describe('HomeAssistant extension', () => { expect(MQTT.publish).toHaveBeenCalledTimes(1); }); + it('Should refresh discovery when device is renamed', async () => { + controller = new Controller(false); + await controller.start(); + await flushPromises(); + MQTT.publish.mockClear(); + MQTT.events.message('zigbee2mqtt/bridge/config/rename', '{"old": "weather_sensor", "new": "weather_sensor_renamed"}'); + await flushPromises(); + + const payload = { + 'unit_of_measurement': '°C', + 'device_class': 'temperature', + 'value_template': '{{ value_json.temperature }}', + 'state_topic': 'zigbee2mqtt/weather_sensor_renamed', + 'json_attributes_topic': 'zigbee2mqtt/weather_sensor_renamed', + 'name': 'weather_sensor_renamed_temperature', + 'unique_id': '0x0017880104e45522_temperature_zigbee2mqtt', + 'device': { + 'identifiers': ['zigbee2mqtt_0x0017880104e45522'], + 'name': 'weather_sensor_renamed', + 'sw_version': this.version, + 'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)', + 'manufacturer': 'Xiaomi', + }, + 'availability_topic': 'zigbee2mqtt/bridge/state', + }; + + expect(MQTT.publish).toHaveBeenCalledWith( + 'homeassistant/sensor/0x0017880104e45522/temperature/config', + JSON.stringify(payload), + { retain: true, qos: 0 }, + expect.any(Function), + ); + }); + it('Should discover update_available sensor when device supports it', async () => { controller = new Controller(false); await controller.start();