Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)


Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
20 changes: 14 additions & 6 deletions src/devices/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/utils/retry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
Loading