From 65f5f1a4ba550b5dfbcbb1d9dba20ecc3ae1c12d Mon Sep 17 00:00:00 2001 From: Marcus Westin Date: Wed, 4 Dec 2019 18:52:50 +0100 Subject: [PATCH] reworked connection handling a bit --- main.js | 2 +- package-lock.json | 62 ++++++++++------------------------------------- package.json | 2 +- plejd.js | 44 ++++++++++++++++++++------------- 4 files changed, 42 insertions(+), 68 deletions(-) diff --git a/main.js b/main.js index b1f2035..5214e4c 100644 --- a/main.js +++ b/main.js @@ -14,7 +14,7 @@ async function main() { plejdApi.getCryptoKey((cryptoKey) => { const devices = plejdApi.getDevices(); - client.once('connected', () => { + client.on('connected', () => { console.log('plejd-mqtt: connected to mqtt.'); client.discover(devices); }); diff --git a/package-lock.json b/package-lock.json index e5094f2..c4a2ea6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,6 @@ "version": "0.5.3-3", "resolved": "https://registry.npmjs.org/@abandonware/bluetooth-hci-socket/-/bluetooth-hci-socket-0.5.3-3.tgz", "integrity": "sha512-SkT5yVoaceiWOK1eWW/QCgAaPph/Y+EkOVBvETmhsD1hhKa83+EmVRMjubO68k54uoIzviqcNhxZI/LuIU2PHA==", - "optional": true, "requires": { "debug": "^4.1.0", "nan": "^2.14.0", @@ -40,14 +39,12 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "optional": true + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "are-we-there-yet": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -142,8 +139,7 @@ "chownr": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", - "optional": true + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" }, "code-point-at": { "version": "1.1.0", @@ -186,19 +182,13 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "optional": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" - }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -234,14 +224,12 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "optional": true + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "optional": true + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, "duplexify": { "version": "3.7.1", @@ -406,7 +394,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "optional": true, "requires": { "minipass": "^2.6.0" } @@ -420,7 +407,6 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "optional": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -480,8 +466,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "optional": true + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "help-me": { "version": "1.1.0", @@ -636,14 +621,12 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "optional": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minipass": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -653,7 +636,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "optional": true, "requires": { "minipass": "^2.9.0" } @@ -662,7 +644,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "optional": true, "requires": { "minimist": "0.0.8" } @@ -726,8 +707,7 @@ "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "optional": true + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" }, "napi-build-utils": { "version": "1.0.1", @@ -744,7 +724,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "optional": true, "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -785,7 +764,6 @@ "version": "0.13.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", - "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", @@ -809,7 +787,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "optional": true, "requires": { "abbrev": "1", "osenv": "^0.1.4" @@ -825,7 +802,6 @@ "version": "1.4.6", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.6.tgz", "integrity": "sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg==", - "optional": true, "requires": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1" @@ -835,7 +811,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "optional": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -852,8 +827,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "optional": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "once": { "version": "1.4.0", @@ -973,7 +947,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "optional": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -1017,7 +990,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "optional": true, "requires": { "glob": "^7.1.3" } @@ -1042,20 +1014,17 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "optional": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "optional": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "optional": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-concat": { "version": "1.0.0", @@ -1103,7 +1072,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -1122,7 +1090,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1137,7 +1104,6 @@ "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "optional": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", @@ -1298,7 +1264,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "optional": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -1326,8 +1291,7 @@ "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } } diff --git a/package.json b/package.json index 0f3e854..6a21681 100644 --- a/package.json +++ b/package.json @@ -9,4 +9,4 @@ "lodash": "^4.17.15", "mqtt": "^3.0.0" } -} \ No newline at end of file +} diff --git a/plejd.js b/plejd.js index 5cf8385..5420e1b 100644 --- a/plejd.js +++ b/plejd.js @@ -39,6 +39,11 @@ class Controller extends EventEmitter { this.keepAlive = keepAlive; this.writeQueue = []; this.peripherals = []; + + // Holds a reference to the connected peripheral from the peripheral list. + // In case the peripheral we're connecting to, disconnects us, we can then reinitiate the connection + // by increasing the connectedIndex and by that, connect to the next in line. + this.connectedIndex = 0; } async init() { @@ -91,8 +96,7 @@ class Controller extends EventEmitter { this.isConnecting = true; - let idx = 0; - return await this._internalConnect(idx); + return await this._internalConnect(this.connectedIndex); } async _internalConnect(idx) { @@ -107,19 +111,19 @@ class Controller extends EventEmitter { try { this.peripherals[idx].connect(async (err) => { if (err) { - logger('error: failed to connect to Plejd device: ' + err); + console.log('error: failed to connect to Plejd device: ' + err); return await self._internalConnect(idx + 1); } self.peripheral = self.peripherals[idx]; - logger('connected to Plejd device with addr ' + self.peripheral.address); + console.log('connected to Plejd device with addr ' + self.peripheral.address); self.peripheral_address = self._reverseBuffer(Buffer.from(String(self.peripheral.address).replace(/\-/g, '').replace(/\:/g, ''), 'hex')); logger('discovering services and characteristics'); await self.peripheral.discoverSomeServicesAndCharacteristics([PLEJD_SERVICE], [], async (err, services, characteristics) => { if (err) { - logger('error: failed to discover services: ' + err); + console.log('error: failed to discover services: ' + err); return; } @@ -149,6 +153,7 @@ class Controller extends EventEmitter { this.on('authenticated', () => { logger('Plejd is connected and authenticated.'); + this.connectedIndex = idx; if (self.keepAlive) { self.startPing(); @@ -164,7 +169,7 @@ class Controller extends EventEmitter { } catch (error) { this.isConnecting = false; - logger('error: failed to authenticate: ' + error); + console.log('error: failed to authenticate: ' + error); return Promise.resolve(false); } @@ -180,7 +185,7 @@ class Controller extends EventEmitter { catch (error) { this.isConnecting = false; - logger('error: failed to connect to Plejd device: ' + error); + console.log('error: failed to connect to Plejd device: ' + error); } return Promise.resolve(true); @@ -191,7 +196,8 @@ class Controller extends EventEmitter { self.lastDataCharacteristic.subscribe((err) => { if (err) { - logger('error: couldnt subscribe to notification characteristic.'); + console.log('error: couldnt subscribe to notification characteristic.'); + return; } // subscribe to last data event @@ -229,7 +235,7 @@ class Controller extends EventEmitter { await this.peripheral.disconnect(); } catch (error) { - logger('error: unable to disconnect from Plejd: ' + error); + console.log('error: unable to disconnect from Plejd: ' + error); return Promise.resolve(false); } @@ -250,7 +256,7 @@ class Controller extends EventEmitter { turnOn(id, brightness) { if (!this.isConnected) { - logger('error: not connected'); + console.log('error: not connected'); return; } @@ -270,7 +276,7 @@ class Controller extends EventEmitter { turnOff(id) { if (!this.isConnected) { - logger('error: not connected'); + console.log('error: not connected'); return; } @@ -312,13 +318,13 @@ class Controller extends EventEmitter { this.pingCharacteristic.write(ping, false, (err) => { if (err) { - logger('error: unable to send ping: ' + err); + console.log('error: unable to send ping: ' + err); callback(false); } this.pingCharacteristic.read((err, data) => { if (err) { - logger('error: unable to read ping: ' + err); + console.log('error: unable to read ping: ' + err); callback(false); } @@ -338,13 +344,13 @@ class Controller extends EventEmitter { logger('authenticating connection'); this.authCharacteristic.write(Buffer.from([0]), false, (err) => { if (err) { - logger('error: failed to authenticate: ' + err); + console.log('error: failed to authenticate: ' + err); return; } this.authCharacteristic.read(async (err2, data) => { if (err2) { - logger('error: challenge request failed: ' + err2); + console.log('error: challenge request failed: ' + err2); return; } @@ -352,7 +358,7 @@ class Controller extends EventEmitter { this.authCharacteristic.write(resp, false, (err3) => { if (err3) { - logger('error: challenge failed: ' + err2); + console.log('error: challenge failed: ' + err2); return; } @@ -367,11 +373,13 @@ class Controller extends EventEmitter { try { if (this.isConnecting) { + logger('adding message to queue.'); this.writeQueue.push(data); return Promise.resolve(true); } if (!this.keepAlive) { + logger('not connected to Plejd. reconnecting.'); await this.connect(); } @@ -390,7 +398,9 @@ class Controller extends EventEmitter { } } catch (error) { - logger('error when writing to plejd: ' + error); + console.log('error: writing to plejd: ' + error); + await self.disconnect(); + await self.connect(); } }