33 * devices/wo-lock-pro.ts: SwitchBot v4.0.0 - Smart Lock Pro Device
44 */
55
6+ import type { Buffer } from 'node:buffer'
7+
68import type { LockCommands , LockStatus } from '../types/device.js'
79
810import { WoSmartLockProCommands } from '../settings.js'
@@ -12,10 +14,21 @@ import { SwitchBotDevice } from './base.js'
1214 * Smart Lock Pro Device (with unlatch support)
1315 */
1416export class WoSmartLockPro extends SwitchBotDevice implements LockCommands {
17+ private lockNotificationHandlers = new Set < ( payload : Buffer ) => void > ( )
18+
1519 /**
1620 * Lock the lock
1721 */
1822 async lock ( ) : Promise < boolean > {
23+ try {
24+ const status = await this . getStatus ( )
25+ if ( status . lockState === 'locked' ) {
26+ return true
27+ }
28+ } catch {
29+ // Best effort status check before command
30+ }
31+
1932 const result = await this . sendCommand (
2033 WoSmartLockProCommands . LOCK ,
2134 'lock' ,
@@ -27,13 +40,34 @@ export class WoSmartLockPro extends SwitchBotDevice implements LockCommands {
2740 * Unlock the lock
2841 */
2942 async unlock ( ) : Promise < boolean > {
43+ try {
44+ const status = await this . getStatus ( )
45+ if ( status . lockState === 'unlocked' ) {
46+ return true
47+ }
48+ } catch {
49+ // Best effort status check before command
50+ }
51+
3052 const result = await this . sendCommand (
3153 WoSmartLockProCommands . UNLOCK ,
3254 'unlock' ,
3355 )
3456 return result . success
3557 }
3658
59+ /**
60+ * Unlock without unlatching the door
61+ */
62+ async unlockWithoutUnlatch ( ) : Promise < boolean > {
63+ const result = await this . sendCommand (
64+ WoSmartLockProCommands . UNLOCK ,
65+ 'unlock' ,
66+ 'withoutUnlatch' ,
67+ )
68+ return result . success
69+ }
70+
3771 /**
3872 * Unlatch the lock (Lock Pro only)
3973 */
@@ -45,6 +79,48 @@ export class WoSmartLockPro extends SwitchBotDevice implements LockCommands {
4579 return result . success
4680 }
4781
82+ async getLockInfo ( ) : Promise < Record < string , unknown > > {
83+ if ( this . hasAPI ( ) ) {
84+ const status = await this . getAPIStatus ( )
85+ return {
86+ lockState : status . lockState ,
87+ doorState : status . doorState ,
88+ calibrate : status . calibrate ,
89+ battery : status . battery ,
90+ version : status . version ,
91+ }
92+ }
93+
94+ const ble = await this . getBLEStatus ( ) . catch ( ( ) => this . normalizeBLEStatusData ( undefined ) )
95+ return {
96+ lockState : ble . lockState ,
97+ doorOpen : ble . doorOpen ,
98+ calibration : ble . calibration ,
99+ battery : ble . battery ,
100+ sequenceNumber : ble . sequenceNumber ,
101+ }
102+ }
103+
104+ async onLockNotification ( handler : ( payload : Buffer ) => void ) : Promise < void > {
105+ if ( ! this . hasBLE ( ) ) {
106+ throw new Error ( 'BLE not available for lock notifications' )
107+ }
108+
109+ const mac = this . info . mac ?? `id:${ this . info . bleId } `
110+ await this . bleConnection ! . subscribeNotifications ( mac , handler )
111+ this . lockNotificationHandlers . add ( handler )
112+ }
113+
114+ offLockNotification ( handler : ( payload : Buffer ) => void ) : void {
115+ if ( ! this . hasBLE ( ) ) {
116+ return
117+ }
118+
119+ const mac = this . info . mac ?? `id:${ this . info . bleId } `
120+ this . bleConnection ?. unsubscribeNotifications ( mac , handler )
121+ this . lockNotificationHandlers . delete ( handler )
122+ }
123+
48124 /**
49125 * Get device status
50126 */
0 commit comments