From 2bc423862a8c65470174818621563b79094ba5a6 Mon Sep 17 00:00:00 2001 From: Alexander Herlin Date: Tue, 24 Sep 2024 18:44:17 +0200 Subject: [PATCH] Refactor reconnection logic, add more logging around RSSI status. --- CHANGELOG.md | 4 ++ package.json | 2 +- src/plejdService.ts | 107 ++++++++++++++++++++++++++++++-------------- 3 files changed, 78 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65b6f91..c6a8386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +#### 1.5.1(2024-09-24) + +Refactor reconnection logic, add more logging around RSSI status. + #### 1.5.0(2024-08-16) Discard global state, add more logging to see what is going on. diff --git a/package.json b/package.json index a50b384..ff17f65 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Plejd", "name": "homebridge-plejd", "author": "Herlix", - "version": "1.5.0", + "version": "1.5.1", "description": "HomeKit support for the Plejd BLE platform using Homebridge", "license": "Apache-2.0", "type": "module", diff --git a/src/plejdService.ts b/src/plejdService.ts index faee009..d10f1d9 100644 --- a/src/plejdService.ts +++ b/src/plejdService.ts @@ -96,49 +96,88 @@ export class PlejdService { private onDiscover = async (peripheral: noble.Peripheral) => { this.log.info( - `Discovered | ${peripheral.advertisement.localName} | addr: ${peripheral.address} | RSSI: ${peripheral.rssi} dB`, + `Discovered | ${peripheral.advertisement.localName} | addr: ${peripheral.address} | Signal strength: ${this.mapRssiToQuality(peripheral.rssi)} (${peripheral.rssi} dB)`, ); this.log.debug(`Stopping scan`); await noble.stopScanningAsync(); - try { - this.log.debug(`Connecting to the new peripheral`); - await peripheral.connectAsync(); - this.log.info( - `Connected to mesh | ${peripheral.advertisement.localName} (addr: ${peripheral.address})`, - ); - } catch (error) { - this.log.error( - `Connecting failed | ${peripheral.advertisement.localName} | addr: ${peripheral.address}) - err: ${error}`, - ); - await this.tryDisconnect(peripheral); - noble.reset(); - await this.tryStartScanning(); - return; - } + let retryCount = 0; + const maxRetries = 3; - this.log.debug("Setting up disconnect handle"); - peripheral.once("disconnect", async () => { - this.log.info("Disconnected from mesh"); - await this.tryStartScanning(); - }); + const connectWithRetry = async () => { + try { + this.log.debug(`Connecting to the new peripheral`); + await peripheral.connectAsync(); + this.log.info( + `Connected to mesh | ${peripheral.advertisement.localName} (addr: ${peripheral.address})`, + ); - let characteristics: noble.Characteristic[]; - try { - characteristics = await this.discoverCaracteristics(peripheral); - } catch (e) { - this.log.error( - "Failed to discover characteristics, disconnecting. Error:", - e, - ); - await this.tryDisconnect(peripheral); - this.tryStartScanning(); - return; - } + peripheral.once("disconnect", async () => { + this.log.info("Disconnected from mesh"); + if (retryCount < maxRetries) { + retryCount++; + this.log.debug(`Attempting to reconnect (attempt ${retryCount})`); + await connectWithRetry(); + } else { + this.log.error("Max reconnection attempts reached. Starting scan."); + await this.tryStartScanning(); + } + }); + + // Reset retry count on successful connection + retryCount = 0; + + let characteristics: noble.Characteristic[]; + try { + characteristics = await this.discoverCaracteristics(peripheral); + } catch (e) { + this.log.error( + "Failed to discover characteristics, disconnecting. Error:", + e, + ); + await this.tryDisconnect(peripheral); + throw e; + } + + await this.setupDevice(peripheral, characteristics); + } catch (error) { + this.log.error( + `Connecting failed | ${peripheral.advertisement.localName} | addr: ${peripheral.address}) - err: ${error}`, + ); + await this.tryDisconnect(peripheral); + if (retryCount < maxRetries) { + retryCount++; + this.log.debug(`Attempting to reconnect (attempt ${retryCount})`); + await connectWithRetry(); + } else { + this.log.error( + "Max reconnection attempts reached. Resetting noble and starting scan.", + ); + noble.reset(); + await this.tryStartScanning(); + } + } + }; - await this.setupDevice(peripheral, characteristics); + await connectWithRetry(); }; + private mapRssiToQuality(rssi: number): string { + if (rssi >= -30) { + return "Excellent (Very close proximity)"; + } else if (rssi >= -67) { + return "Very Good"; + } else if (rssi >= -70) { + return "Good"; + } else if (rssi >= -80) { + return "Fair"; + } else if (rssi >= -90) { + return "Weak"; + } else { + return "Very Weak (Potential connection issues)"; + } + } + private discoverCaracteristics = async ( peripheral: noble.Peripheral, ): Promise => {