reworked ble connection handling
This commit is contained in:
parent
aa71c9ec4c
commit
43e3a8b8af
1 changed files with 62 additions and 27 deletions
|
|
@ -3,6 +3,7 @@ const crypto = require('crypto');
|
||||||
const xor = require('buffer-xor');
|
const xor = require('buffer-xor');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
|
const sleep = require('sleep');
|
||||||
|
|
||||||
let debug = '';
|
let debug = '';
|
||||||
|
|
||||||
|
|
@ -63,6 +64,24 @@ class Controller extends EventEmitter {
|
||||||
self.peripherals.push(peripheral);
|
self.peripherals.push(peripheral);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
noble.on('disconnect', async () => {
|
||||||
|
if (self.peripherals.length) {
|
||||||
|
logger('peripherals already scanned.');
|
||||||
|
this.connectedIndex = 0;
|
||||||
|
await self.connect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async reinit() {
|
||||||
|
console.log('reinitializing the Plejd add-on.');
|
||||||
|
this.once('scanComplete', async (peripherals) => {
|
||||||
|
console.log('found Plejd devices, reconnecting');
|
||||||
|
await this.connect();
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.scan();
|
||||||
}
|
}
|
||||||
|
|
||||||
async scan() {
|
async scan() {
|
||||||
|
|
@ -88,9 +107,9 @@ class Controller extends EventEmitter {
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.peripherals.length) {
|
// if (!this.peripherals.length) {
|
||||||
await this.scan();
|
// await this.scan();
|
||||||
}
|
// }
|
||||||
|
|
||||||
this.isConnecting = true;
|
this.isConnecting = true;
|
||||||
|
|
||||||
|
|
@ -114,7 +133,7 @@ class Controller extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.peripheral = self.peripherals[idx];
|
self.peripheral = self.peripherals[idx];
|
||||||
console.log('connected to Plejd device with addr ' + self.peripheral.address);
|
console.log('connected to Plejd device with addr ' + self.peripheral.address + ' with rssi ' + self.peripheral.rssi);
|
||||||
|
|
||||||
self.peripheral_address = self._reverseBuffer(Buffer.from(String(self.peripheral.address).replace(/\-/g, '').replace(/\:/g, ''), 'hex'));
|
self.peripheral_address = self._reverseBuffer(Buffer.from(String(self.peripheral.address).replace(/\-/g, '').replace(/\:/g, ''), 'hex'));
|
||||||
|
|
||||||
|
|
@ -149,7 +168,7 @@ class Controller extends EventEmitter {
|
||||||
&& this.authCharacteristic
|
&& this.authCharacteristic
|
||||||
&& this.pingCharacteristic) {
|
&& this.pingCharacteristic) {
|
||||||
|
|
||||||
this.on('authenticated', () => {
|
this.once('authenticated', () => {
|
||||||
logger('Plejd is connected and authenticated.');
|
logger('Plejd is connected and authenticated.');
|
||||||
this.connectedIndex = idx;
|
this.connectedIndex = idx;
|
||||||
|
|
||||||
|
|
@ -173,6 +192,11 @@ class Controller extends EventEmitter {
|
||||||
|
|
||||||
this.isConnected = true;
|
this.isConnected = true;
|
||||||
this.isConnecting = false;
|
this.isConnecting = false;
|
||||||
|
|
||||||
|
// make sure to write any queued up messages to the Plejd devices
|
||||||
|
if (this.writeQueue && this.writeQueue.length > 0) {
|
||||||
|
this.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
|
|
@ -230,7 +254,16 @@ class Controller extends EventEmitter {
|
||||||
|
|
||||||
if (this.peripheral) {
|
if (this.peripheral) {
|
||||||
try {
|
try {
|
||||||
|
// disconnect
|
||||||
await this.peripheral.disconnect();
|
await this.peripheral.disconnect();
|
||||||
|
|
||||||
|
// we need to reset the ble adapter too
|
||||||
|
noble._bindings._hci.reset();
|
||||||
|
|
||||||
|
// wait 200 ms for reset command to take effect :)
|
||||||
|
sleep.msleep(200);
|
||||||
|
|
||||||
|
// now we're ready to connect again
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log('error: unable to disconnect from Plejd: ' + error);
|
console.log('error: unable to disconnect from Plejd: ' + error);
|
||||||
|
|
@ -253,10 +286,10 @@ class Controller extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async turnOn(id, brightness) {
|
async turnOn(id, brightness) {
|
||||||
if (!this.isConnected) {
|
// if (this.peripheral.state !== 'connected') {
|
||||||
console.log('warning: not connected, will connect. might take a few seconds.');
|
// console.log('warning: not connected, will connect. might take a few seconds.');
|
||||||
await this.connect();
|
// await this.reinit();
|
||||||
}
|
// }
|
||||||
|
|
||||||
logger('turning on ' + id + ' at brightness ' + brightness);
|
logger('turning on ' + id + ' at brightness ' + brightness);
|
||||||
|
|
||||||
|
|
@ -273,10 +306,10 @@ class Controller extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async turnOff(id) {
|
async turnOff(id) {
|
||||||
if (!this.isConnected) {
|
// if (this.peripheral.state !== 'connected') {
|
||||||
console.log('warning: not connected, will connect. might take a few seconds.');
|
// console.log('warning: not connected, will connect. might take a few seconds.');
|
||||||
await this.connect();
|
// await this.reinit();
|
||||||
}
|
// }
|
||||||
|
|
||||||
logger('turning off ' + id);
|
logger('turning off ' + id);
|
||||||
|
|
||||||
|
|
@ -291,13 +324,13 @@ class Controller extends EventEmitter {
|
||||||
logger('starting ping');
|
logger('starting ping');
|
||||||
this.pingRef = setInterval(async () => {
|
this.pingRef = setInterval(async () => {
|
||||||
logger('ping');
|
logger('ping');
|
||||||
if (self.isConnected) {
|
if (self.peripheral.state == 'connected') {
|
||||||
await self.plejdPing(async (pingOk) => {
|
await self.plejdPing(async (pingOk) => {
|
||||||
|
|
||||||
if (!pingOk) {
|
if (!pingOk) {
|
||||||
logger('ping failed');
|
console.log('error: ping failed');
|
||||||
await self.disconnect();
|
await self.disconnect();
|
||||||
await self.connect();
|
// await self.reinit();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger('pong');
|
logger('pong');
|
||||||
|
|
@ -306,7 +339,7 @@ class Controller extends EventEmitter {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await self.disconnect();
|
await self.disconnect();
|
||||||
await self.connect();
|
// await self.reinit();
|
||||||
}
|
}
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
@ -316,7 +349,7 @@ class Controller extends EventEmitter {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// make sure we're connected, otherwise, return false and reconnect
|
// make sure we're connected, otherwise, return false and reconnect
|
||||||
if (this.peripheral.state !== 'connected') {
|
if (this.peripheral.state != 'connected') {
|
||||||
callback(false);
|
callback(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -344,8 +377,7 @@ class Controller extends EventEmitter {
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log('error: writing to plejd: ' + error);
|
console.log('error: writing to plejd: ' + error);
|
||||||
await self.disconnect();
|
callback(false);
|
||||||
await self.connect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -383,7 +415,7 @@ class Controller extends EventEmitter {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.isConnecting) {
|
if (this.peripheral.state !== 'connected') {
|
||||||
logger('adding message to queue.');
|
logger('adding message to queue.');
|
||||||
this.writeQueue.push(data);
|
this.writeQueue.push(data);
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
|
|
@ -395,11 +427,7 @@ class Controller extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dataCharacteristic.write(this._encryptDecrypt(this.cryptoKey, this.peripheral_address, data), false);
|
this.dataCharacteristic.write(this._encryptDecrypt(this.cryptoKey, this.peripheral_address, data), false);
|
||||||
|
this.flush();
|
||||||
let writeData;
|
|
||||||
while ((writeData = this.writeQueue.shift()) !== undefined) {
|
|
||||||
this.dataCharacteristic.write(this._encryptDecrypt(this.cryptoKey, this.peripheral_address, writeData), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.keepAlive) {
|
if (!this.keepAlive) {
|
||||||
clearTimeout(this.disconnectIntervalRef);
|
clearTimeout(this.disconnectIntervalRef);
|
||||||
|
|
@ -411,7 +439,14 @@ class Controller extends EventEmitter {
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log('error: writing to plejd: ' + error);
|
console.log('error: writing to plejd: ' + error);
|
||||||
await self.disconnect();
|
await self.disconnect();
|
||||||
await self.connect();
|
// await self.connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async flush() {
|
||||||
|
let writeData;
|
||||||
|
while ((writeData = this.writeQueue.shift()) !== undefined) {
|
||||||
|
this.dataCharacteristic.write(this._encryptDecrypt(this.cryptoKey, this.peripheral_address, writeData), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue