node-switchbot 4.0.0-beta.7 → 4.0.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +3 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +9 -6
- package/dist/api.js.map +1 -1
- package/dist/ble.d.ts +32 -1
- package/dist/ble.d.ts.map +1 -1
- package/dist/ble.js +262 -15
- package/dist/ble.js.map +1 -1
- package/dist/devices/base.d.ts +3 -0
- package/dist/devices/base.d.ts.map +1 -1
- package/dist/devices/base.js +45 -10
- package/dist/devices/base.js.map +1 -1
- package/dist/devices/wo-curtain.d.ts +3 -3
- package/dist/devices/wo-curtain.d.ts.map +1 -1
- package/dist/devices/wo-curtain.js +12 -9
- package/dist/devices/wo-curtain.js.map +1 -1
- package/dist/devices/wo-hand.js +1 -1
- package/dist/devices/wo-hand.js.map +1 -1
- package/dist/devices/wo-lock-pro.js +1 -1
- package/dist/devices/wo-lock-pro.js.map +1 -1
- package/dist/devices/wo-lock.js +1 -1
- package/dist/devices/wo-lock.js.map +1 -1
- package/dist/devices/wo-relay-switch-1.js +1 -1
- package/dist/devices/wo-relay-switch-1.js.map +1 -1
- package/dist/switchbot.d.ts.map +1 -1
- package/dist/switchbot.js +4 -2
- package/dist/switchbot.js.map +1 -1
- package/dist/types/ble.d.ts +18 -0
- package/dist/types/ble.d.ts.map +1 -1
- package/dist/types/ble.js.map +1 -1
- package/dist/types/device.d.ts +3 -3
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/APIError.html +2 -2
- package/docs/classes/APINotAvailableError.html +2 -2
- package/docs/classes/BLEConnection.html +14 -10
- package/docs/classes/BLENotAvailableError.html +2 -2
- package/docs/classes/BLEScanner.html +11 -9
- package/docs/classes/CommandFailedError.html +2 -2
- package/docs/classes/ConnectionTimeoutError.html +2 -2
- package/docs/classes/DeviceManager.html +13 -13
- package/docs/classes/DeviceNotFoundError.html +2 -2
- package/docs/classes/DiscoveryError.html +2 -2
- package/docs/classes/OpenAPIClient.html +24 -24
- package/docs/classes/SwitchBot.html +11 -11
- package/docs/classes/SwitchBotDevice.html +28 -28
- package/docs/classes/SwitchBotError.html +2 -2
- package/docs/classes/ValidationError.html +2 -2
- package/docs/classes/WoAirPurifier.html +32 -32
- package/docs/classes/WoAirPurifierTable.html +32 -32
- package/docs/classes/WoBlindTilt.html +34 -34
- package/docs/classes/WoBulb.html +33 -33
- package/docs/classes/WoCeilingLight.html +33 -33
- package/docs/classes/WoContact.html +28 -28
- package/docs/classes/WoCurtain.html +32 -32
- package/docs/classes/WoHand.html +34 -34
- package/docs/classes/WoHub2.html +28 -28
- package/docs/classes/WoHub3.html +28 -28
- package/docs/classes/WoHumi.html +32 -32
- package/docs/classes/WoHumi2.html +32 -32
- package/docs/classes/WoIOSensorTH.html +28 -28
- package/docs/classes/WoKeypad.html +28 -28
- package/docs/classes/WoLeak.html +28 -28
- package/docs/classes/WoPlugMiniJP.html +31 -31
- package/docs/classes/WoPlugMiniUS.html +31 -31
- package/docs/classes/WoPresence.html +28 -28
- package/docs/classes/WoRelaySwitch1.html +31 -31
- package/docs/classes/WoRelaySwitch1PM.html +31 -31
- package/docs/classes/WoRemote.html +28 -28
- package/docs/classes/WoSensorTH.html +28 -28
- package/docs/classes/WoSensorTHPlus.html +28 -28
- package/docs/classes/WoSensorTHPro.html +28 -28
- package/docs/classes/WoSensorTHProCO2.html +28 -28
- package/docs/classes/WoSmartLock.html +30 -30
- package/docs/classes/WoSmartLockPro.html +31 -31
- package/docs/classes/WoStrip.html +33 -33
- package/docs/enums/LogLevel.html +2 -2
- package/docs/enums/SwitchBotBLEModel.html +2 -2
- package/docs/enums/SwitchBotBLEModelName.html +2 -2
- package/docs/functions/updateBaseURL.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/APICommandRequest.html +2 -2
- package/docs/interfaces/APICommandResponse.html +2 -2
- package/docs/interfaces/APIDevice.html +2 -2
- package/docs/interfaces/APIDeviceStatus.html +2 -2
- package/docs/interfaces/APIErrorResponse.html +2 -2
- package/docs/interfaces/APIResponse.html +2 -2
- package/docs/interfaces/AirPurifierCommands.html +2 -2
- package/docs/interfaces/AirPurifierServiceData.html +20 -5
- package/docs/interfaces/AirPurifierStatus.html +7 -7
- package/docs/interfaces/BLEAdvertisement.html +2 -2
- package/docs/interfaces/BLEScanOptions.html +5 -5
- package/docs/interfaces/BLEServiceData.html +22 -5
- package/docs/interfaces/BlindTiltCommands.html +2 -2
- package/docs/interfaces/BlindTiltServiceData.html +21 -5
- package/docs/interfaces/BlindTiltStatus.html +6 -6
- package/docs/interfaces/BotCommands.html +2 -2
- package/docs/interfaces/BotServiceData.html +20 -5
- package/docs/interfaces/BotStatus.html +6 -6
- package/docs/interfaces/BulbCommands.html +2 -2
- package/docs/interfaces/BulbServiceData.html +21 -5
- package/docs/interfaces/BulbStatus.html +6 -6
- package/docs/interfaces/CeilingLightCommands.html +2 -2
- package/docs/interfaces/CeilingLightServiceData.html +21 -5
- package/docs/interfaces/CeilingLightStatus.html +6 -6
- package/docs/interfaces/CommandResult.html +6 -6
- package/docs/interfaces/ContactServiceData.html +22 -5
- package/docs/interfaces/ContactStatus.html +6 -6
- package/docs/interfaces/CurtainCommands.html +2 -2
- package/docs/interfaces/CurtainServiceData.html +22 -5
- package/docs/interfaces/CurtainStatus.html +6 -6
- package/docs/interfaces/DeviceInfo.html +22 -14
- package/docs/interfaces/DeviceListResponse.html +2 -2
- package/docs/interfaces/DeviceStatus.html +6 -6
- package/docs/interfaces/DiscoveryOptions.html +7 -7
- package/docs/interfaces/HubServiceData.html +22 -5
- package/docs/interfaces/HubStatus.html +6 -6
- package/docs/interfaces/HumidifierCommands.html +2 -2
- package/docs/interfaces/HumidifierServiceData.html +23 -6
- package/docs/interfaces/HumidifierStatus.html +6 -6
- package/docs/interfaces/KeypadStatus.html +6 -6
- package/docs/interfaces/LeakServiceData.html +22 -5
- package/docs/interfaces/LeakStatus.html +6 -6
- package/docs/interfaces/LockCommands.html +2 -2
- package/docs/interfaces/LockServiceData.html +20 -6
- package/docs/interfaces/LockStatus.html +6 -6
- package/docs/interfaces/MeterServiceData.html +22 -5
- package/docs/interfaces/MeterStatus.html +6 -6
- package/docs/interfaces/MotionServiceData.html +22 -5
- package/docs/interfaces/MotionStatus.html +6 -6
- package/docs/interfaces/PlugCommands.html +2 -2
- package/docs/interfaces/PlugServiceData.html +21 -5
- package/docs/interfaces/PlugStatus.html +6 -6
- package/docs/interfaces/PresenceServiceData.html +22 -5
- package/docs/interfaces/PresenceStatus.html +6 -6
- package/docs/interfaces/RelaySwitchCommands.html +2 -2
- package/docs/interfaces/RelaySwitchServiceData.html +21 -5
- package/docs/interfaces/RelaySwitchStatus.html +6 -6
- package/docs/interfaces/RemoteStatus.html +6 -6
- package/docs/interfaces/SceneListResponse.html +2 -2
- package/docs/interfaces/StripCommands.html +2 -2
- package/docs/interfaces/StripServiceData.html +21 -5
- package/docs/interfaces/StripStatus.html +6 -6
- package/docs/interfaces/SwitchBotConfig.html +15 -15
- package/docs/interfaces/WebhookConfig.html +2 -2
- package/docs/interfaces/WebhookDetails.html +2 -2
- package/docs/interfaces/WebhookQueryResponse.html +2 -2
- package/docs/interfaces/WebhookSetupResponse.html +2 -2
- package/docs/types/ConnectionType.html +1 -1
- package/docs/types/PhysicalDeviceType.html +1 -1
- package/docs/types/VirtualDeviceType.html +1 -1
- package/docs/variables/urls.html +1 -1
- package/package.json +1 -1
- package/todo/PYSWITCHBOT_COMPARISON.md +484 -0
- package/todo/README.md +68 -0
- package/todo/completed.md +65 -0
- package/todo/todo.md +369 -0
- package/PRODUCTION_READY.md +0 -135
package/dist/api.d.ts
CHANGED
|
@@ -73,10 +73,10 @@ export declare class OpenAPIClient {
|
|
|
73
73
|
/**
|
|
74
74
|
* Curtain-specific commands
|
|
75
75
|
*/
|
|
76
|
-
curtainOpen(deviceId: string): Promise<APICommandResponse>;
|
|
77
|
-
curtainClose(deviceId: string): Promise<APICommandResponse>;
|
|
76
|
+
curtainOpen(deviceId: string, speed?: number): Promise<APICommandResponse>;
|
|
77
|
+
curtainClose(deviceId: string, speed?: number): Promise<APICommandResponse>;
|
|
78
78
|
curtainPause(deviceId: string): Promise<APICommandResponse>;
|
|
79
|
-
curtainSetPosition(deviceId: string, position: number): Promise<APICommandResponse>;
|
|
79
|
+
curtainSetPosition(deviceId: string, position: number, speed?: number): Promise<APICommandResponse>;
|
|
80
80
|
/**
|
|
81
81
|
* Lock-specific commands
|
|
82
82
|
*/
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAqB,kBAAkB,EAAE,SAAS,EAAE,eAAe,EAAe,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAOtN;;GAEG;AACH,qBAAa,aAAa;IAItB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO;IALjB,OAAO,CAAC,MAAM,CAAQ;gBAGZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAAkB,EACnC,QAAQ,CAAC,EAAE,MAAM;IASnB;;OAEG;YACW,eAAe;IAc7B;;OAEG;YACW,WAAW;IAgCzB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAK/C;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAK3D;;OAEG;IACG,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,GAAG,GACd,OAAO,CAAC,kBAAkB,CAAC;IAe9B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAK7C;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAUxE;;OAEG;IACG,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAWlE;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD;;OAEG;IACG,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAKjE;;OAEG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAKhE;;OAEG;IACG,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/D;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIvD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIxD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAI/D;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
CHANGED
|
@@ -176,17 +176,20 @@ export class OpenAPIClient {
|
|
|
176
176
|
/**
|
|
177
177
|
* Curtain-specific commands
|
|
178
178
|
*/
|
|
179
|
-
async curtainOpen(deviceId) {
|
|
180
|
-
|
|
179
|
+
async curtainOpen(deviceId, speed = 255) {
|
|
180
|
+
const clampedSpeed = Math.min(255, Math.max(1, speed));
|
|
181
|
+
return this.sendCommand(deviceId, 'setPosition', `0,${clampedSpeed.toString(16).padStart(2, '0')},0`);
|
|
181
182
|
}
|
|
182
|
-
async curtainClose(deviceId) {
|
|
183
|
-
|
|
183
|
+
async curtainClose(deviceId, speed = 255) {
|
|
184
|
+
const clampedSpeed = Math.min(255, Math.max(1, speed));
|
|
185
|
+
return this.sendCommand(deviceId, 'setPosition', `0,${clampedSpeed.toString(16).padStart(2, '0')},100`);
|
|
184
186
|
}
|
|
185
187
|
async curtainPause(deviceId) {
|
|
186
188
|
return this.sendCommand(deviceId, 'pause');
|
|
187
189
|
}
|
|
188
|
-
async curtainSetPosition(deviceId, position) {
|
|
189
|
-
|
|
190
|
+
async curtainSetPosition(deviceId, position, speed = 255) {
|
|
191
|
+
const clampedSpeed = Math.min(255, Math.max(1, speed));
|
|
192
|
+
return this.sendCommand(deviceId, 'setPosition', `0,${clampedSpeed.toString(16).padStart(2, '0')},${position}`);
|
|
190
193
|
}
|
|
191
194
|
/**
|
|
192
195
|
* Lock-specific commands
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/ble.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
2
|
import type { BLEAdvertisement, BLEScanOptions } from './types/ble.js';
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
4
|
/**
|
|
@@ -9,6 +9,11 @@ export declare class BLEScanner extends EventEmitter {
|
|
|
9
9
|
private logger;
|
|
10
10
|
private scanning;
|
|
11
11
|
private discoveredDevices;
|
|
12
|
+
private discoveredModelCache;
|
|
13
|
+
private nobleStateHandler?;
|
|
14
|
+
private nobleDiscoverHandler?;
|
|
15
|
+
private nobleScanStartHandler?;
|
|
16
|
+
private nobleScanStopHandler?;
|
|
12
17
|
private noblePromise;
|
|
13
18
|
constructor(options?: {
|
|
14
19
|
noble?: any;
|
|
@@ -26,6 +31,10 @@ export declare class BLEScanner extends EventEmitter {
|
|
|
26
31
|
* Setup Noble event handlers
|
|
27
32
|
*/
|
|
28
33
|
private setupNobleHandlers;
|
|
34
|
+
/**
|
|
35
|
+
* Remove Noble event handlers
|
|
36
|
+
*/
|
|
37
|
+
private removeNobleHandlers;
|
|
29
38
|
/**
|
|
30
39
|
* Handle device discovery
|
|
31
40
|
*/
|
|
@@ -42,6 +51,10 @@ export declare class BLEScanner extends EventEmitter {
|
|
|
42
51
|
* Stop scanning
|
|
43
52
|
*/
|
|
44
53
|
stopScan(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Cleanup all resources
|
|
56
|
+
*/
|
|
57
|
+
destroy(): void;
|
|
45
58
|
/**
|
|
46
59
|
* Get all discovered devices
|
|
47
60
|
*/
|
|
@@ -67,6 +80,10 @@ export declare class BLEConnection {
|
|
|
67
80
|
private logger;
|
|
68
81
|
private connections;
|
|
69
82
|
private characteristics;
|
|
83
|
+
private disconnectTimers;
|
|
84
|
+
private operationLocks;
|
|
85
|
+
private encryptionConfig;
|
|
86
|
+
private persistentConnectionMs;
|
|
70
87
|
private noblePromise;
|
|
71
88
|
constructor(options?: {
|
|
72
89
|
noble?: any;
|
|
@@ -80,6 +97,20 @@ export declare class BLEConnection {
|
|
|
80
97
|
* Ensure Noble is loaded before operations
|
|
81
98
|
*/
|
|
82
99
|
private ensureNoble;
|
|
100
|
+
private withMacLock;
|
|
101
|
+
private clearDisconnectTimer;
|
|
102
|
+
private scheduleDisconnect;
|
|
103
|
+
setPersistentConnectionTimeout(timeoutMs: number): void;
|
|
104
|
+
setEncryption(mac: string, keyHex: string, ivHex: string, mode?: 'auto' | 'ctr' | 'gcm'): void;
|
|
105
|
+
clearEncryption(mac: string): void;
|
|
106
|
+
private incrementIv;
|
|
107
|
+
private encryptIfConfigured;
|
|
108
|
+
private validateCommandResult;
|
|
109
|
+
sendCommand(mac: string, data: Buffer, options?: {
|
|
110
|
+
expectResponse?: boolean;
|
|
111
|
+
validateResponse?: boolean;
|
|
112
|
+
responseTimeoutMs?: number;
|
|
113
|
+
}): Promise<Buffer | undefined>;
|
|
83
114
|
/**
|
|
84
115
|
* Connect to a device
|
|
85
116
|
*/
|
package/dist/ble.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ble.d.ts","sourceRoot":"","sources":["../src/ble.ts"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"ble.d.ts","sourceRoot":"","sources":["../src/ble.ts"],"names":[],"mappings":"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"}
|
package/dist/ble.js
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
*
|
|
3
3
|
* ble.ts: SwitchBot v4.0.0 - BLE Discovery and Communication
|
|
4
4
|
*/
|
|
5
|
+
import { Buffer } from 'node:buffer';
|
|
6
|
+
import { createCipheriv } from 'node:crypto';
|
|
5
7
|
import { EventEmitter } from 'node:events';
|
|
6
|
-
import { BLENotAvailableError, DeviceNotFoundError } from './errors.js';
|
|
8
|
+
import { BLENotAvailableError, CommandFailedError, DeviceNotFoundError } from './errors.js';
|
|
7
9
|
import { BLE_COMMAND_TIMEOUT, BLE_CONNECT_TIMEOUT, BLE_NOTIFY_CHARACTERISTIC_UUID, BLE_SCAN_TIMEOUT, BLE_SERVICE_UUID, BLE_WRITE_CHARACTERISTIC_UUID, DEVICE_MODEL_MAP } from './settings.js';
|
|
8
10
|
import { Logger, macToDeviceId, normalizeMAC, withTimeout, extractMacFromManufacturerData } from './utils/index.js';
|
|
9
11
|
/**
|
|
@@ -14,6 +16,11 @@ export class BLEScanner extends EventEmitter {
|
|
|
14
16
|
logger;
|
|
15
17
|
scanning = false;
|
|
16
18
|
discoveredDevices = new Map();
|
|
19
|
+
discoveredModelCache = new Map();
|
|
20
|
+
nobleStateHandler;
|
|
21
|
+
nobleDiscoverHandler;
|
|
22
|
+
nobleScanStartHandler;
|
|
23
|
+
nobleScanStopHandler;
|
|
17
24
|
noblePromise = null;
|
|
18
25
|
constructor(options = {}) {
|
|
19
26
|
super();
|
|
@@ -72,38 +79,85 @@ export class BLEScanner extends EventEmitter {
|
|
|
72
79
|
* Setup Noble event handlers
|
|
73
80
|
*/
|
|
74
81
|
setupNobleHandlers() {
|
|
75
|
-
|
|
82
|
+
// Prevent duplicate listeners if handlers are re-initialized
|
|
83
|
+
this.removeNobleHandlers();
|
|
84
|
+
// Store handlers as properties for later cleanup
|
|
85
|
+
this.nobleStateHandler = (state) => {
|
|
76
86
|
this.logger.debug('Noble state changed:', state);
|
|
77
87
|
this.emit('state-change', state);
|
|
78
88
|
if (state === 'poweredOn') {
|
|
79
89
|
this.emit('ready');
|
|
80
90
|
}
|
|
81
|
-
}
|
|
82
|
-
this.
|
|
91
|
+
};
|
|
92
|
+
this.nobleDiscoverHandler = (peripheral) => {
|
|
83
93
|
this.handleDiscovery(peripheral);
|
|
84
|
-
}
|
|
85
|
-
this.
|
|
94
|
+
};
|
|
95
|
+
this.nobleScanStartHandler = () => {
|
|
86
96
|
this.scanning = true;
|
|
87
97
|
this.logger.info('BLE scan started');
|
|
88
98
|
this.emit('scan-start');
|
|
89
|
-
}
|
|
90
|
-
this.
|
|
99
|
+
};
|
|
100
|
+
this.nobleScanStopHandler = () => {
|
|
91
101
|
this.scanning = false;
|
|
92
102
|
this.logger.info('BLE scan stopped');
|
|
93
103
|
this.emit('scan-stop');
|
|
94
|
-
}
|
|
104
|
+
};
|
|
105
|
+
this.noble.on('stateChange', this.nobleStateHandler);
|
|
106
|
+
this.noble.on('discover', this.nobleDiscoverHandler);
|
|
107
|
+
this.noble.on('scanStart', this.nobleScanStartHandler);
|
|
108
|
+
this.noble.on('scanStop', this.nobleScanStopHandler);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Remove Noble event handlers
|
|
112
|
+
*/
|
|
113
|
+
removeNobleHandlers() {
|
|
114
|
+
if (this.nobleStateHandler) {
|
|
115
|
+
this.noble.off('stateChange', this.nobleStateHandler);
|
|
116
|
+
}
|
|
117
|
+
if (this.nobleDiscoverHandler) {
|
|
118
|
+
this.noble.off('discover', this.nobleDiscoverHandler);
|
|
119
|
+
}
|
|
120
|
+
if (this.nobleScanStartHandler) {
|
|
121
|
+
this.noble.off('scanStart', this.nobleScanStartHandler);
|
|
122
|
+
}
|
|
123
|
+
if (this.nobleScanStopHandler) {
|
|
124
|
+
this.noble.off('scanStop', this.nobleScanStopHandler);
|
|
125
|
+
}
|
|
126
|
+
this.nobleStateHandler = undefined;
|
|
127
|
+
this.nobleDiscoverHandler = undefined;
|
|
128
|
+
this.nobleScanStartHandler = undefined;
|
|
129
|
+
this.nobleScanStopHandler = undefined;
|
|
95
130
|
}
|
|
96
131
|
/**
|
|
97
132
|
* Handle device discovery
|
|
98
133
|
*/
|
|
99
134
|
handleDiscovery(peripheral) {
|
|
100
135
|
try {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
136
|
+
// Validate peripheral has required properties
|
|
137
|
+
if (!peripheral || typeof peripheral !== 'object') {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const { advertisement, address, rssi, connectable } = peripheral;
|
|
141
|
+
// Skip non-connectable devices
|
|
142
|
+
if (connectable === false) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
// Skip devices with invalid RSSI (typical range: -120 to 0 dBm)
|
|
146
|
+
if (typeof rssi !== 'number' || rssi < -120 || rssi > 0) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Validate advertisement object exists and has service data
|
|
150
|
+
if (!advertisement || typeof advertisement !== 'object') {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (!Array.isArray(advertisement.serviceData) || advertisement.serviceData.length === 0) {
|
|
104
154
|
return;
|
|
105
155
|
}
|
|
106
156
|
for (const serviceDataItem of advertisement.serviceData) {
|
|
157
|
+
// Validate service data item has required properties
|
|
158
|
+
if (!serviceDataItem || typeof serviceDataItem !== 'object') {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
107
161
|
// SwitchBot service UUID (current: fd3d, legacy: 000d)
|
|
108
162
|
const uuid = typeof serviceDataItem.uuid === 'string' ? serviceDataItem.uuid.toLowerCase() : '';
|
|
109
163
|
const isSwitchBotUUID = uuid === 'fd3d' ||
|
|
@@ -120,7 +174,7 @@ export class BLEScanner extends EventEmitter {
|
|
|
120
174
|
let normalizedAddress = typeof address === 'string' && address.length > 0 ? normalizeMAC(address) : undefined;
|
|
121
175
|
// Fallback to manufacturer data MAC if service data address is empty
|
|
122
176
|
if (!normalizedAddress) {
|
|
123
|
-
const manufacturerMac = extractMacFromManufacturerData(peripheral.advertisement
|
|
177
|
+
const manufacturerMac = extractMacFromManufacturerData(peripheral.advertisement?.manufacturerData);
|
|
124
178
|
if (manufacturerMac) {
|
|
125
179
|
normalizedAddress = manufacturerMac;
|
|
126
180
|
}
|
|
@@ -141,6 +195,7 @@ export class BLEScanner extends EventEmitter {
|
|
|
141
195
|
};
|
|
142
196
|
const discoveryKey = normalizedAddress ?? `id:${fallbackId}`;
|
|
143
197
|
this.discoveredDevices.set(discoveryKey, advertisement);
|
|
198
|
+
this.discoveredModelCache.set(discoveryKey, serviceData.model);
|
|
144
199
|
this.emit('discover', advertisement);
|
|
145
200
|
this.logger.debug(`Discovered ${serviceData.modelName} at ${normalizedAddress ?? fallbackId}`);
|
|
146
201
|
}
|
|
@@ -173,6 +228,45 @@ export class BLEScanner extends EventEmitter {
|
|
|
173
228
|
if (data.length > 2) {
|
|
174
229
|
serviceData.battery = data[2] & 0x7F;
|
|
175
230
|
}
|
|
231
|
+
// Model-specific advertisement parsing for status without active connection
|
|
232
|
+
if (model === 'H' && data.length > 1) {
|
|
233
|
+
// Bot (WoHand): infer mode/state from status bits
|
|
234
|
+
serviceData.mode = (data[1] & 0x80) ? 'switch' : 'press';
|
|
235
|
+
serviceData.state = (data[1] & 0x40) !== 0;
|
|
236
|
+
}
|
|
237
|
+
if ((model === 'c' || model === '{') && data.length > 4) {
|
|
238
|
+
// Curtain/Curtain3
|
|
239
|
+
serviceData.inMotion = (data[1] & 0x40) !== 0;
|
|
240
|
+
serviceData.position = Math.min(100, Math.max(0, data[3] & 0x7F));
|
|
241
|
+
serviceData.lightLevel = data[4] & 0x7F;
|
|
242
|
+
serviceData.calibration = (data[1] & 0x20) !== 0;
|
|
243
|
+
if (data.length > 5) {
|
|
244
|
+
serviceData.deviceChain = data[5] & 0x03;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if ((model === 'o' || model === '\x11') && data.length > 1) {
|
|
248
|
+
// Lock / Lock Pro
|
|
249
|
+
const lockStatus = data[1] & 0x0F;
|
|
250
|
+
serviceData.status = lockStatus;
|
|
251
|
+
serviceData.doorOpen = (data[1] & 0x10) !== 0;
|
|
252
|
+
serviceData.calibration = (data[1] & 0x80) !== 0;
|
|
253
|
+
serviceData.lockState = lockStatus === 1
|
|
254
|
+
? 'unlocked'
|
|
255
|
+
: lockStatus === 2
|
|
256
|
+
? 'jammed'
|
|
257
|
+
: 'locked';
|
|
258
|
+
if (data.length > 3) {
|
|
259
|
+
serviceData.sequenceNumber = data[3];
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if ((model === '\x0D' || model === '\x0E') && data.length > 1) {
|
|
263
|
+
// Relay Switch 1PM / Relay Switch 1
|
|
264
|
+
serviceData.state = (data[1] & 0x01) === 0x01;
|
|
265
|
+
serviceData.channel2State = (data[1] & 0x02) === 0x02;
|
|
266
|
+
if (data.length > 3) {
|
|
267
|
+
serviceData.sequenceNumber = data[3];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
176
270
|
return serviceData;
|
|
177
271
|
}
|
|
178
272
|
catch (error) {
|
|
@@ -203,6 +297,7 @@ export class BLEScanner extends EventEmitter {
|
|
|
203
297
|
}
|
|
204
298
|
// Clear previous discoveries if starting fresh
|
|
205
299
|
this.discoveredDevices.clear();
|
|
300
|
+
this.discoveredModelCache.clear();
|
|
206
301
|
// Start scanning
|
|
207
302
|
this.noble.startScanning([], active);
|
|
208
303
|
// Auto-stop after duration
|
|
@@ -222,6 +317,15 @@ export class BLEScanner extends EventEmitter {
|
|
|
222
317
|
this.noble.stopScanning();
|
|
223
318
|
}
|
|
224
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Cleanup all resources
|
|
322
|
+
*/
|
|
323
|
+
destroy() {
|
|
324
|
+
this.stopScan();
|
|
325
|
+
this.removeNobleHandlers();
|
|
326
|
+
this.discoveredDevices.clear();
|
|
327
|
+
this.discoveredModelCache.clear();
|
|
328
|
+
}
|
|
225
329
|
/**
|
|
226
330
|
* Get all discovered devices
|
|
227
331
|
*/
|
|
@@ -282,6 +386,10 @@ export class BLEConnection {
|
|
|
282
386
|
logger;
|
|
283
387
|
connections = new Map(); // Map of MAC -> Peripheral
|
|
284
388
|
characteristics = new Map();
|
|
389
|
+
disconnectTimers = new Map();
|
|
390
|
+
operationLocks = new Map();
|
|
391
|
+
encryptionConfig = new Map();
|
|
392
|
+
persistentConnectionMs = 8500;
|
|
285
393
|
noblePromise = null;
|
|
286
394
|
constructor(options = {}) {
|
|
287
395
|
this.logger = new Logger('BLEConnection', options.logLevel);
|
|
@@ -331,6 +439,127 @@ export class BLEConnection {
|
|
|
331
439
|
throw new BLENotAvailableError('BLE not available - noble failed to initialize');
|
|
332
440
|
}
|
|
333
441
|
}
|
|
442
|
+
async withMacLock(mac, fn) {
|
|
443
|
+
const normalizedMac = normalizeMAC(mac);
|
|
444
|
+
const previousLock = this.operationLocks.get(normalizedMac) ?? Promise.resolve();
|
|
445
|
+
let releaseCurrent = () => { };
|
|
446
|
+
const currentLock = new Promise((resolve) => {
|
|
447
|
+
releaseCurrent = resolve;
|
|
448
|
+
});
|
|
449
|
+
const chainedLock = previousLock.then(() => currentLock);
|
|
450
|
+
this.operationLocks.set(normalizedMac, chainedLock);
|
|
451
|
+
await previousLock;
|
|
452
|
+
try {
|
|
453
|
+
return await fn();
|
|
454
|
+
}
|
|
455
|
+
finally {
|
|
456
|
+
releaseCurrent();
|
|
457
|
+
if (this.operationLocks.get(normalizedMac) === chainedLock) {
|
|
458
|
+
this.operationLocks.delete(normalizedMac);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
clearDisconnectTimer(mac) {
|
|
463
|
+
const existingTimer = this.disconnectTimers.get(mac);
|
|
464
|
+
if (existingTimer) {
|
|
465
|
+
clearTimeout(existingTimer);
|
|
466
|
+
this.disconnectTimers.delete(mac);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
scheduleDisconnect(mac) {
|
|
470
|
+
this.clearDisconnectTimer(mac);
|
|
471
|
+
const timer = setTimeout(() => {
|
|
472
|
+
this.disconnect(mac).catch((error) => {
|
|
473
|
+
this.logger.debug(`Auto-disconnect failed for ${mac}`, error);
|
|
474
|
+
});
|
|
475
|
+
}, this.persistentConnectionMs);
|
|
476
|
+
this.disconnectTimers.set(mac, timer);
|
|
477
|
+
}
|
|
478
|
+
setPersistentConnectionTimeout(timeoutMs) {
|
|
479
|
+
this.persistentConnectionMs = Math.max(1000, timeoutMs);
|
|
480
|
+
}
|
|
481
|
+
setEncryption(mac, keyHex, ivHex, mode = 'auto') {
|
|
482
|
+
const normalizedMac = normalizeMAC(mac);
|
|
483
|
+
const key = Buffer.from(keyHex, 'hex');
|
|
484
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
485
|
+
if (key.length !== 16) {
|
|
486
|
+
throw new CommandFailedError('Invalid BLE encryption key length (expected 16 bytes)', 'ble');
|
|
487
|
+
}
|
|
488
|
+
const resolvedMode = mode === 'auto'
|
|
489
|
+
? (iv.length === 12 ? 'gcm' : 'ctr')
|
|
490
|
+
: mode;
|
|
491
|
+
const expectedIvLength = resolvedMode === 'gcm' ? 12 : 16;
|
|
492
|
+
if (iv.length !== expectedIvLength) {
|
|
493
|
+
throw new CommandFailedError(`Invalid IV length for ${resolvedMode.toUpperCase()} mode`, 'ble');
|
|
494
|
+
}
|
|
495
|
+
this.encryptionConfig.set(normalizedMac, { key, iv: Buffer.from(iv), mode: resolvedMode });
|
|
496
|
+
}
|
|
497
|
+
clearEncryption(mac) {
|
|
498
|
+
this.encryptionConfig.delete(normalizeMAC(mac));
|
|
499
|
+
}
|
|
500
|
+
incrementIv(iv) {
|
|
501
|
+
const nextIv = Buffer.from(iv);
|
|
502
|
+
for (let i = nextIv.length - 1; i >= 0; i--) {
|
|
503
|
+
if ((nextIv[i] ?? 0) === 0xFF) {
|
|
504
|
+
nextIv[i] = 0x00;
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
nextIv[i] = (nextIv[i] ?? 0) + 1;
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return nextIv;
|
|
512
|
+
}
|
|
513
|
+
encryptIfConfigured(mac, data) {
|
|
514
|
+
const normalizedMac = normalizeMAC(mac);
|
|
515
|
+
const config = this.encryptionConfig.get(normalizedMac);
|
|
516
|
+
if (!config) {
|
|
517
|
+
return data;
|
|
518
|
+
}
|
|
519
|
+
if (config.mode === 'gcm') {
|
|
520
|
+
const cipher = createCipheriv('aes-128-gcm', config.key, config.iv);
|
|
521
|
+
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
522
|
+
const tag = cipher.getAuthTag().subarray(0, 2);
|
|
523
|
+
this.encryptionConfig.set(normalizedMac, {
|
|
524
|
+
...config,
|
|
525
|
+
iv: this.incrementIv(config.iv),
|
|
526
|
+
});
|
|
527
|
+
return Buffer.concat([encrypted, tag]);
|
|
528
|
+
}
|
|
529
|
+
const cipher = createCipheriv('aes-128-ctr', config.key, config.iv);
|
|
530
|
+
return Buffer.concat([cipher.update(data), cipher.final()]);
|
|
531
|
+
}
|
|
532
|
+
validateCommandResult(response, mac) {
|
|
533
|
+
if (!response || response.length === 0) {
|
|
534
|
+
throw new CommandFailedError(`Empty BLE response from ${mac}`, 'ble');
|
|
535
|
+
}
|
|
536
|
+
if (response.includes(0x07)) {
|
|
537
|
+
throw new CommandFailedError(`BLE command rejected by ${mac}: password required`, 'ble');
|
|
538
|
+
}
|
|
539
|
+
if (response.includes(0x09)) {
|
|
540
|
+
throw new CommandFailedError(`BLE command rejected by ${mac}: password incorrect`, 'ble');
|
|
541
|
+
}
|
|
542
|
+
const acknowledged = response.some(byte => byte === 0x01 || byte === 0x05 || byte === 0x06);
|
|
543
|
+
if (!acknowledged) {
|
|
544
|
+
throw new CommandFailedError(`Unexpected BLE response from ${mac}: ${response.toString('hex')}`, 'ble');
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
async sendCommand(mac, data, options = {}) {
|
|
548
|
+
const normalizedMac = normalizeMAC(mac);
|
|
549
|
+
const { expectResponse = true, validateResponse = true, responseTimeoutMs = 1200, } = options;
|
|
550
|
+
return this.withMacLock(normalizedMac, async () => {
|
|
551
|
+
const payload = this.encryptIfConfigured(normalizedMac, data);
|
|
552
|
+
await this.write(normalizedMac, payload);
|
|
553
|
+
if (!expectResponse && !validateResponse) {
|
|
554
|
+
return undefined;
|
|
555
|
+
}
|
|
556
|
+
const response = await withTimeout(this.read(normalizedMac), responseTimeoutMs, `BLE response timeout from ${normalizedMac}`);
|
|
557
|
+
if (validateResponse) {
|
|
558
|
+
this.validateCommandResult(response, normalizedMac);
|
|
559
|
+
}
|
|
560
|
+
return response;
|
|
561
|
+
});
|
|
562
|
+
}
|
|
334
563
|
/**
|
|
335
564
|
* Connect to a device
|
|
336
565
|
*/
|
|
@@ -339,6 +568,7 @@ export class BLEConnection {
|
|
|
339
568
|
const normalizedMac = normalizeMAC(mac);
|
|
340
569
|
// Already connected?
|
|
341
570
|
if (this.connections.has(normalizedMac)) {
|
|
571
|
+
this.clearDisconnectTimer(normalizedMac);
|
|
342
572
|
this.logger.debug(`Already connected to ${mac}`);
|
|
343
573
|
return;
|
|
344
574
|
}
|
|
@@ -372,9 +602,22 @@ export class BLEConnection {
|
|
|
372
602
|
});
|
|
373
603
|
}), BLE_CONNECT_TIMEOUT, `Connection to ${mac} timed out`);
|
|
374
604
|
this.connections.set(normalizedMac, peripheral);
|
|
605
|
+
this.clearDisconnectTimer(normalizedMac);
|
|
375
606
|
this.logger.info(`Connected to ${mac}`);
|
|
376
|
-
// Discover characteristics
|
|
377
|
-
|
|
607
|
+
// Discover characteristics (may throw)
|
|
608
|
+
try {
|
|
609
|
+
await this.discoverCharacteristics(normalizedMac, peripheral);
|
|
610
|
+
}
|
|
611
|
+
catch (error) {
|
|
612
|
+
// Clean up partial connection if characteristic discovery fails
|
|
613
|
+
this.connections.delete(normalizedMac);
|
|
614
|
+
this.characteristics.delete(normalizedMac);
|
|
615
|
+
// Best effort disconnect to avoid leaked active BLE links
|
|
616
|
+
await new Promise((resolve) => {
|
|
617
|
+
peripheral.disconnect(() => resolve());
|
|
618
|
+
});
|
|
619
|
+
throw error;
|
|
620
|
+
}
|
|
378
621
|
}
|
|
379
622
|
/**
|
|
380
623
|
* Discover service characteristics
|
|
@@ -404,6 +647,8 @@ export class BLEConnection {
|
|
|
404
647
|
async disconnect(mac) {
|
|
405
648
|
const normalizedMac = normalizeMAC(mac);
|
|
406
649
|
const peripheral = this.connections.get(normalizedMac);
|
|
650
|
+
this.clearDisconnectTimer(normalizedMac);
|
|
651
|
+
this.clearEncryption(normalizedMac);
|
|
407
652
|
if (!peripheral) {
|
|
408
653
|
return;
|
|
409
654
|
}
|
|
@@ -436,6 +681,7 @@ export class BLEConnection {
|
|
|
436
681
|
reject(error);
|
|
437
682
|
}
|
|
438
683
|
else {
|
|
684
|
+
this.scheduleDisconnect(normalizedMac);
|
|
439
685
|
resolve();
|
|
440
686
|
}
|
|
441
687
|
});
|
|
@@ -461,6 +707,7 @@ export class BLEConnection {
|
|
|
461
707
|
reject(error);
|
|
462
708
|
}
|
|
463
709
|
else {
|
|
710
|
+
this.scheduleDisconnect(normalizedMac);
|
|
464
711
|
resolve(data);
|
|
465
712
|
}
|
|
466
713
|
});
|