Merge pull request #137 from JohnPhoto/lifecycle-fixes

multiple fixes for improved lifecycle and errors
This commit is contained in:
Marcus Westin 2021-01-13 21:39:36 +01:00 committed by GitHub
commit fe8d2b84f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -60,7 +60,8 @@ class PlejdService extends EventEmitter {
this.writeQueueWaitTime = writeQueueWaitTime; this.writeQueueWaitTime = writeQueueWaitTime;
this.writeQueue = []; this.writeQueue = [];
this.writeQueueRef = null; this.writeQueueRef = null;
this.delayedInit = null;
this.maxQueueLengthTarget = MAX_WRITEQUEUE_LENGTH_TARGET || this.devices.length || 5; this.maxQueueLengthTarget = MAX_WRITEQUEUE_LENGTH_TARGET || this.devices.length || 5;
logger('Max global transition queue length target', this.maxQueueLengthTarget) logger('Max global transition queue length target', this.maxQueueLengthTarget)
@ -85,8 +86,9 @@ class PlejdService extends EventEmitter {
this.objectManager.removeAllListeners(); this.objectManager.removeAllListeners();
} }
this.bleDevices = [];
this.connectedDevice = null; this.connectedDevice = null;
this.characteristics = { this.characteristics = {
data: null, data: null,
lastData: null, lastData: null,
@ -96,7 +98,7 @@ class PlejdService extends EventEmitter {
}; };
clearInterval(this.pingRef); clearInterval(this.pingRef);
clearInterval(this.writeQueueRef); clearTimeout(this.writeQueueRef);
console.log('init()'); console.log('init()');
const bluez = await this.bus.getProxyObject(BLUEZ_SERVICE_NAME, '/'); const bluez = await this.bus.getProxyObject(BLUEZ_SERVICE_NAME, '/');
@ -146,10 +148,7 @@ class PlejdService extends EventEmitter {
console.log('plejd-ble: error: failed to start discovery. Make sure no other add-on is currently scanning.'); console.log('plejd-ble: error: failed to start discovery. Make sure no other add-on is currently scanning.');
return; return;
} }
return new Promise(resolve => setTimeout(() => resolve(this._internalInit()), this.connectionTimeout * 1000));
setTimeout(async () => {
await this._internalInit();
}, this.connectionTimeout * 1000);
} }
async _internalInit() { async _internalInit() {
@ -277,7 +276,7 @@ class PlejdService extends EventEmitter {
logger('transitioning from', initialBrightness, 'to', targetBrightness, 'in', transition, 'seconds.'); logger('transitioning from', initialBrightness, 'to', targetBrightness, 'in', transition, 'seconds.');
logger('delta brightness', deltaBrightness, ', steps ', transitionSteps, ', interval', transitionInterval, 'ms'); logger('delta brightness', deltaBrightness, ', steps ', transitionSteps, ', interval', transitionInterval, 'ms');
const dtStart = new Date(); const dtStart = new Date();
let nSteps = 0; let nSteps = 0;
@ -286,7 +285,7 @@ class PlejdService extends EventEmitter {
this.bleDeviceTransitionTimers[id] = setInterval(() => { this.bleDeviceTransitionTimers[id] = setInterval(() => {
let tElapsedMs = (new Date().getTime() - dtStart.getTime()); let tElapsedMs = (new Date().getTime() - dtStart.getTime());
let tElapsed = tElapsedMs / 1000; let tElapsed = tElapsedMs / 1000;
if (tElapsed > transition || tElapsed < 0) { if (tElapsed > transition || tElapsed < 0) {
tElapsed = transition; tElapsed = transition;
} }
@ -310,7 +309,7 @@ class PlejdService extends EventEmitter {
} }
}, transitionInterval); }, transitionInterval);
} }
else { else {
if (transition && isDimmable) { if (transition && isDimmable) {
logger('Could not transition light change. Either initial value is unknown or change is too small. Requested from', initialBrightness, 'to', targetBrightness) logger('Could not transition light change. Either initial value is unknown or change is too small. Requested from', initialBrightness, 'to', targetBrightness)
@ -324,7 +323,7 @@ class PlejdService extends EventEmitter {
logger('no brightness specified, setting ', id, ' to previous known.'); logger('no brightness specified, setting ', id, ' to previous known.');
var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009701', 'hex'); var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009701', 'hex');
this.writeQueue.unshift(payload); this.writeQueue.unshift(payload);
} }
else { else {
if (brightness <= 0) { if (brightness <= 0) {
this._turnOff(id); this._turnOff(id);
@ -333,7 +332,7 @@ class PlejdService extends EventEmitter {
if (brightness > 255) { if (brightness > 255) {
brightness = 255; brightness = 255;
} }
logger('Setting ', id, 'brightness to ' + brightness); logger('Setting ', id, 'brightness to ' + brightness);
brightness = brightness << 8 | brightness; brightness = brightness << 8 | brightness;
var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009801' + (brightness).toString(16).padStart(4, '0'), 'hex'); var payload = Buffer.from((id).toString(16).padStart(2, '0') + '0110009801' + (brightness).toString(16).padStart(4, '0'), 'hex');
@ -370,8 +369,8 @@ class PlejdService extends EventEmitter {
} }
// auth done, start ping // auth done, start ping
await this.startPing(); this.startPing();
await this.startWriteQueue(); this.startWriteQueue();
// After we've authenticated, we need to hook up the event listener // After we've authenticated, we need to hook up the event listener
// for changes to lastData. // for changes to lastData.
@ -379,8 +378,20 @@ class PlejdService extends EventEmitter {
this.characteristics.lastData.StartNotify(); 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) { async write(data, retry = true) {
if (!this.plejdService || !this.characteristics.data) { if (!data || !this.plejdService || !this.characteristics.data) {
return; return;
} }
@ -393,20 +404,17 @@ class PlejdService extends EventEmitter {
setTimeout(() => this.write(data, retry), 1000); setTimeout(() => this.write(data, retry), 1000);
return; return;
} }
console.log('plejd-ble: write failed ' + err); console.log('plejd-ble: write failed ' + err);
setTimeout(async () => { await this.throttledInit(this.connectionTimeout * 1000);
await this.init();
if (retry) { if(retry){
logger('reconnected and retrying to write'); logger('reconnected and retrying to write');
await this.write(data, false); await this.write(data, false);
} }
}, this.connectionTimeout * 1000);
} }
} }
async startPing() { startPing() {
console.log('startPing()'); console.log('startPing()');
clearInterval(this.pingRef); clearInterval(this.pingRef);
@ -452,9 +460,9 @@ class PlejdService extends EventEmitter {
this.emit('pingSuccess', pong[0]); this.emit('pingSuccess', pong[0]);
} }
async startWriteQueue() { startWriteQueue() {
console.log('startWriteQueue()'); console.log('startWriteQueue()');
clearInterval(this.writeQueueRef); clearTimeout(this.writeQueueRef);
this.writeQueueRef = setTimeout(() => this.runWriteQueue(), this.writeQueueWaitTime); this.writeQueueRef = setTimeout(() => this.runWriteQueue(), this.writeQueueWaitTime);
} }
@ -683,4 +691,4 @@ class PlejdService extends EventEmitter {
} }
} }
module.exports = PlejdService; module.exports = PlejdService;