From 126c393cee34de329ccf03d94bacaaf38d020e6c Mon Sep 17 00:00:00 2001 From: John Lindahl Date: Wed, 13 Jan 2021 01:47:05 +0100 Subject: [PATCH] multiple fixes for improved lifecycle and errors * Init and _internalInit is actually awaitable * this.bleDevices is reset on init * check for actual data in write to preven length of undefined * Throttled re-inits on write-errors. --- plejd/ble.bluez.js | 49 ++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/plejd/ble.bluez.js b/plejd/ble.bluez.js index 4303e61..a4ea356 100644 --- a/plejd/ble.bluez.js +++ b/plejd/ble.bluez.js @@ -60,7 +60,7 @@ class PlejdService extends EventEmitter { this.writeQueueWaitTime = writeQueueWaitTime; this.writeQueue = []; this.writeQueueRef = null; - + this.maxQueueLengthTarget = MAX_WRITEQUEUE_LENGTH_TARGET || this.devices.length || 5; logger('Max global transition queue length target', this.maxQueueLengthTarget) @@ -85,8 +85,9 @@ class PlejdService extends EventEmitter { this.objectManager.removeAllListeners(); } + this.bleDevices = []; this.connectedDevice = null; - + this.characteristics = { data: null, lastData: null, @@ -146,10 +147,7 @@ class PlejdService extends EventEmitter { console.log('plejd-ble: error: failed to start discovery. Make sure no other add-on is currently scanning.'); return; } - - setTimeout(async () => { - await this._internalInit(); - }, this.connectionTimeout * 1000); + return new Promise(resolve => setTimeout(() => resolve(this._internalInit()), this.connectionTimeout * 1000)); } async _internalInit() { @@ -277,7 +275,7 @@ class PlejdService extends EventEmitter { logger('transitioning from', initialBrightness, 'to', targetBrightness, 'in', transition, 'seconds.'); logger('delta brightness', deltaBrightness, ', steps ', transitionSteps, ', interval', transitionInterval, 'ms'); - + const dtStart = new Date(); let nSteps = 0; @@ -286,7 +284,7 @@ class PlejdService extends EventEmitter { this.bleDeviceTransitionTimers[id] = setInterval(() => { let tElapsedMs = (new Date().getTime() - dtStart.getTime()); let tElapsed = tElapsedMs / 1000; - + if (tElapsed > transition || tElapsed < 0) { tElapsed = transition; } @@ -310,7 +308,7 @@ class PlejdService extends EventEmitter { } }, transitionInterval); - } + } else { if (transition && isDimmable) { logger('Could not transition light change. Either initial value is unknown or change is too small. Requested from', initialBrightness, 'to', targetBrightness) @@ -324,7 +322,7 @@ class PlejdService extends EventEmitter { logger('no brightness specified, setting ', id, ' to previous known.'); var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009701', 'hex'); this.writeQueue.unshift(payload); - } + } else { if (brightness <= 0) { this._turnOff(id); @@ -333,7 +331,7 @@ class PlejdService extends EventEmitter { if (brightness > 255) { brightness = 255; } - + logger('Setting ', id, 'brightness to ' + brightness); brightness = brightness << 8 | brightness; var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009801' + (brightness).toString(16).padStart(4, '0'), 'hex'); @@ -379,8 +377,20 @@ class PlejdService extends EventEmitter { this.characteristics.lastData.StartNotify(); } + async throttledInit(delay) { + if(this.delayedInit){ + return this.delayedInit; + } + this.delayedInit = new Promise((resolve) => setTimeout(async () => { + const result = await this.init(); + this.delayedInit = null; + resolve(result) + }, delay)) + return this.delayedInit; + } + async write(data, retry = true) { - if (!this.plejdService || !this.characteristics.data) { + if (!data || !this.plejdService || !this.characteristics.data) { return; } @@ -393,16 +403,13 @@ class PlejdService extends EventEmitter { setTimeout(() => this.write(data, retry), 1000); return; } - console.log('plejd-ble: write failed ' + err); - setTimeout(async () => { - await this.init(); + await this.throttledInit(this.connectionTimeout * 1000); - if (retry) { - logger('reconnected and retrying to write'); - await this.write(data, false); - } - }, this.connectionTimeout * 1000); + if(retry){ + logger('reconnected and retrying to write'); + await this.write(data, false); + } } } @@ -683,4 +690,4 @@ class PlejdService extends EventEmitter { } } -module.exports = PlejdService; \ No newline at end of file +module.exports = PlejdService;