From 5562c2d838d424b536a4f31ad7035bec9cc98207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20Hagelb=C3=A4ck?= Date: Mon, 25 Jan 2021 08:06:28 +0100 Subject: [PATCH] Improved error handling in event handling code - Earlier errors would restart the addon --- plejd/MqttClient.js | 16 +++++++- plejd/PlejdService.js | 13 ++++--- plejd/main.js | 88 ++++++++++++++++++++++++++----------------- 3 files changed, 75 insertions(+), 42 deletions(-) diff --git a/plejd/MqttClient.js b/plejd/MqttClient.js index 4b18874..4747d30 100644 --- a/plejd/MqttClient.js +++ b/plejd/MqttClient.js @@ -106,7 +106,15 @@ class MqttClient extends EventEmitter { } else if (topic.includes('set')) { logger.verbose(`Got mqtt command on ${topic} - ${message}`); const device = self.devices.find((x) => getCommandTopic(x) === topic); - self.emit('stateChanged', device, command); + if (device) { + self.emit('stateChanged', device, command); + } else { + logger.warn( + `Device for topic ${topic} not found! Can happen if HA calls previously existing devices.`, + ); + } + } else if (topic.includes('state')) { + logger.verbose(`State update sent over mqtt to HA ${topic} - ${message}`); } else { logger.verbose(`Warning: Got unrecognized mqtt command on ${topic} - ${message}`); } @@ -145,7 +153,11 @@ class MqttClient extends EventEmitter { return; } - logger.verbose(`Updating state for ${device.name}: ${data.state}`); + logger.verbose( + `Updating state for ${device.name}: ${data.state}${ + data.brightness ? `, dim: ${data.brightness}` : '' + }`, + ); let payload = null; if (device.type === 'switch') { diff --git a/plejd/PlejdService.js b/plejd/PlejdService.js index e6dee38..c941a1b 100644 --- a/plejd/PlejdService.js +++ b/plejd/PlejdService.js @@ -253,9 +253,9 @@ class PlejdService extends EventEmitter { turnOff(deviceId, command) { const deviceName = this._getDeviceName(deviceId); logger.info( - `Plejd got turn off command for ${deviceName} (${deviceId}), brightness ${ - command.brightness - }${command.transition ? `, transition: ${command.transition}` : ''}`, + `Plejd got turn off command for ${deviceName} (${deviceId})${ + command.transition ? `, transition: ${command.transition}` : '' + }`, ); this._transitionTo(deviceId, 0, command.transition, deviceName); } @@ -447,7 +447,7 @@ class PlejdService extends EventEmitter { } try { - logger.verbose(`Sending ${data.length} byte(s) of data to Plejd`, data); + logger.verbose(`Sending ${data.length} byte(s) of data to Plejd. ${data.toString('hex')}`); const encryptedData = this._encryptDecrypt(this.cryptoKey, this.plejdService.addr, data); await this.characteristics.data.WriteValue([...encryptedData], {}); return true; @@ -576,7 +576,10 @@ class PlejdService extends EventEmitter { const regex = /dev_([0-9A-F_]+)$/; const dirtyAddr = regex.exec(dev); const addr = this._reverseBuffer( - Buffer.from(String(dirtyAddr[1]).replace(/-/g, '').replace(/_/g, '').replace(/:/g, ''), 'hex'), + Buffer.from( + String(dirtyAddr[1]).replace(/-/g, '').replace(/_/g, '').replace(/:/g, ''), + 'hex', + ), ); // eslint-disable-next-line no-restricted-syntax diff --git a/plejd/main.js b/plejd/main.js index 20d268b..ae77952 100644 --- a/plejd/main.js +++ b/plejd/main.js @@ -36,8 +36,12 @@ async function main() { const devices = plejdApi.getDevices(); client.on('connected', () => { - logger.verbose('connected to mqtt.'); - client.discover(devices); + try { + logger.verbose('connected to mqtt.'); + client.discover(devices); + } catch (err) { + logger.error('Error in MqttClient.connected callback in main.js', err); + } }); client.init(); @@ -54,7 +58,9 @@ async function main() { plejd.on('connectFailed', () => { logger.verbose('Were unable to connect, will retry connection in 10 seconds.'); setTimeout(() => { - plejd.init(); + plejd + .init() + .catch((e) => logger.error('Error in init() from connectFailed in main.js', e)); }, 10000); }); @@ -66,50 +72,62 @@ async function main() { // subscribe to changes from Plejd plejd.on('stateChanged', (deviceId, command) => { - client.updateState(deviceId, command); + try { + client.updateState(deviceId, command); + } catch (err) { + logger.error('Error in PlejdService.stateChanged callback in main.js', err); + } }); plejd.on('sceneTriggered', (deviceId, scene) => { - client.sceneTriggered(scene); + try { + client.sceneTriggered(scene); + } catch (err) { + logger.error('Error in PlejdService.sceneTriggered callback in main.js', err); + } }); // subscribe to changes from HA client.on('stateChanged', (device, command) => { - const deviceId = device.id; + try { + const deviceId = device.id; - if (device.typeName === 'Scene') { - // we're triggering a scene, lets do that and jump out. - // since scenes aren't "real" devices. - plejd.triggerScene(device.id); - return; - } + if (device.typeName === 'Scene') { + // we're triggering a scene, lets do that and jump out. + // since scenes aren't "real" devices. + plejd.triggerScene(device.id); + return; + } - let state = 'OFF'; - let commandObj = {}; + let state = 'OFF'; + let commandObj = {}; - if (typeof command === 'string') { - // switch command - state = command; - commandObj = { - state, - }; + if (typeof command === 'string') { + // switch command + state = command; + commandObj = { + state, + }; - // since the switch doesn't get any updates on whether it's on or not, - // we fake this by directly send the updateState back to HA in order for - // it to change state. - client.updateState(deviceId, { - state: state === 'ON' ? 1 : 0, - }); - } else { - // eslint-disable-next-line prefer-destructuring - state = command.state; - commandObj = command; - } + // since the switch doesn't get any updates on whether it's on or not, + // we fake this by directly send the updateState back to HA in order for + // it to change state. + client.updateState(deviceId, { + state: state === 'ON' ? 1 : 0, + }); + } else { + // eslint-disable-next-line prefer-destructuring + state = command.state; + commandObj = command; + } - if (state === 'ON') { - plejd.turnOn(deviceId, commandObj); - } else { - plejd.turnOff(deviceId, commandObj); + if (state === 'ON') { + plejd.turnOn(deviceId, commandObj); + } else { + plejd.turnOff(deviceId, commandObj); + } + } catch (err) { + logger.error('Error in MqttClient.stateChanged callback in main.js', err); } }); });