node-switchbot 4.0.0-beta.1 → 4.0.0-beta.10
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/.github/copilot-instructions.md +19 -5
- package/BLE.md +117 -4
- package/CHANGELOG.md +45 -0
- package/README.md +7 -1
- 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 +38 -4
- package/dist/ble.d.ts.map +1 -1
- package/dist/ble.js +409 -53
- package/dist/ble.js.map +1 -1
- package/dist/devices/base.d.ts +83 -5
- package/dist/devices/base.d.ts.map +1 -1
- package/dist/devices/base.js +371 -34
- package/dist/devices/base.js.map +1 -1
- package/dist/devices/device-override-state-during-connection.d.ts +27 -0
- package/dist/devices/device-override-state-during-connection.d.ts.map +1 -0
- package/dist/devices/device-override-state-during-connection.js +45 -0
- package/dist/devices/device-override-state-during-connection.js.map +1 -0
- package/dist/devices/index.d.ts +4 -0
- package/dist/devices/index.d.ts.map +1 -1
- package/dist/devices/index.js +4 -0
- package/dist/devices/index.js.map +1 -1
- package/dist/devices/sequence-device.d.ts +36 -0
- package/dist/devices/sequence-device.d.ts.map +1 -0
- package/dist/devices/sequence-device.js +75 -0
- package/dist/devices/sequence-device.js.map +1 -0
- package/dist/devices/wo-air-purifier.d.ts +2 -2
- package/dist/devices/wo-air-purifier.d.ts.map +1 -1
- package/dist/devices/wo-air-purifier.js +2 -2
- package/dist/devices/wo-air-purifier.js.map +1 -1
- package/dist/devices/wo-bulb.d.ts +10 -0
- package/dist/devices/wo-bulb.d.ts.map +1 -1
- package/dist/devices/wo-bulb.js +69 -0
- package/dist/devices/wo-bulb.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.d.ts +53 -2
- package/dist/devices/wo-hand.d.ts.map +1 -1
- package/dist/devices/wo-hand.js +121 -3
- package/dist/devices/wo-hand.js.map +1 -1
- package/dist/devices/wo-lock-pro.d.ts +11 -2
- package/dist/devices/wo-lock-pro.d.ts.map +1 -1
- package/dist/devices/wo-lock-pro.js +65 -3
- package/dist/devices/wo-lock-pro.js.map +1 -1
- package/dist/devices/wo-lock.d.ts +7 -2
- package/dist/devices/wo-lock.d.ts.map +1 -1
- package/dist/devices/wo-lock.js +58 -3
- package/dist/devices/wo-lock.js.map +1 -1
- package/dist/devices/wo-plug-mini-us.d.ts +2 -2
- package/dist/devices/wo-plug-mini-us.d.ts.map +1 -1
- package/dist/devices/wo-plug-mini-us.js +2 -2
- package/dist/devices/wo-plug-mini-us.js.map +1 -1
- package/dist/devices/wo-relay-switch-1.d.ts +4 -2
- package/dist/devices/wo-relay-switch-1.d.ts.map +1 -1
- package/dist/devices/wo-relay-switch-1.js +36 -4
- package/dist/devices/wo-relay-switch-1.js.map +1 -1
- package/dist/devices/wo-relay-switch-2pm.d.ts +21 -0
- package/dist/devices/wo-relay-switch-2pm.d.ts.map +1 -0
- package/dist/devices/wo-relay-switch-2pm.js +39 -0
- package/dist/devices/wo-relay-switch-2pm.js.map +1 -0
- package/dist/devices/wo-rgbic-bulb.d.ts +29 -0
- package/dist/devices/wo-rgbic-bulb.d.ts.map +1 -0
- package/dist/devices/wo-rgbic-bulb.js +84 -0
- package/dist/devices/wo-rgbic-bulb.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/settings.d.ts +17 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +18 -1
- package/dist/settings.js.map +1 -1
- package/dist/switchbot.d.ts.map +1 -1
- package/dist/switchbot.js +31 -8
- package/dist/switchbot.js.map +1 -1
- package/dist/types/ble.d.ts +20 -1
- package/dist/types/ble.d.ts.map +1 -1
- package/dist/types/ble.js.map +1 -1
- package/dist/types/device.d.ts +30 -3
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/bot-ble.d.ts +36 -0
- package/dist/utils/bot-ble.d.ts.map +1 -0
- package/dist/utils/bot-ble.js +109 -0
- package/dist/utils/bot-ble.js.map +1 -0
- package/dist/utils/circuit-breaker.d.ts +98 -0
- package/dist/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/utils/circuit-breaker.js +187 -0
- package/dist/utils/circuit-breaker.js.map +1 -0
- package/dist/utils/connection-tracker.d.ts +66 -0
- package/dist/utils/connection-tracker.d.ts.map +1 -0
- package/dist/utils/connection-tracker.js +184 -0
- package/dist/utils/connection-tracker.js.map +1 -0
- package/dist/utils/fallback-handler.d.ts +68 -0
- package/dist/utils/fallback-handler.d.ts.map +1 -0
- package/dist/utils/fallback-handler.js +131 -0
- package/dist/utils/fallback-handler.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +41 -4
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/retry.d.ts +55 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +95 -0
- package/dist/utils/retry.js.map +1 -0
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.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 +16 -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/DeviceOverrideStateDuringConnection.html +56 -0
- package/docs/classes/DiscoveryError.html +2 -2
- package/docs/classes/OpenAPIClient.html +24 -24
- package/docs/classes/SequenceDevice.html +58 -0
- package/docs/classes/SwitchBot.html +11 -11
- package/docs/classes/SwitchBotDevice.html +43 -15
- package/docs/classes/SwitchBotError.html +2 -2
- package/docs/classes/ValidationError.html +2 -2
- package/docs/classes/WoAirPurifier.html +48 -18
- package/docs/classes/WoAirPurifierTable.html +48 -18
- package/docs/classes/WoBlindTilt.html +48 -20
- package/docs/classes/WoBulb.html +52 -19
- package/docs/classes/WoCeilingLight.html +52 -19
- package/docs/classes/WoContact.html +42 -14
- package/docs/classes/WoCurtain.html +46 -18
- package/docs/classes/WoHand.html +63 -19
- package/docs/classes/WoHub2.html +42 -14
- package/docs/classes/WoHub3.html +42 -14
- package/docs/classes/WoHumi.html +46 -18
- package/docs/classes/WoHumi2.html +46 -18
- package/docs/classes/WoIOSensorTH.html +42 -14
- package/docs/classes/WoKeypad.html +42 -14
- package/docs/classes/WoLeak.html +42 -14
- package/docs/classes/WoPlugMiniJP.html +45 -17
- package/docs/classes/WoPlugMiniUS.html +45 -17
- package/docs/classes/WoPresence.html +42 -14
- package/docs/classes/WoRelaySwitch1.html +47 -17
- package/docs/classes/WoRelaySwitch1PM.html +47 -17
- package/docs/classes/WoRemote.html +42 -14
- package/docs/classes/WoSensorTH.html +42 -14
- package/docs/classes/WoSensorTHPlus.html +42 -14
- package/docs/classes/WoSensorTHPro.html +42 -14
- package/docs/classes/WoSensorTHProCO2.html +42 -14
- package/docs/classes/WoSmartLock.html +49 -16
- package/docs/classes/WoSmartLockPro.html +52 -17
- package/docs/classes/WoStrip.html +52 -19
- 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/index.html +2 -2
- 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 +3 -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 +6 -2
- package/docs/interfaces/BotServiceData.html +20 -5
- package/docs/interfaces/BotStatus.html +6 -6
- package/docs/interfaces/BulbCommands.html +4 -2
- package/docs/interfaces/BulbServiceData.html +21 -5
- package/docs/interfaces/BulbStatus.html +6 -6
- package/docs/interfaces/CeilingLightCommands.html +4 -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 +23 -13
- 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 +6 -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 +4 -2
- package/docs/interfaces/StripServiceData.html +21 -5
- package/docs/interfaces/StripStatus.html +6 -6
- package/docs/interfaces/SwitchBotConfig.html +21 -9
- 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/media/BLE.md +117 -4
- package/docs/modules.html +1 -1
- 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 +11 -7
- package/tmp-switchbot-scan.mjs +79 -0
- package/todo/PYSWITCHBOT_COMPARISON.md +484 -0
- package/todo/README.md +68 -0
- package/todo/completed.md +134 -0
- package/todo/todo.md +296 -0
- package/tsconfig.build.json +17 -0
- package/PRODUCTION_READY.md +0 -135
package/dist/devices/wo-hand.js
CHANGED
|
@@ -3,15 +3,38 @@
|
|
|
3
3
|
* devices/wo-hand.ts: SwitchBot v4.0.0 - Bot (WoHand) Device
|
|
4
4
|
*/
|
|
5
5
|
import { DEVICE_COMMANDS } from '../settings.js';
|
|
6
|
-
import {
|
|
6
|
+
import { BOT_BLE_ACTIONS, buildBotBleCommand, parseBotBleResponse, validateBotPassword } from '../utils/index.js';
|
|
7
|
+
import { DeviceOverrideStateDuringConnection } from './device-override-state-during-connection.js';
|
|
7
8
|
/**
|
|
8
9
|
* Bot (WoHand) Device - Press or switch button device
|
|
10
|
+
* Supports optional BLE password protection
|
|
9
11
|
*/
|
|
10
|
-
export class WoHand extends
|
|
12
|
+
export class WoHand extends DeviceOverrideStateDuringConnection {
|
|
13
|
+
password;
|
|
14
|
+
constructor(info, options = {}) {
|
|
15
|
+
super(info, options);
|
|
16
|
+
// Validate and store password if provided
|
|
17
|
+
if (options.password) {
|
|
18
|
+
try {
|
|
19
|
+
validateBotPassword(options.password);
|
|
20
|
+
this.password = options.password;
|
|
21
|
+
this.logger.info('Bot password configured');
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
this.logger.error('Invalid password format', error);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
11
29
|
/**
|
|
12
30
|
* Turn on (switch mode)
|
|
13
31
|
*/
|
|
14
32
|
async turnOn() {
|
|
33
|
+
// Use password-protected command if password is configured
|
|
34
|
+
if (this.password) {
|
|
35
|
+
return await this.executePasswordCommand(BOT_BLE_ACTIONS.TURN_ON);
|
|
36
|
+
}
|
|
37
|
+
// Standard command
|
|
15
38
|
const result = await this.sendCommand(DEVICE_COMMANDS.BOT.TURN_ON, 'turnOn');
|
|
16
39
|
return result.success;
|
|
17
40
|
}
|
|
@@ -19,6 +42,11 @@ export class WoHand extends SwitchBotDevice {
|
|
|
19
42
|
* Turn off (switch mode)
|
|
20
43
|
*/
|
|
21
44
|
async turnOff() {
|
|
45
|
+
// Use password-protected command if password is configured
|
|
46
|
+
if (this.password) {
|
|
47
|
+
return await this.executePasswordCommand(BOT_BLE_ACTIONS.TURN_OFF);
|
|
48
|
+
}
|
|
49
|
+
// Standard command
|
|
22
50
|
const result = await this.sendCommand(DEVICE_COMMANDS.BOT.TURN_OFF, 'turnOff');
|
|
23
51
|
return result.success;
|
|
24
52
|
}
|
|
@@ -26,9 +54,99 @@ export class WoHand extends SwitchBotDevice {
|
|
|
26
54
|
* Press (press mode)
|
|
27
55
|
*/
|
|
28
56
|
async press() {
|
|
57
|
+
// Use password-protected command if password is configured
|
|
58
|
+
if (this.password) {
|
|
59
|
+
return await this.executePasswordCommand(BOT_BLE_ACTIONS.PRESS);
|
|
60
|
+
}
|
|
61
|
+
// Standard command
|
|
29
62
|
const result = await this.sendCommand(DEVICE_COMMANDS.BOT.PRESS, 'press');
|
|
30
63
|
return result.success;
|
|
31
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Set Bot mode
|
|
67
|
+
*/
|
|
68
|
+
async setMode(mode) {
|
|
69
|
+
const modeByte = mode === 'switch' ? 0x01 : 0x00;
|
|
70
|
+
const result = await this.sendCommand([...DEVICE_COMMANDS.BOT.SET_MODE, modeByte], 'setMode', mode);
|
|
71
|
+
return result.success;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Set Bot long-press duration (1-255 deciseconds)
|
|
75
|
+
*/
|
|
76
|
+
async setLongPress(duration) {
|
|
77
|
+
const clampedDuration = Math.min(255, Math.max(1, Math.trunc(duration)));
|
|
78
|
+
const result = await this.sendCommand([...DEVICE_COMMANDS.BOT.SET_LONG_PRESS, clampedDuration], 'setLongPress', clampedDuration);
|
|
79
|
+
return result.success;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Raise Bot arm
|
|
83
|
+
*/
|
|
84
|
+
async handUp() {
|
|
85
|
+
const result = await this.sendCommand(DEVICE_COMMANDS.BOT.UP, 'turnOff');
|
|
86
|
+
return result.success;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Lower Bot arm
|
|
90
|
+
*/
|
|
91
|
+
async handDown() {
|
|
92
|
+
const result = await this.sendCommand(DEVICE_COMMANDS.BOT.DOWN, 'turnOn');
|
|
93
|
+
return result.success;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Execute password-protected Bot command
|
|
97
|
+
* @param action - Bot action to perform
|
|
98
|
+
* @returns True if command was successful
|
|
99
|
+
*/
|
|
100
|
+
async executePasswordCommand(action) {
|
|
101
|
+
if (!this.password) {
|
|
102
|
+
throw new Error('Password not configured for this Bot device');
|
|
103
|
+
}
|
|
104
|
+
if (!this.hasBLE()) {
|
|
105
|
+
throw new Error('BLE not available - password-protected commands require BLE connection');
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
// Build encrypted command
|
|
109
|
+
const command = buildBotBleCommand(action, this.password);
|
|
110
|
+
this.logger.debug('Sending password-protected command', { action });
|
|
111
|
+
// Send command via BLE
|
|
112
|
+
const mac = this.info.mac ?? `id:${this.info.bleId}`;
|
|
113
|
+
await this.bleConnection.write(mac, command);
|
|
114
|
+
// Read response
|
|
115
|
+
const responseBuffer = await this.bleConnection.read(mac);
|
|
116
|
+
// Parse and validate response
|
|
117
|
+
parseBotBleResponse(responseBuffer);
|
|
118
|
+
this.info.activeConnection = 'ble';
|
|
119
|
+
this.emit('command', { type: 'ble', success: true, encrypted: true });
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
this.logger.error('Password-protected command failed', error);
|
|
124
|
+
this.emit('error', { type: 'ble', error, encrypted: true });
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Set or update Bot password
|
|
130
|
+
* @param password - 4-character alphanumeric password (case-sensitive)
|
|
131
|
+
*/
|
|
132
|
+
setPassword(password) {
|
|
133
|
+
validateBotPassword(password);
|
|
134
|
+
this.password = password;
|
|
135
|
+
this.logger.info('Bot password updated');
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Clear Bot password
|
|
139
|
+
*/
|
|
140
|
+
clearPassword() {
|
|
141
|
+
this.password = undefined;
|
|
142
|
+
this.logger.info('Bot password cleared');
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Check if password is configured
|
|
146
|
+
*/
|
|
147
|
+
hasPassword() {
|
|
148
|
+
return !!this.password;
|
|
149
|
+
}
|
|
32
150
|
/**
|
|
33
151
|
* Get device status
|
|
34
152
|
*/
|
|
@@ -49,7 +167,7 @@ export class WoHand extends SwitchBotDevice {
|
|
|
49
167
|
}
|
|
50
168
|
// Fallback to BLE
|
|
51
169
|
if (this.hasBLE()) {
|
|
52
|
-
const bleData = await this.getBLEStatus();
|
|
170
|
+
const bleData = await this.getBLEStatus().catch(() => this.normalizeBLEStatusData(undefined));
|
|
53
171
|
return {
|
|
54
172
|
deviceId: this.info.id,
|
|
55
173
|
connectionType: 'ble',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-hand.js","sourceRoot":"","sources":["../../src/devices/wo-hand.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"wo-hand.js","sourceRoot":"","sources":["../../src/devices/wo-hand.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import type { Buffer } from 'node:buffer';
|
|
1
2
|
import type { LockCommands, LockStatus } from '../types/device.js';
|
|
2
|
-
import {
|
|
3
|
+
import { SequenceDevice } from './sequence-device.js';
|
|
3
4
|
/**
|
|
4
5
|
* Smart Lock Pro Device (with unlatch support)
|
|
5
6
|
*/
|
|
6
|
-
export declare class WoSmartLockPro extends
|
|
7
|
+
export declare class WoSmartLockPro extends SequenceDevice implements LockCommands {
|
|
8
|
+
private lockNotificationHandlers;
|
|
7
9
|
/**
|
|
8
10
|
* Lock the lock
|
|
9
11
|
*/
|
|
@@ -12,10 +14,17 @@ export declare class WoSmartLockPro extends SwitchBotDevice implements LockComma
|
|
|
12
14
|
* Unlock the lock
|
|
13
15
|
*/
|
|
14
16
|
unlock(): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* Unlock without unlatching the door
|
|
19
|
+
*/
|
|
20
|
+
unlockWithoutUnlatch(): Promise<boolean>;
|
|
15
21
|
/**
|
|
16
22
|
* Unlatch the lock (Lock Pro only)
|
|
17
23
|
*/
|
|
18
24
|
unlatch(): Promise<boolean>;
|
|
25
|
+
getLockInfo(): Promise<Record<string, unknown>>;
|
|
26
|
+
onLockNotification(handler: (payload: Buffer) => void): Promise<void>;
|
|
27
|
+
offLockNotification(handler: (payload: Buffer) => void): void;
|
|
19
28
|
/**
|
|
20
29
|
* Get device status
|
|
21
30
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-lock-pro.d.ts","sourceRoot":"","sources":["../../src/devices/wo-lock-pro.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGlE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wo-lock-pro.d.ts","sourceRoot":"","sources":["../../src/devices/wo-lock-pro.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGlE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD;;GAEG;AACH,qBAAa,cAAe,SAAQ,cAAe,YAAW,YAAY;IACxE,OAAO,CAAC,wBAAwB,CAAuC;IAEvE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAiB9B;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAiBhC;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IAS9C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ3B,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAsB/C,kBAAkB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAU3E,mBAAmB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAU7D;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;CAqCvC"}
|
|
@@ -3,15 +3,25 @@
|
|
|
3
3
|
* devices/wo-lock-pro.ts: SwitchBot v4.0.0 - Smart Lock Pro Device
|
|
4
4
|
*/
|
|
5
5
|
import { WoSmartLockProCommands } from '../settings.js';
|
|
6
|
-
import {
|
|
6
|
+
import { SequenceDevice } from './sequence-device.js';
|
|
7
7
|
/**
|
|
8
8
|
* Smart Lock Pro Device (with unlatch support)
|
|
9
9
|
*/
|
|
10
|
-
export class WoSmartLockPro extends
|
|
10
|
+
export class WoSmartLockPro extends SequenceDevice {
|
|
11
|
+
lockNotificationHandlers = new Set();
|
|
11
12
|
/**
|
|
12
13
|
* Lock the lock
|
|
13
14
|
*/
|
|
14
15
|
async lock() {
|
|
16
|
+
try {
|
|
17
|
+
const status = await this.getStatus();
|
|
18
|
+
if (status.lockState === 'locked') {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Best effort status check before command
|
|
24
|
+
}
|
|
15
25
|
const result = await this.sendCommand(WoSmartLockProCommands.LOCK, 'lock');
|
|
16
26
|
return result.success;
|
|
17
27
|
}
|
|
@@ -19,9 +29,25 @@ export class WoSmartLockPro extends SwitchBotDevice {
|
|
|
19
29
|
* Unlock the lock
|
|
20
30
|
*/
|
|
21
31
|
async unlock() {
|
|
32
|
+
try {
|
|
33
|
+
const status = await this.getStatus();
|
|
34
|
+
if (status.lockState === 'unlocked') {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Best effort status check before command
|
|
40
|
+
}
|
|
22
41
|
const result = await this.sendCommand(WoSmartLockProCommands.UNLOCK, 'unlock');
|
|
23
42
|
return result.success;
|
|
24
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Unlock without unlatching the door
|
|
46
|
+
*/
|
|
47
|
+
async unlockWithoutUnlatch() {
|
|
48
|
+
const result = await this.sendCommand(WoSmartLockProCommands.UNLOCK, 'unlock', 'withoutUnlatch');
|
|
49
|
+
return result.success;
|
|
50
|
+
}
|
|
25
51
|
/**
|
|
26
52
|
* Unlatch the lock (Lock Pro only)
|
|
27
53
|
*/
|
|
@@ -29,6 +55,42 @@ export class WoSmartLockPro extends SwitchBotDevice {
|
|
|
29
55
|
const result = await this.sendCommand(WoSmartLockProCommands.UNLATCH, 'unlock');
|
|
30
56
|
return result.success;
|
|
31
57
|
}
|
|
58
|
+
async getLockInfo() {
|
|
59
|
+
if (this.hasAPI()) {
|
|
60
|
+
const status = await this.getAPIStatus();
|
|
61
|
+
return {
|
|
62
|
+
lockState: status.lockState,
|
|
63
|
+
doorState: status.doorState,
|
|
64
|
+
calibrate: status.calibrate,
|
|
65
|
+
battery: status.battery,
|
|
66
|
+
version: status.version,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const ble = await this.getBLEStatus().catch(() => this.normalizeBLEStatusData(undefined));
|
|
70
|
+
return {
|
|
71
|
+
lockState: ble.lockState,
|
|
72
|
+
doorOpen: ble.doorOpen,
|
|
73
|
+
calibration: ble.calibration,
|
|
74
|
+
battery: ble.battery,
|
|
75
|
+
sequenceNumber: ble.sequenceNumber,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async onLockNotification(handler) {
|
|
79
|
+
if (!this.hasBLE()) {
|
|
80
|
+
throw new Error('BLE not available for lock notifications');
|
|
81
|
+
}
|
|
82
|
+
const mac = this.info.mac ?? `id:${this.info.bleId}`;
|
|
83
|
+
await this.bleConnection.subscribeNotifications(mac, handler);
|
|
84
|
+
this.lockNotificationHandlers.add(handler);
|
|
85
|
+
}
|
|
86
|
+
offLockNotification(handler) {
|
|
87
|
+
if (!this.hasBLE()) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const mac = this.info.mac ?? `id:${this.info.bleId}`;
|
|
91
|
+
this.bleConnection?.unsubscribeNotifications(mac, handler);
|
|
92
|
+
this.lockNotificationHandlers.delete(handler);
|
|
93
|
+
}
|
|
32
94
|
/**
|
|
33
95
|
* Get device status
|
|
34
96
|
*/
|
|
@@ -50,7 +112,7 @@ export class WoSmartLockPro extends SwitchBotDevice {
|
|
|
50
112
|
}
|
|
51
113
|
// Fallback to BLE
|
|
52
114
|
if (this.hasBLE()) {
|
|
53
|
-
const bleData = await this.getBLEStatus();
|
|
115
|
+
const bleData = await this.getBLEStatus().catch(() => this.normalizeBLEStatusData(undefined));
|
|
54
116
|
return {
|
|
55
117
|
deviceId: this.info.id,
|
|
56
118
|
connectionType: 'ble',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-lock-pro.js","sourceRoot":"","sources":["../../src/devices/wo-lock-pro.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"wo-lock-pro.js","sourceRoot":"","sources":["../../src/devices/wo-lock-pro.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import type { Buffer } from 'node:buffer';
|
|
1
2
|
import type { LockCommands, LockStatus } from '../types/device.js';
|
|
2
|
-
import {
|
|
3
|
+
import { SequenceDevice } from './sequence-device.js';
|
|
3
4
|
/**
|
|
4
5
|
* Smart Lock Device
|
|
5
6
|
*/
|
|
6
|
-
export declare class WoSmartLock extends
|
|
7
|
+
export declare class WoSmartLock extends SequenceDevice implements LockCommands {
|
|
8
|
+
private lockNotificationHandlers;
|
|
7
9
|
/**
|
|
8
10
|
* Lock the lock
|
|
9
11
|
*/
|
|
@@ -12,6 +14,9 @@ export declare class WoSmartLock extends SwitchBotDevice implements LockCommands
|
|
|
12
14
|
* Unlock the lock
|
|
13
15
|
*/
|
|
14
16
|
unlock(): Promise<boolean>;
|
|
17
|
+
getLockInfo(): Promise<Record<string, unknown>>;
|
|
18
|
+
onLockNotification(handler: (payload: Buffer) => void): Promise<void>;
|
|
19
|
+
offLockNotification(handler: (payload: Buffer) => void): void;
|
|
15
20
|
/**
|
|
16
21
|
* Get device status
|
|
17
22
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-lock.d.ts","sourceRoot":"","sources":["../../src/devices/wo-lock.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGlE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wo-lock.d.ts","sourceRoot":"","sources":["../../src/devices/wo-lock.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGlE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD;;GAEG;AACH,qBAAa,WAAY,SAAQ,cAAe,YAAW,YAAY;IACrE,OAAO,CAAC,wBAAwB,CAAuC;IAEvE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAiB9B;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAiB1B,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAsB/C,kBAAkB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAU3E,mBAAmB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAU7D;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;CAoCvC"}
|
package/dist/devices/wo-lock.js
CHANGED
|
@@ -3,15 +3,25 @@
|
|
|
3
3
|
* devices/wo-lock.ts: SwitchBot v4.0.0 - Smart Lock Device
|
|
4
4
|
*/
|
|
5
5
|
import { WoSmartLockCommands } from '../settings.js';
|
|
6
|
-
import {
|
|
6
|
+
import { SequenceDevice } from './sequence-device.js';
|
|
7
7
|
/**
|
|
8
8
|
* Smart Lock Device
|
|
9
9
|
*/
|
|
10
|
-
export class WoSmartLock extends
|
|
10
|
+
export class WoSmartLock extends SequenceDevice {
|
|
11
|
+
lockNotificationHandlers = new Set();
|
|
11
12
|
/**
|
|
12
13
|
* Lock the lock
|
|
13
14
|
*/
|
|
14
15
|
async lock() {
|
|
16
|
+
try {
|
|
17
|
+
const status = await this.getStatus();
|
|
18
|
+
if (status.lockState === 'locked') {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Best effort status check before command
|
|
24
|
+
}
|
|
15
25
|
const result = await this.sendCommand(WoSmartLockCommands.LOCK, 'lock');
|
|
16
26
|
return result.success;
|
|
17
27
|
}
|
|
@@ -19,9 +29,54 @@ export class WoSmartLock extends SwitchBotDevice {
|
|
|
19
29
|
* Unlock the lock
|
|
20
30
|
*/
|
|
21
31
|
async unlock() {
|
|
32
|
+
try {
|
|
33
|
+
const status = await this.getStatus();
|
|
34
|
+
if (status.lockState === 'unlocked') {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Best effort status check before command
|
|
40
|
+
}
|
|
22
41
|
const result = await this.sendCommand(WoSmartLockCommands.UNLOCK, 'unlock');
|
|
23
42
|
return result.success;
|
|
24
43
|
}
|
|
44
|
+
async getLockInfo() {
|
|
45
|
+
if (this.hasAPI()) {
|
|
46
|
+
const status = await this.getAPIStatus();
|
|
47
|
+
return {
|
|
48
|
+
lockState: status.lockState,
|
|
49
|
+
doorState: status.doorState,
|
|
50
|
+
calibrate: status.calibrate,
|
|
51
|
+
battery: status.battery,
|
|
52
|
+
version: status.version,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const ble = await this.getBLEStatus().catch(() => this.normalizeBLEStatusData(undefined));
|
|
56
|
+
return {
|
|
57
|
+
lockState: ble.lockState,
|
|
58
|
+
doorOpen: ble.doorOpen,
|
|
59
|
+
calibration: ble.calibration,
|
|
60
|
+
battery: ble.battery,
|
|
61
|
+
sequenceNumber: ble.sequenceNumber,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async onLockNotification(handler) {
|
|
65
|
+
if (!this.hasBLE()) {
|
|
66
|
+
throw new Error('BLE not available for lock notifications');
|
|
67
|
+
}
|
|
68
|
+
const mac = this.info.mac ?? `id:${this.info.bleId}`;
|
|
69
|
+
await this.bleConnection.subscribeNotifications(mac, handler);
|
|
70
|
+
this.lockNotificationHandlers.add(handler);
|
|
71
|
+
}
|
|
72
|
+
offLockNotification(handler) {
|
|
73
|
+
if (!this.hasBLE()) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const mac = this.info.mac ?? `id:${this.info.bleId}`;
|
|
77
|
+
this.bleConnection?.unsubscribeNotifications(mac, handler);
|
|
78
|
+
this.lockNotificationHandlers.delete(handler);
|
|
79
|
+
}
|
|
25
80
|
/**
|
|
26
81
|
* Get device status
|
|
27
82
|
*/
|
|
@@ -43,7 +98,7 @@ export class WoSmartLock extends SwitchBotDevice {
|
|
|
43
98
|
}
|
|
44
99
|
// Fallback to BLE
|
|
45
100
|
if (this.hasBLE()) {
|
|
46
|
-
const bleData = await this.getBLEStatus();
|
|
101
|
+
const bleData = await this.getBLEStatus().catch(() => this.normalizeBLEStatusData(undefined));
|
|
47
102
|
return {
|
|
48
103
|
deviceId: this.info.id,
|
|
49
104
|
connectionType: 'ble',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-lock.js","sourceRoot":"","sources":["../../src/devices/wo-lock.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"wo-lock.js","sourceRoot":"","sources":["../../src/devices/wo-lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { PlugCommands, PlugStatus } from '../types/device.js';
|
|
2
|
-
import {
|
|
2
|
+
import { DeviceOverrideStateDuringConnection } from './device-override-state-during-connection.js';
|
|
3
3
|
/**
|
|
4
4
|
* Plug Mini (US) Device
|
|
5
5
|
*/
|
|
6
|
-
export declare class WoPlugMiniUS extends
|
|
6
|
+
export declare class WoPlugMiniUS extends DeviceOverrideStateDuringConnection implements PlugCommands {
|
|
7
7
|
/**
|
|
8
8
|
* Turn on
|
|
9
9
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-plug-mini-us.d.ts","sourceRoot":"","sources":["../../src/devices/wo-plug-mini-us.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGlE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wo-plug-mini-us.d.ts","sourceRoot":"","sources":["../../src/devices/wo-plug-mini-us.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGlE,OAAO,EAAE,mCAAmC,EAAE,MAAM,8CAA8C,CAAA;AAElG;;GAEG;AACH,qBAAa,YAAa,SAAQ,mCAAoC,YAAW,YAAY;IAC3F;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAQhC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAQjC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAQhC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;CAmCvC"}
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* devices/wo-plug-mini-us.ts: SwitchBot v4.0.0 - Plug Mini (US)
|
|
4
4
|
*/
|
|
5
5
|
import { DEVICE_COMMANDS } from '../settings.js';
|
|
6
|
-
import {
|
|
6
|
+
import { DeviceOverrideStateDuringConnection } from './device-override-state-during-connection.js';
|
|
7
7
|
/**
|
|
8
8
|
* Plug Mini (US) Device
|
|
9
9
|
*/
|
|
10
|
-
export class WoPlugMiniUS extends
|
|
10
|
+
export class WoPlugMiniUS extends DeviceOverrideStateDuringConnection {
|
|
11
11
|
/**
|
|
12
12
|
* Turn on
|
|
13
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-plug-mini-us.js","sourceRoot":"","sources":["../../src/devices/wo-plug-mini-us.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wo-plug-mini-us.js","sourceRoot":"","sources":["../../src/devices/wo-plug-mini-us.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,mCAAmC,EAAE,MAAM,8CAA8C,CAAA;AAElG;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,mCAAmC;IACnE;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CACnC,eAAe,CAAC,IAAI,CAAC,OAAO,EAC5B,QAAQ,CACT,CAAA;QACD,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CACnC,eAAe,CAAC,IAAI,CAAC,QAAQ,EAC7B,SAAS,CACV,CAAA;QACD,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CACnC,eAAe,CAAC,IAAI,CAAC,MAAM,EAC3B,QAAQ,CACT,CAAA;QACD,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,6BAA6B;YAC7B,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;gBAC3C,OAAO;oBACL,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;oBACtB,cAAc,EAAE,KAAK;oBACrB,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,KAAK;oBAC/B,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,eAAe,EAAE,SAAS,CAAC,eAAe;oBAC1C,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;oBAC5C,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAA;YACH,CAAC;YAED,kBAAkB;YAClB,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;gBACzC,OAAO;oBACL,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;oBACtB,cAAc,EAAE,KAAK;oBACrB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;oBACnC,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAA;YACH,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAA;YAChD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { RelaySwitchCommands, RelaySwitchStatus } from '../types/device.js';
|
|
2
|
-
import {
|
|
2
|
+
import { SequenceDevice } from './sequence-device.js';
|
|
3
3
|
/**
|
|
4
4
|
* Relay Switch 1 Device (1-channel)
|
|
5
5
|
*/
|
|
6
|
-
export declare class WoRelaySwitch1 extends
|
|
6
|
+
export declare class WoRelaySwitch1 extends SequenceDevice implements RelaySwitchCommands {
|
|
7
|
+
private parseRelayPowerResponse;
|
|
8
|
+
private getRelayPowerMonitoring;
|
|
7
9
|
/**
|
|
8
10
|
* Turn on
|
|
9
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-relay-switch-1.d.ts","sourceRoot":"","sources":["../../src/devices/wo-relay-switch-1.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"wo-relay-switch-1.d.ts","sourceRoot":"","sources":["../../src/devices/wo-relay-switch-1.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAKhF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD;;GAEG;AACH,qBAAa,cAAe,SAAQ,cAAe,YAAW,mBAAmB;IAC/E,OAAO,CAAC,uBAAuB;YAqBjB,uBAAuB;IAiBrC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAQhC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAQjC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAQhC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC;CA0C9C"}
|
|
@@ -2,12 +2,37 @@
|
|
|
2
2
|
*
|
|
3
3
|
* devices/wo-relay-switch-1.ts: SwitchBot v4.0.0 - Relay Switch 1 Device
|
|
4
4
|
*/
|
|
5
|
+
import { Buffer } from 'node:buffer';
|
|
5
6
|
import { DEVICE_COMMANDS } from '../settings.js';
|
|
6
|
-
import {
|
|
7
|
+
import { SequenceDevice } from './sequence-device.js';
|
|
7
8
|
/**
|
|
8
9
|
* Relay Switch 1 Device (1-channel)
|
|
9
10
|
*/
|
|
10
|
-
export class WoRelaySwitch1 extends
|
|
11
|
+
export class WoRelaySwitch1 extends SequenceDevice {
|
|
12
|
+
parseRelayPowerResponse(buffer) {
|
|
13
|
+
if (!buffer || buffer.length < 11) {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
// Best-effort parsing aligned with relay basic-info responses.
|
|
17
|
+
const voltageRaw = buffer.readUInt16BE(5);
|
|
18
|
+
const currentRaw = buffer.readUInt16BE(7);
|
|
19
|
+
const energyRaw = buffer.readUInt16BE(9);
|
|
20
|
+
return {
|
|
21
|
+
voltage: voltageRaw / 10,
|
|
22
|
+
electricCurrent: currentRaw / 100,
|
|
23
|
+
electricityOfDay: energyRaw / 100,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async getRelayPowerMonitoring() {
|
|
27
|
+
if (!this.hasBLE()) {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
const result = await this.sendBLECommand(DEVICE_COMMANDS.RELAY.GET_BASIC_INFO);
|
|
31
|
+
if (!result.success || !result.data || !Buffer.isBuffer(result.data)) {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
return this.parseRelayPowerResponse(result.data);
|
|
35
|
+
}
|
|
11
36
|
/**
|
|
12
37
|
* Turn on
|
|
13
38
|
*/
|
|
@@ -50,12 +75,19 @@ export class WoRelaySwitch1 extends SwitchBotDevice {
|
|
|
50
75
|
}
|
|
51
76
|
// Fallback to BLE
|
|
52
77
|
if (this.hasBLE()) {
|
|
53
|
-
const bleData = await this.getBLEStatus();
|
|
78
|
+
const bleData = await this.getBLEStatus().catch(() => this.normalizeBLEStatusData(undefined));
|
|
79
|
+
const power = await this.getRelayPowerMonitoring().catch(() => ({
|
|
80
|
+
voltage: undefined,
|
|
81
|
+
electricCurrent: undefined,
|
|
82
|
+
electricityOfDay: undefined,
|
|
83
|
+
}));
|
|
54
84
|
return {
|
|
55
85
|
deviceId: this.info.id,
|
|
56
86
|
connectionType: 'ble',
|
|
57
87
|
power: bleData.state ? 'on' : 'off',
|
|
58
|
-
voltage: bleData.voltage,
|
|
88
|
+
voltage: power.voltage ?? bleData.voltage,
|
|
89
|
+
electricCurrent: power.electricCurrent,
|
|
90
|
+
electricityOfDay: power.electricityOfDay,
|
|
59
91
|
updatedAt: new Date(),
|
|
60
92
|
};
|
|
61
93
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wo-relay-switch-1.js","sourceRoot":"","sources":["../../src/devices/wo-relay-switch-1.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wo-relay-switch-1.js","sourceRoot":"","sources":["../../src/devices/wo-relay-switch-1.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { RelaySwitchChannelCommands, RelaySwitchStatus } from '../types/device.js';
|
|
2
|
+
import { WoRelaySwitch1 } from './wo-relay-switch-1.js';
|
|
3
|
+
/**
|
|
4
|
+
* Relay Switch 2PM Device (2-channel with power monitoring)
|
|
5
|
+
* Extends Relay Switch 1 with channel-specific control
|
|
6
|
+
*/
|
|
7
|
+
export declare class WoRelaySwitch2PM extends WoRelaySwitch1 implements RelaySwitchChannelCommands {
|
|
8
|
+
/**
|
|
9
|
+
* Set channel 1 state
|
|
10
|
+
*/
|
|
11
|
+
setChannel1(state: boolean): Promise<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* Set channel 2 state
|
|
14
|
+
*/
|
|
15
|
+
setChannel2(state: boolean): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Get device status (inherited, same as 1PM)
|
|
18
|
+
*/
|
|
19
|
+
getStatus(): Promise<RelaySwitchStatus>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=wo-relay-switch-2pm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wo-relay-switch-2pm.d.ts","sourceRoot":"","sources":["../../src/devices/wo-relay-switch-2pm.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAGvF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvD;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,cAAe,YAAW,0BAA0B;IACxF;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IASnD;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IASnD;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC;CAG9C"}
|