From 9f31cd86a3261179b9990ec4a0e63a7eb5d9e005 Mon Sep 17 00:00:00 2001 From: Koen Kanters Date: Tue, 12 Mar 2019 21:19:04 +0100 Subject: [PATCH] Implemented MQTT group add and remove. https://github.com/Koenkk/zigbee2mqtt/issues/764 --- lib/extension/bridgeConfig.js | 16 +++++++++ lib/util/settings.js | 36 +++++++++++++++++++ test/bridgeConfig.test.js | 66 ++++++++++++++++++++++++++++++++--- 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/lib/extension/bridgeConfig.js b/lib/extension/bridgeConfig.js index f4417aab5..c731a8f3f 100644 --- a/lib/extension/bridgeConfig.js +++ b/lib/extension/bridgeConfig.js @@ -23,6 +23,8 @@ class BridgeConfig { this.remove = this.remove.bind(this); this.ban = this.ban.bind(this); this.deviceOptions = this.deviceOptions.bind(this); + this.addGroup = this.addGroup.bind(this); + this.removeGroup = this.removeGroup.bind(this); // Set supported options this.supportedOptions = { @@ -36,6 +38,8 @@ class BridgeConfig { 'remove': this.remove, 'ban': this.ban, 'device_options': this.deviceOptions, + 'add_group': this.addGroup, + 'remove_group': this.removeGroup, }; } @@ -159,6 +163,18 @@ class BridgeConfig { } } + addGroup(topic, message) { + const name = message.toString(); + const added = settings.addGroup(name); + added ? logger.info(`Added group '${name}'`) : logger.error(`Failed to add group '${name}'`); + } + + removeGroup(topic, message) { + const name = message.toString(); + const removed = settings.removeGroup(name); + removed ? logger.info(`Removed group '${name}'`) : logger.error(`Failed to remove group '${name}'`); + } + remove(topic, message) { this.removeOrBan(false, message); } diff --git a/lib/util/settings.js b/lib/util/settings.js index cdbf2c6cc..ee7123dca 100644 --- a/lib/util/settings.js +++ b/lib/util/settings.js @@ -160,6 +160,40 @@ function removeDevice(ieeeAddr) { writeRead(); } +function addGroup(groupName) { + const settings = getSettings(); + if (!settings.groups) { + settings.groups = {}; + } + + let ID = '1'; + while (settings.groups.hasOwnProperty(ID)) { + ID = (Number.parseInt(ID) + 1).toString(); + } + + settings.groups[ID] = {friendly_name: groupName}; + writeRead(); + + return true; +} + +function removeGroup(name) { + const settings = getSettings(); + if (!settings.groups) return; + + const ID = Object.keys(settings.groups).find((key) => { + return settings.groups[key].friendly_name === name; + }); + + if (ID) { + delete settings.groups[ID]; + writeRead(); + return true; + } else { + return false; + } +} + function getIeeeAddrByFriendlyName(friendlyName) { const entry = Object.entries(getDevices()).find(([ieeeAddr, device]) => device.friendly_name === friendlyName @@ -243,6 +277,8 @@ module.exports = { getDevices, addDevice: (ieeeAddr) => addDevice(ieeeAddr), removeDevice: (ieeeAddr) => removeDevice(ieeeAddr), + addGroup: (name) => addGroup(name), + removeGroup: (name) => removeGroup(name), getIeeeAddrByFriendlyName: (friendlyName) => getIeeeAddrByFriendlyName(friendlyName), getGroupIDByFriendlyName: (friendlyName) => getGroupIDByFriendlyName(friendlyName), diff --git a/test/bridgeConfig.test.js b/test/bridgeConfig.test.js index 6cf71e066..16924204d 100644 --- a/test/bridgeConfig.test.js +++ b/test/bridgeConfig.test.js @@ -41,10 +41,6 @@ describe('BridgeConfig', () => { fs.writeYaml.mockRestore(); }); - afterEach(() => { - jest.restoreAllMocks(); - }); - it('Setting elapsed false', async () => { write(configurationFile, {advanced: {elapsed: true}}); bridgeConfig.onMQTTMessage('zigbee2mqtt/bridge/config/elapsed', 'false'); @@ -56,4 +52,66 @@ describe('BridgeConfig', () => { expect(read(configurationFile)).toStrictEqual(expected); }); + + it('Add groups when there are none', async () => { + write(configurationFile, {}); + bridgeConfig.onMQTTMessage('zigbee2mqtt/bridge/config/add_group', 'test123'); + const expected = { + groups: { + '1': { + friendly_name: 'test123', + }, + }, + }; + + expect(read(configurationFile)).toStrictEqual(expected); + }); + + it('Add groups when there are', async () => { + write(configurationFile, { + groups: { + '1': { + friendly_name: 'test123', + }, + }, + }); + + bridgeConfig.onMQTTMessage('zigbee2mqtt/bridge/config/add_group', 'test1234'); + const expected = { + groups: { + '1': { + friendly_name: 'test123', + }, + '2': { + friendly_name: 'test1234', + }, + }, + }; + + expect(read(configurationFile)).toStrictEqual(expected); + }); + + it('Remove group', async () => { + write(configurationFile, { + groups: { + '1': { + friendly_name: 'test123', + }, + '2': { + friendly_name: 'test1234', + }, + }, + }); + + bridgeConfig.onMQTTMessage('zigbee2mqtt/bridge/config/remove_group', 'test123'); + const expected = { + groups: { + '2': { + friendly_name: 'test1234', + }, + }, + }; + + expect(read(configurationFile)).toStrictEqual(expected); + }); });