From ef7a5086a1c7dcb3f42d0158ad12b5328010760e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20Hagelb=C3=A4ck?= Date: Wed, 10 Feb 2021 10:10:28 +0100 Subject: [PATCH] Handle when scene and device have the same Id - Catch emitted errors in Mqtt --- plejd/DeviceRegistry.js | 4 ++++ plejd/MqttClient.js | 29 +++++++++++++++++++++-------- plejd/PlejdBLEHandler.js | 2 +- plejd/SceneManager.js | 2 +- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/plejd/DeviceRegistry.js b/plejd/DeviceRegistry.js index 9cf6ae9..647e5bc 100644 --- a/plejd/DeviceRegistry.js +++ b/plejd/DeviceRegistry.js @@ -65,6 +65,10 @@ class DeviceRegistry { return (this.plejdDevices[deviceId] || {}).name; } + getScene(sceneId) { + return this.sceneDevices[sceneId]; + } + getSceneName(sceneId) { return (this.sceneDevices[sceneId] || {}).name; } diff --git a/plejd/MqttClient.js b/plejd/MqttClient.js index 282bf65..78e3327 100644 --- a/plejd/MqttClient.js +++ b/plejd/MqttClient.js @@ -85,6 +85,10 @@ class MqttClient extends EventEmitter { password: this.config.mqttPassword, }); + this.client.on('error', (err) => { + logger.warn('Error emitted from mqtt client', err); + }); + this.client.on('connect', () => { logger.info('Connected to MQTT.'); @@ -115,17 +119,26 @@ class MqttClient extends EventEmitter { } else { const decodedTopic = decodeTopic(topic); if (decodedTopic) { - const device = this.deviceRegistry.getDevice(decodedTopic.id); - const deviceName = device ? device.name : ''; + let device = this.deviceRegistry.getDevice(decodedTopic.id); - const command = message.toString().substring(0, 1) === '{' - ? JSON.parse(message.toString()) - : message.toString(); + const messageString = message.toString(); + const isJsonMessage = messageString.startsWith('{'); + const command = isJsonMessage + ? JSON.parse(messageString) + : messageString; + + if (!isJsonMessage && messageString === 'ON' && this.deviceRegistry.getScene(decodedTopic.id)) { + // Guess that id that got state command without dim value belongs to Scene, not Device + // This guess could very well be wrong depending on the installation... + logger.warn(`Device id ${decodedTopic.id} belongs to both scene and device, guessing Scene is what should be set to ON. OFF commands still sent to device.`); + device = this.deviceRegistry.getScene(decodedTopic.id); + } + const deviceName = device ? device.name : ''; switch (decodedTopic.command) { case 'set': logger.verbose( - `Got mqtt SET command for ${decodedTopic.type}, ${deviceName} (${decodedTopic.id}): ${message}`, + `Got mqtt SET command for ${decodedTopic.type}, ${deviceName} (${decodedTopic.id}): ${messageString}`, ); if (device) { @@ -143,7 +156,7 @@ class MqttClient extends EventEmitter { `Sent mqtt ${decodedTopic.command} command for ${ decodedTopic.type }, ${deviceName} (${decodedTopic.id}). ${ - decodedTopic.command === 'availability' ? message : '' + decodedTopic.command === 'availability' ? messageString : '' }`, ); break; @@ -151,7 +164,7 @@ class MqttClient extends EventEmitter { logger.verbose(`Warning: Unknown command ${decodedTopic.command} in decoded topic`); } } else { - logger.verbose(`Warning: Got unrecognized mqtt command on '${topic}': ${message}`); + logger.verbose(`Warning: Got unrecognized mqtt command on '${topic}': ${message.toString()}`); } } }); diff --git a/plejd/PlejdBLEHandler.js b/plejd/PlejdBLEHandler.js index 62bf919..54cdd3a 100644 --- a/plejd/PlejdBLEHandler.js +++ b/plejd/PlejdBLEHandler.js @@ -49,7 +49,7 @@ class PlejBLEHandler extends EventEmitter { plejdService = null; plejdDevices = {}; pingRef = null; - writeQueue = {}; + writeQueue = []; writeQueueRef = null; reconnectInProgress = false; diff --git a/plejd/SceneManager.js b/plejd/SceneManager.js index 42279cb..a30e58b 100644 --- a/plejd/SceneManager.js +++ b/plejd/SceneManager.js @@ -24,7 +24,7 @@ class SceneManager extends EventEmitter { this.scenes = {}; scenes.forEach((scene) => { const idx = this.deviceRegistry.apiSite.sceneIndex[scene.sceneId]; - this.scenes[scene.id] = new Scene(idx, scene, this.deviceRegistry.apiSite.sceneSteps); + this.scenes[idx] = new Scene(idx, scene, this.deviceRegistry.apiSite.sceneSteps); }); }