diff --git a/CHANGELOG.md b/CHANGELOG.md index e01d4c0a..2b8719b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [5.2.1](https://github.com/OpenWonderLabs/node-switchbot/compare/v5.2.0...v5.2.1) (2026-10-25) + + +### Bug Fixes + +* **ble:** only report disconnects the device starts as unexpected ([d36216d](https://github.com/OpenWonderLabs/node-switchbot/commit/d36216d0e0b03820753c9d40ed23d87631657904)), closes [#348](https://github.com/OpenWonderLabs/node-switchbot/issues/348) + + + # [5.2.0](https://github.com/OpenWonderLabs/node-switchbot/compare/v5.1.1...v5.2.0) (2026-10-24) diff --git a/package-lock.json b/package-lock.json index 44cbded2..18afc05a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "node-switchbot", - "version": "5.2.0", + "version": "5.2.1", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 836fe8d1..12d0584f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-switchbot", "type": "module", - "version": "5.2.0", + "version": "5.2.1", "description": "The node-switchbot is a Node.js module which allows you to control your Switchbot Devices through Bluetooth (BLE) with automatic OpenAPI fallback.", "author": "OpenWonderLabs (https://github.com/OpenWonderLabs)", "license": "MIT", diff --git a/src/devices/base.ts b/src/devices/base.ts index 66a68477..0eaa20bf 100644 --- a/src/devices/base.ts +++ b/src/devices/base.ts @@ -349,7 +349,11 @@ export abstract class SwitchBotDevice extends EventEmitter { try { return await tryBLE() } catch (err) { - this.logger?.warn?.('BLE getStatus failed, falling back to API', err) + if (this.enableFallback && this.hasAPI()) { + this.logger?.debug?.('BLE getStatus failed, falling back to API', err) + } else { + this.logger?.debug?.('BLE getStatus failed', err) + } } if (this.enableFallback && this.hasAPI()) { return await tryAPI() @@ -360,7 +364,11 @@ export abstract class SwitchBotDevice extends EventEmitter { try { return await tryAPI() } catch (err) { - this.logger?.warn?.('API getStatus failed, falling back to BLE', err) + if (this.enableFallback && this.hasBLE()) { + this.logger?.debug?.('API getStatus failed, falling back to BLE', err) + } else { + this.logger?.debug?.('API getStatus failed', err) + } } if (this.enableFallback && this.hasBLE()) { return await tryBLE() @@ -476,7 +484,7 @@ export abstract class SwitchBotDevice extends EventEmitter { this.circuitBreakerBLE.recordFailure() } - this.logger.error('BLE command failed', error) + this.logger.debug('BLE command failed', error) this.emitError({ type: 'ble', error }) return { @@ -555,7 +563,7 @@ export abstract class SwitchBotDevice extends EventEmitter { this.circuitBreakerAPI.recordFailure() } - this.logger.error('API command failed', error) + this.logger.debug('API command failed', error) this.emitError({ type: 'api', error }) return { @@ -718,7 +726,7 @@ export abstract class SwitchBotDevice extends EventEmitter { this.circuitBreakerBLE.recordFailure() } - this.logger.error('Failed to read BLE status', error) + this.logger.debug('Failed to read BLE status', error) throw error } } @@ -817,7 +825,7 @@ export abstract class SwitchBotDevice extends EventEmitter { this.circuitBreakerAPI.recordFailure() } - this.logger.error('Failed to read API status', error) + this.logger.debug('Failed to read API status', error) throw error } } diff --git a/src/utils/retry.ts b/src/utils/retry.ts index 9c1286d8..8a636325 100644 --- a/src/utils/retry.ts +++ b/src/utils/retry.ts @@ -137,14 +137,14 @@ export class RetryExecutor { if (attemptNumber < this.config.maxAttempts && (isDBusError || isBleakRetry || attemptNumber < this.config.maxAttempts)) { // DBus error: always backoff 0.25s (250ms) before normal backoff if (isDBusError) { - this.logger.warn( + this.logger.debug( `${description} DBus error detected on attempt ${attemptNumber}, applying 250ms backoff`, { error: errorMsg }, ) await new Promise(resolve => setTimeout(resolve, 250)) } const delayMs = this.calculateDelay(attemptNumber) - this.logger.warn( + this.logger.debug( `${description} failed on attempt ${attemptNumber}/${this.config.maxAttempts}, retrying in ${delayMs}ms`, { error: errorMsg, @@ -156,7 +156,7 @@ export class RetryExecutor { ) await new Promise(resolve => setTimeout(resolve, delayMs)) } else { - this.logger.error( + this.logger.debug( `${description} failed after ${attemptNumber} attempts`, { error: errorMsg,