diff --git a/lib/extension/bridgeConfig.js b/lib/extension/bridgeConfig.js index 61b1337f0..708363f91 100644 --- a/lib/extension/bridgeConfig.js +++ b/lib/extension/bridgeConfig.js @@ -215,9 +215,10 @@ class BridgeConfig extends BaseExtension { _renameInternal(from, to) { try { + const isGroup = settings.getGroup(from) !== null; settings.changeFriendlyName(from, to); logger.info(`Successfully renamed - ${from} to ${to} `); - this.mqtt.log('device_renamed', {from, to}); + this.mqtt.log(`${isGroup ? 'group' : 'device'}_renamed`, {from, to}); } catch (error) { logger.error(`Failed to rename - ${from} to ${to}`); } diff --git a/lib/util/settings.js b/lib/util/settings.js index a0f15a02a..abd4dca19 100644 --- a/lib/util/settings.js +++ b/lib/util/settings.js @@ -600,9 +600,15 @@ function changeFriendlyName(IDorName, newName) { throw new Error(`friendly_name '${newName}' is already in use`); } - const device = getDeviceThrowIfNotExists(IDorName); const settings = get(); - settings.devices[device.ID].friendly_name = newName; + if (getDevice(IDorName)) { + settings.devices[getDevice(IDorName).ID].friendly_name = newName; + } else if (getGroup(IDorName)) { + settings.groups[getGroup(IDorName).ID].friendly_name = newName; + } else { + throw new Error(`Device or group '${IDorName}' does not exist`); + } + write(); } diff --git a/test/bridgeConfig.test.js b/test/bridgeConfig.test.js index 42834e354..186ceb773 100644 --- a/test/bridgeConfig.test.js +++ b/test/bridgeConfig.test.js @@ -203,6 +203,20 @@ describe('Bridge config', () => { expect(settings.getDevice('bulb_color2')).toStrictEqual(bulb_color2); }); + it('Should allow rename groups', async () => { + MQTT.publish.mockClear(); + expect(settings.getGroup(1)).toStrictEqual({"ID": 1, devices: [], friendlyName: "group_1", "friendly_name": "group_1", optimistic: true, retain: false}); + MQTT.events.message('zigbee2mqtt/bridge/config/rename', JSON.stringify({old: 'group_1', new: 'group_1_renamed'})); + await flushPromises(); + expect(settings.getGroup(1)).toStrictEqual({"ID": 1, devices: [], friendlyName: "group_1_renamed", "friendly_name": "group_1_renamed", optimistic: true, retain: false}); + expect(MQTT.publish).toHaveBeenCalledWith( + 'zigbee2mqtt/bridge/log', + JSON.stringify({type: 'group_renamed', message: {from: 'group_1', to: 'group_1_renamed'}}), + {qos: 0, retain: false}, + expect.any(Function) + ); + }); + it('Should allow to rename last joined device', async () => { const device = zigbeeHerdsman.devices.bulb; const payload = {device}; diff --git a/test/settings.test.js b/test/settings.test.js index 688f36ac2..da36f613f 100644 --- a/test/settings.test.js +++ b/test/settings.test.js @@ -539,6 +539,21 @@ describe('Settings', () => { }).toThrowError(`friendly_name 'myname' is already in use`); }); + it('Should throw when removing device which doesnt exist', async () => { + write(configurationFile, { + devices: { + '0x0017880104e45519': {friendly_name: 'myname', retain: false}, + '0x0017880104e45511': {friendly_name: 'myname1', retain: false} + }, + }); + + settings._reRead(); + + expect(() => { + settings.removeDevice('myname33'); + }).toThrowError(`Device 'myname33' does not exist`); + }); + it('Shouldnt write to configuration.yaml when there are no changes in it', () => { const contentConfiguration = {devices: 'devices.yaml'}; const contentDevices = {};