@switchbot/homebridge-switchbot 3.7.1-beta.8 → 3.8.0
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/CHANGELOG.md +8 -2
- package/README.md +14 -0
- package/assets/security-privacy-bluetooth.png +0 -0
- package/config.schema.json +78 -3
- package/dist/device/blindtilt.d.ts +18 -8
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +108 -70
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +9 -9
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +143 -170
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +13 -13
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +38 -73
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +12 -12
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +41 -79
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +5 -5
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +20 -42
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +15 -5
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +127 -81
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +18 -18
- package/dist/device/device.d.ts.map +1 -1
- package/dist/device/device.js +33 -36
- package/dist/device/device.js.map +1 -1
- package/dist/device/fan.d.ts +8 -8
- package/dist/device/fan.d.ts.map +1 -1
- package/dist/device/fan.js +43 -75
- package/dist/device/fan.js.map +1 -1
- package/dist/device/hub.d.ts +5 -5
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +18 -39
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +5 -5
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +38 -78
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +5 -5
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +21 -40
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +6 -6
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +34 -73
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +9 -9
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +37 -52
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +5 -5
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +21 -39
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +5 -5
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +21 -38
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +5 -5
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +14 -32
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +12 -12
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +16 -25
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +11 -11
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +42 -56
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +5 -5
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +47 -44
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/homebridge-ui/server.js +2 -2
- package/dist/homebridge-ui/server.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +8 -8
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +61 -105
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +10 -10
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +22 -42
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +9 -9
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +15 -25
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +8 -8
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +21 -40
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +11 -11
- package/dist/irdevice/irdevice.d.ts.map +1 -1
- package/dist/irdevice/irdevice.js +14 -22
- package/dist/irdevice/irdevice.js.map +1 -1
- package/dist/irdevice/light.d.ts +9 -9
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +24 -47
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +9 -9
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +40 -83
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +9 -9
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +29 -54
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +5 -5
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +11 -21
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +5 -5
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +11 -22
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +24 -23
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +471 -715
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +6 -3
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/types/bledevicestatus.d.ts +9 -9
- package/dist/types/bledevicestatus.d.ts.map +1 -1
- package/dist/types/devicelist.d.ts +6 -6
- package/dist/types/devicelist.d.ts.map +1 -1
- package/dist/types/deviceresponse.d.ts +4 -4
- package/dist/types/deviceresponse.d.ts.map +1 -1
- package/dist/types/devicestatus.d.ts +2 -2
- package/dist/types/devicestatus.d.ts.map +1 -1
- package/dist/types/devicewebhookstatus.d.ts +5 -5
- package/dist/types/devicewebhookstatus.d.ts.map +1 -1
- package/dist/types/irdevicelist.d.ts +4 -4
- package/dist/types/irdevicelist.d.ts.map +1 -1
- package/dist/types/pushbody.d.ts +2 -2
- package/dist/types/pushbody.d.ts.map +1 -1
- package/dist/utils.d.ts +4 -4
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +9 -13
- package/dist/utils.js.map +1 -1
- package/eslint.config.js +48 -93
- package/package.json +62 -55
- package/src/device/blindtilt.ts +509 -460
- package/src/device/bot.ts +696 -718
- package/src/device/ceilinglight.ts +331 -364
- package/src/device/colorbulb.ts +412 -448
- package/src/device/contact.ts +200 -221
- package/src/device/curtain.ts +506 -444
- package/src/device/device.ts +206 -208
- package/src/device/fan.ts +307 -340
- package/src/device/hub.ts +184 -209
- package/src/device/humidifier.ts +297 -342
- package/src/device/iosensor.ts +182 -204
- package/src/device/lightstrip.ts +362 -399
- package/src/device/lock.ts +262 -276
- package/src/device/meter.ts +183 -205
- package/src/device/meterplus.ts +183 -204
- package/src/device/motion.ts +169 -185
- package/src/device/plug.ts +174 -177
- package/src/device/robotvacuumcleaner.ts +256 -269
- package/src/device/waterdetector.ts +185 -185
- package/src/homebridge-ui/server.ts +16 -15
- package/src/index.ts +5 -6
- package/src/irdevice/airconditioner.ts +277 -326
- package/src/irdevice/airpurifier.ts +124 -143
- package/src/irdevice/camera.ts +58 -64
- package/src/irdevice/fan.ts +106 -123
- package/src/irdevice/irdevice.ts +116 -119
- package/src/irdevice/light.ts +119 -143
- package/src/irdevice/other.ts +417 -461
- package/src/irdevice/tv.ts +155 -177
- package/src/irdevice/vacuumcleaner.ts +54 -60
- package/src/irdevice/waterheater.ts +56 -63
- package/src/platform.ts +1467 -1683
- package/src/settings.ts +173 -170
- package/src/types/bledevicestatus.ts +252 -256
- package/src/types/devicelist.ts +79 -79
- package/src/types/deviceresponse.ts +12 -13
- package/src/types/devicestatus.ts +124 -124
- package/src/types/devicewebhookstatus.ts +126 -131
- package/src/types/irdevicelist.ts +10 -10
- package/src/types/pushbody.ts +5 -5
- package/src/utils.ts +64 -65
- package/tsconfig.json +10 -9
- package/.github/npm-version-script.cjs +0 -81
package/src/device/lock.ts
CHANGED
|
@@ -2,313 +2,307 @@
|
|
|
2
2
|
*
|
|
3
3
|
* lock.ts: @switchbot/homebridge-switchbot.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
|
|
6
|
+
|
|
7
|
+
import type { SwitchBotPlatform } from '../platform.js'
|
|
8
|
+
import type { devicesConfig } from '../settings.js'
|
|
9
|
+
import type { lockProServiceData, lockServiceData } from '../types/bledevicestatus.js'
|
|
10
|
+
import type { device } from '../types/devicelist.js'
|
|
11
|
+
import type { lockProStatus, lockStatus } from '../types/devicestatus.js'
|
|
12
|
+
import type { lockProWebhookContext, lockWebhookContext } from '../types/devicewebhookstatus.js'
|
|
13
|
+
|
|
6
14
|
/*
|
|
7
15
|
* For Testing Locally:
|
|
8
16
|
* import { SwitchBotBLEModel, SwitchBotBLEModelName } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
|
|
9
17
|
*/
|
|
10
|
-
import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot'
|
|
11
|
-
import {
|
|
18
|
+
import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot'
|
|
19
|
+
import { debounceTime, interval, skipWhile, Subject, take, tap } from 'rxjs'
|
|
12
20
|
|
|
13
|
-
import
|
|
14
|
-
import type { device } from '../types/devicelist.js';
|
|
15
|
-
import type { SwitchBotPlatform } from '../platform.js';
|
|
16
|
-
import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
17
|
-
import type { lockServiceData, lockProServiceData } from '../types/bledevicestatus.js';
|
|
18
|
-
import type { lockStatus, lockProStatus } from '../types/devicestatus.js';
|
|
19
|
-
import type { lockProWebhookContext, lockWebhookContext } from '../types/devicewebhookstatus.js';
|
|
21
|
+
import { deviceBase } from './device.js'
|
|
20
22
|
|
|
21
23
|
export class Lock extends deviceBase {
|
|
22
24
|
// Services
|
|
23
25
|
private LockMechanism: {
|
|
24
|
-
Name: CharacteristicValue
|
|
25
|
-
Service: Service
|
|
26
|
-
LockTargetState: CharacteristicValue
|
|
27
|
-
LockCurrentState: CharacteristicValue
|
|
28
|
-
}
|
|
26
|
+
Name: CharacteristicValue
|
|
27
|
+
Service: Service
|
|
28
|
+
LockTargetState: CharacteristicValue
|
|
29
|
+
LockCurrentState: CharacteristicValue
|
|
30
|
+
}
|
|
29
31
|
|
|
30
32
|
private Battery: {
|
|
31
|
-
Name: CharacteristicValue
|
|
32
|
-
Service: Service
|
|
33
|
-
BatteryLevel: CharacteristicValue
|
|
34
|
-
StatusLowBattery: CharacteristicValue
|
|
35
|
-
}
|
|
33
|
+
Name: CharacteristicValue
|
|
34
|
+
Service: Service
|
|
35
|
+
BatteryLevel: CharacteristicValue
|
|
36
|
+
StatusLowBattery: CharacteristicValue
|
|
37
|
+
}
|
|
36
38
|
|
|
37
39
|
private ContactSensor?: {
|
|
38
|
-
Name: CharacteristicValue
|
|
39
|
-
Service: Service
|
|
40
|
-
ContactSensorState: CharacteristicValue
|
|
41
|
-
}
|
|
40
|
+
Name: CharacteristicValue
|
|
41
|
+
Service: Service
|
|
42
|
+
ContactSensorState: CharacteristicValue
|
|
43
|
+
}
|
|
42
44
|
|
|
43
45
|
private Switch?: {
|
|
44
|
-
Name: CharacteristicValue
|
|
45
|
-
Service: Service
|
|
46
|
-
On: CharacteristicValue
|
|
47
|
-
}
|
|
46
|
+
Name: CharacteristicValue
|
|
47
|
+
Service: Service
|
|
48
|
+
On: CharacteristicValue
|
|
49
|
+
}
|
|
48
50
|
|
|
49
51
|
// OpenAPI
|
|
50
|
-
deviceStatus!: lockStatus | lockProStatus
|
|
52
|
+
deviceStatus!: lockStatus | lockProStatus
|
|
51
53
|
|
|
52
|
-
//Webhook
|
|
53
|
-
webhookContext!: lockWebhookContext | lockProWebhookContext
|
|
54
|
+
// Webhook
|
|
55
|
+
webhookContext!: lockWebhookContext | lockProWebhookContext
|
|
54
56
|
|
|
55
57
|
// BLE
|
|
56
|
-
serviceData!: lockServiceData | lockProServiceData
|
|
58
|
+
serviceData!: lockServiceData | lockProServiceData
|
|
57
59
|
|
|
58
60
|
// Updates
|
|
59
|
-
lockUpdateInProgress!: boolean
|
|
60
|
-
doLockUpdate!: Subject<void
|
|
61
|
+
lockUpdateInProgress!: boolean
|
|
62
|
+
doLockUpdate!: Subject<void>
|
|
61
63
|
|
|
62
64
|
constructor(
|
|
63
65
|
readonly platform: SwitchBotPlatform,
|
|
64
66
|
accessory: PlatformAccessory,
|
|
65
67
|
device: device & devicesConfig,
|
|
66
68
|
) {
|
|
67
|
-
super(platform, accessory, device)
|
|
69
|
+
super(platform, accessory, device)
|
|
68
70
|
// Set category
|
|
69
|
-
accessory.category = this.hap.Categories.DOOR_LOCK
|
|
71
|
+
accessory.category = this.hap.Categories.DOOR_LOCK
|
|
70
72
|
|
|
71
73
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
72
|
-
this.doLockUpdate = new Subject()
|
|
73
|
-
this.lockUpdateInProgress = false
|
|
74
|
+
this.doLockUpdate = new Subject()
|
|
75
|
+
this.lockUpdateInProgress = false
|
|
74
76
|
|
|
75
77
|
// Initialize LockMechanism Service
|
|
76
|
-
accessory.context.LockMechanism = accessory.context.LockMechanism ?? {}
|
|
78
|
+
accessory.context.LockMechanism = accessory.context.LockMechanism ?? {}
|
|
77
79
|
this.LockMechanism = {
|
|
78
80
|
Name: accessory.displayName,
|
|
79
81
|
Service: accessory.getService(this.hap.Service.LockMechanism) ?? accessory.addService(this.hap.Service.LockMechanism) as Service,
|
|
80
82
|
LockTargetState: accessory.context.LockTargetState ?? this.hap.Characteristic.LockTargetState.SECURED,
|
|
81
83
|
LockCurrentState: accessory.context.LockCurrentState ?? this.hap.Characteristic.LockCurrentState.SECURED,
|
|
82
|
-
}
|
|
83
|
-
accessory.context.LockMechanism = this.LockMechanism as object
|
|
84
|
+
}
|
|
85
|
+
accessory.context.LockMechanism = this.LockMechanism as object
|
|
84
86
|
|
|
85
87
|
// Initialize LockMechanism Characteristics
|
|
86
|
-
this.LockMechanism.Service
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
.onGet(() => {
|
|
90
|
-
return this.LockMechanism.LockTargetState;
|
|
91
|
-
})
|
|
92
|
-
.onSet(this.LockTargetStateSet.bind(this));
|
|
88
|
+
this.LockMechanism.Service.setCharacteristic(this.hap.Characteristic.Name, this.LockMechanism.Name).getCharacteristic(this.hap.Characteristic.LockTargetState).onGet(() => {
|
|
89
|
+
return this.LockMechanism.LockTargetState
|
|
90
|
+
}).onSet(this.LockTargetStateSet.bind(this))
|
|
93
91
|
|
|
94
92
|
// Initialize Battery property
|
|
95
|
-
accessory.context.Battery = accessory.context.Battery ?? {}
|
|
93
|
+
accessory.context.Battery = accessory.context.Battery ?? {}
|
|
96
94
|
this.Battery = {
|
|
97
95
|
Name: `${accessory.displayName} Battery`,
|
|
98
96
|
Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
|
|
99
97
|
BatteryLevel: accessory.context.BatteryLevel ?? 100,
|
|
100
98
|
StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
101
|
-
}
|
|
102
|
-
accessory.context.Battery = this.Battery as object
|
|
99
|
+
}
|
|
100
|
+
accessory.context.Battery = this.Battery as object
|
|
103
101
|
|
|
104
102
|
// Initialize Battery Characteristics
|
|
105
|
-
this.Battery.Service
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this.Battery.Service
|
|
114
|
-
.getCharacteristic(this.hap.Characteristic.StatusLowBattery)
|
|
115
|
-
.onGet(() => {
|
|
116
|
-
return this.Battery.StatusLowBattery;
|
|
117
|
-
});
|
|
103
|
+
this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name).setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE).getCharacteristic(this.hap.Characteristic.BatteryLevel).onGet(() => {
|
|
104
|
+
return this.Battery.BatteryLevel
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
this.Battery.Service.getCharacteristic(this.hap.Characteristic.StatusLowBattery).onGet(() => {
|
|
108
|
+
return this.Battery.StatusLowBattery
|
|
109
|
+
})
|
|
118
110
|
|
|
119
111
|
// Contact Sensor Service
|
|
120
112
|
if (device.lock?.hide_contactsensor) {
|
|
121
113
|
if (this.ContactSensor) {
|
|
122
|
-
this.debugLog('Removing Contact Sensor Service')
|
|
123
|
-
this.ContactSensor.Service = this.accessory.getService(this.hap.Service.ContactSensor) as Service
|
|
124
|
-
accessory.removeService(this.ContactSensor.Service)
|
|
114
|
+
this.debugLog('Removing Contact Sensor Service')
|
|
115
|
+
this.ContactSensor.Service = this.accessory.getService(this.hap.Service.ContactSensor) as Service
|
|
116
|
+
accessory.removeService(this.ContactSensor.Service)
|
|
125
117
|
}
|
|
126
118
|
} else {
|
|
127
|
-
accessory.context.ContactSensor = accessory.context.ContactSensor ?? {}
|
|
119
|
+
accessory.context.ContactSensor = accessory.context.ContactSensor ?? {}
|
|
128
120
|
this.ContactSensor = {
|
|
129
121
|
Name: `${accessory.displayName} Contact Sensor`,
|
|
130
122
|
Service: accessory.getService(this.hap.Service.ContactSensor) ?? this.accessory.addService(this.hap.Service.ContactSensor) as Service,
|
|
131
123
|
ContactSensorState: accessory.context.ContactSensorState ?? this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED,
|
|
132
|
-
}
|
|
133
|
-
accessory.context.ContactSensor = this.ContactSensor as object
|
|
124
|
+
}
|
|
125
|
+
accessory.context.ContactSensor = this.ContactSensor as object
|
|
134
126
|
|
|
135
127
|
// Initialize Contact Sensor Characteristics
|
|
136
|
-
this.ContactSensor.Service
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
.getCharacteristic(this.hap.Characteristic.ContactSensorState)
|
|
140
|
-
.onGet(() => {
|
|
141
|
-
return this.ContactSensor!.ContactSensorState;
|
|
142
|
-
});
|
|
128
|
+
this.ContactSensor.Service.setCharacteristic(this.hap.Characteristic.Name, this.ContactSensor.Name).setCharacteristic(this.hap.Characteristic.StatusActive, true).getCharacteristic(this.hap.Characteristic.ContactSensorState).onGet(() => {
|
|
129
|
+
return this.ContactSensor!.ContactSensorState
|
|
130
|
+
})
|
|
143
131
|
}
|
|
144
132
|
|
|
145
133
|
// Initialize Latch Button Service
|
|
146
134
|
if (device.lock?.activate_latchbutton === false) {
|
|
147
135
|
if (this.Switch) {
|
|
148
|
-
this.debugLog('Removing Latch Button Service')
|
|
149
|
-
this.Switch.Service = accessory.getService(this.hap.Service.Switch) as Service
|
|
150
|
-
accessory.removeService(this.Switch.Service)
|
|
136
|
+
this.debugLog('Removing Latch Button Service')
|
|
137
|
+
this.Switch.Service = accessory.getService(this.hap.Service.Switch) as Service
|
|
138
|
+
accessory.removeService(this.Switch.Service)
|
|
151
139
|
}
|
|
152
140
|
} else {
|
|
153
|
-
accessory.context.Switch = accessory.context.Switch ?? {}
|
|
141
|
+
accessory.context.Switch = accessory.context.Switch ?? {}
|
|
154
142
|
this.Switch = {
|
|
155
143
|
Name: `${accessory.displayName} Latch`,
|
|
156
144
|
Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
|
|
157
145
|
On: accessory.context.On ?? false,
|
|
158
|
-
}
|
|
159
|
-
accessory.context.Switch = this.Switch as object
|
|
146
|
+
}
|
|
147
|
+
accessory.context.Switch = this.Switch as object
|
|
160
148
|
|
|
161
149
|
// Initialize Latch Button Characteristics
|
|
162
|
-
this.Switch.Service
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
.onGet(() => {
|
|
166
|
-
return this.Switch!.On;
|
|
167
|
-
})
|
|
168
|
-
.onSet(this.OnSet.bind(this));
|
|
150
|
+
this.Switch.Service.setCharacteristic(this.hap.Characteristic.Name, this.Switch.Name).getCharacteristic(this.hap.Characteristic.On).onGet(() => {
|
|
151
|
+
return this.Switch!.On
|
|
152
|
+
}).onSet(this.OnSet.bind(this))
|
|
169
153
|
}
|
|
170
154
|
|
|
171
155
|
// Retrieve initial values and updateHomekit
|
|
172
156
|
try {
|
|
173
|
-
this.debugLog('Retrieve initial values and update Homekit')
|
|
174
|
-
this.refreshStatus()
|
|
157
|
+
this.debugLog('Retrieve initial values and update Homekit')
|
|
158
|
+
this.refreshStatus()
|
|
175
159
|
} catch (e: any) {
|
|
176
|
-
this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e}`)
|
|
160
|
+
this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e}`)
|
|
177
161
|
}
|
|
178
162
|
|
|
179
|
-
//regisiter webhook event handler if enabled
|
|
163
|
+
// regisiter webhook event handler if enabled
|
|
180
164
|
try {
|
|
181
|
-
this.debugLog('Registering Webhook Event Handler')
|
|
182
|
-
this.registerWebhook()
|
|
165
|
+
this.debugLog('Registering Webhook Event Handler')
|
|
166
|
+
this.registerWebhook()
|
|
183
167
|
} catch (e: any) {
|
|
184
|
-
this.errorLog(`failed to registerWebhook, Error: ${e}`)
|
|
168
|
+
this.errorLog(`failed to registerWebhook, Error: ${e}`)
|
|
185
169
|
}
|
|
186
170
|
|
|
187
|
-
//regisiter platform BLE event handler if enabled
|
|
171
|
+
// regisiter platform BLE event handler if enabled
|
|
188
172
|
try {
|
|
189
|
-
this.debugLog('Registering Platform BLE Event Handler')
|
|
190
|
-
this.registerPlatformBLE()
|
|
173
|
+
this.debugLog('Registering Platform BLE Event Handler')
|
|
174
|
+
this.registerPlatformBLE()
|
|
191
175
|
} catch (e: any) {
|
|
192
|
-
this.errorLog(`failed to registerPlatformBLE, Error: ${e}`)
|
|
176
|
+
this.errorLog(`failed to registerPlatformBLE, Error: ${e}`)
|
|
193
177
|
}
|
|
194
178
|
|
|
195
179
|
// Start an update interval
|
|
196
180
|
interval(this.deviceRefreshRate * 1000)
|
|
197
181
|
.pipe(skipWhile(() => this.lockUpdateInProgress))
|
|
198
182
|
.subscribe(async () => {
|
|
199
|
-
await this.refreshStatus()
|
|
200
|
-
})
|
|
183
|
+
await this.refreshStatus()
|
|
184
|
+
})
|
|
201
185
|
|
|
202
186
|
// Watch for Lock change events
|
|
203
187
|
// We put in a debounce of 100ms so we don't make duplicate calls
|
|
204
188
|
this.doLockUpdate
|
|
205
189
|
.pipe(
|
|
206
190
|
tap(() => {
|
|
207
|
-
this.lockUpdateInProgress = true
|
|
191
|
+
this.lockUpdateInProgress = true
|
|
208
192
|
}),
|
|
209
193
|
debounceTime(this.devicePushRate * 1000),
|
|
210
194
|
)
|
|
211
195
|
.subscribe(async () => {
|
|
212
196
|
try {
|
|
213
|
-
await this.pushChanges()
|
|
197
|
+
await this.pushChanges()
|
|
214
198
|
} catch (e: any) {
|
|
215
|
-
await this.apiError(e)
|
|
216
|
-
await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
199
|
+
await this.apiError(e)
|
|
200
|
+
await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
217
201
|
}
|
|
218
|
-
this.lockUpdateInProgress = false
|
|
219
|
-
})
|
|
202
|
+
this.lockUpdateInProgress = false
|
|
203
|
+
})
|
|
220
204
|
}
|
|
221
205
|
|
|
222
206
|
async BLEparseStatus(): Promise<void> {
|
|
223
|
-
await this.debugLog('BLEparseStatus')
|
|
224
|
-
await this.debugLog(`(lockState) = BLE:(${this.serviceData.status}), current:(${this.LockMechanism.LockCurrentState})`)
|
|
207
|
+
await this.debugLog('BLEparseStatus')
|
|
208
|
+
await this.debugLog(`(lockState) = BLE:(${this.serviceData.status}), current:(${this.LockMechanism.LockCurrentState})`)
|
|
225
209
|
|
|
226
210
|
// LockCurrentState
|
|
227
211
|
this.LockMechanism.LockCurrentState = this.serviceData.status === 'locked'
|
|
228
|
-
? this.hap.Characteristic.LockCurrentState.SECURED
|
|
229
|
-
|
|
212
|
+
? this.hap.Characteristic.LockCurrentState.SECURED
|
|
213
|
+
: this.hap.Characteristic.LockCurrentState.UNSECURED
|
|
214
|
+
await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`)
|
|
230
215
|
|
|
231
216
|
// LockTargetState
|
|
232
217
|
this.LockMechanism.LockTargetState = this.serviceData.status === 'locked'
|
|
233
|
-
? this.hap.Characteristic.LockTargetState.SECURED
|
|
234
|
-
|
|
218
|
+
? this.hap.Characteristic.LockTargetState.SECURED
|
|
219
|
+
: this.hap.Characteristic.LockTargetState.UNSECURED
|
|
220
|
+
await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`)
|
|
235
221
|
|
|
236
222
|
// Contact Sensor
|
|
237
223
|
if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
|
|
238
224
|
this.ContactSensor.ContactSensorState = this.serviceData.door_open === 'opened'
|
|
239
|
-
? this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
|
|
240
|
-
|
|
225
|
+
? this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
|
|
226
|
+
: this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED
|
|
227
|
+
await this.debugLog(`ContactSensorState: ${this.ContactSensor.ContactSensorState}`)
|
|
241
228
|
}
|
|
242
229
|
|
|
243
230
|
// BatteryLevel
|
|
244
|
-
this.Battery.BatteryLevel = this.serviceData.battery
|
|
245
|
-
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
231
|
+
this.Battery.BatteryLevel = this.serviceData.battery
|
|
232
|
+
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
246
233
|
|
|
247
234
|
// StatusLowBattery
|
|
248
235
|
this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
|
|
249
|
-
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
250
|
-
|
|
236
|
+
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
237
|
+
: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
|
|
238
|
+
await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
|
|
251
239
|
}
|
|
252
240
|
|
|
253
241
|
async openAPIparseStatus(): Promise<void> {
|
|
254
|
-
await this.debugLog('openAPIparseStatus')
|
|
255
|
-
await this.debugLog(`(lockState) = OpenAPI:(${this.deviceStatus.lockState}), current:(${this.LockMechanism.LockCurrentState})`)
|
|
242
|
+
await this.debugLog('openAPIparseStatus')
|
|
243
|
+
await this.debugLog(`(lockState) = OpenAPI:(${this.deviceStatus.lockState}), current:(${this.LockMechanism.LockCurrentState})`)
|
|
256
244
|
|
|
257
245
|
// LockCurrentState
|
|
258
246
|
this.LockMechanism.LockCurrentState = this.deviceStatus.lockState === 'locked'
|
|
259
|
-
? this.hap.Characteristic.LockCurrentState.SECURED
|
|
260
|
-
|
|
247
|
+
? this.hap.Characteristic.LockCurrentState.SECURED
|
|
248
|
+
: this.hap.Characteristic.LockCurrentState.UNSECURED
|
|
249
|
+
await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`)
|
|
261
250
|
|
|
262
251
|
// LockTargetState
|
|
263
252
|
this.LockMechanism.LockTargetState = this.deviceStatus.lockState === 'locked'
|
|
264
|
-
? this.hap.Characteristic.LockTargetState.SECURED
|
|
265
|
-
|
|
253
|
+
? this.hap.Characteristic.LockTargetState.SECURED
|
|
254
|
+
: this.hap.Characteristic.LockTargetState.UNSECURED
|
|
255
|
+
await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`)
|
|
266
256
|
|
|
267
257
|
// ContactSensorState
|
|
268
258
|
if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
|
|
269
259
|
this.ContactSensor.ContactSensorState = this.deviceStatus.doorState === 'opened'
|
|
270
|
-
? this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
|
|
271
|
-
|
|
260
|
+
? this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
|
|
261
|
+
: this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED
|
|
262
|
+
await this.debugLog(`ContactSensorState: ${this.ContactSensor.ContactSensorState}`)
|
|
272
263
|
}
|
|
273
264
|
|
|
274
265
|
// BatteryLevel
|
|
275
|
-
this.Battery.BatteryLevel = this.deviceStatus.battery
|
|
276
|
-
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
266
|
+
this.Battery.BatteryLevel = this.deviceStatus.battery
|
|
267
|
+
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
277
268
|
|
|
278
269
|
// StatusLowBattery
|
|
279
270
|
this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
|
|
280
|
-
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
281
|
-
|
|
271
|
+
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
272
|
+
: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
|
|
273
|
+
await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
|
|
282
274
|
|
|
283
275
|
// Firmware Version
|
|
284
276
|
if (this.deviceStatus.version) {
|
|
285
|
-
const version = this.deviceStatus.version.toString()
|
|
286
|
-
await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`)
|
|
287
|
-
const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0'
|
|
277
|
+
const version = this.deviceStatus.version.toString()
|
|
278
|
+
await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`)
|
|
279
|
+
const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0'
|
|
288
280
|
this.accessory
|
|
289
281
|
.getService(this.hap.Service.AccessoryInformation)!
|
|
290
282
|
.setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
|
|
291
283
|
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
|
|
292
284
|
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
293
|
-
.updateValue(deviceVersion)
|
|
294
|
-
this.accessory.context.version = deviceVersion
|
|
295
|
-
await this.debugSuccessLog(`version: ${this.accessory.context.version}`)
|
|
285
|
+
.updateValue(deviceVersion)
|
|
286
|
+
this.accessory.context.version = deviceVersion
|
|
287
|
+
await this.debugSuccessLog(`version: ${this.accessory.context.version}`)
|
|
296
288
|
}
|
|
297
289
|
}
|
|
298
290
|
|
|
299
291
|
async parseStatusWebhook(): Promise<void> {
|
|
300
|
-
await this.debugLog('parseStatusWebhook')
|
|
301
|
-
await this.debugLog(`(lockState) = Webhook:(${this.webhookContext.lockState}), current:(${this.LockMechanism.LockCurrentState})`)
|
|
292
|
+
await this.debugLog('parseStatusWebhook')
|
|
293
|
+
await this.debugLog(`(lockState) = Webhook:(${this.webhookContext.lockState}), current:(${this.LockMechanism.LockCurrentState})`)
|
|
302
294
|
|
|
303
295
|
// LockCurrentState
|
|
304
296
|
this.LockMechanism.LockCurrentState = this.webhookContext.lockState === 'LOCKED'
|
|
305
|
-
? this.hap.Characteristic.LockCurrentState.SECURED
|
|
306
|
-
|
|
297
|
+
? this.hap.Characteristic.LockCurrentState.SECURED
|
|
298
|
+
: this.hap.Characteristic.LockCurrentState.UNSECURED
|
|
299
|
+
await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`)
|
|
307
300
|
|
|
308
301
|
// LockTargetState
|
|
309
302
|
this.LockMechanism.LockTargetState = this.webhookContext.lockState === 'LOCKED'
|
|
310
|
-
? this.hap.Characteristic.LockTargetState.SECURED
|
|
311
|
-
|
|
303
|
+
? this.hap.Characteristic.LockTargetState.SECURED
|
|
304
|
+
: this.hap.Characteristic.LockTargetState.UNSECURED
|
|
305
|
+
await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`)
|
|
312
306
|
}
|
|
313
307
|
|
|
314
308
|
/**
|
|
@@ -316,132 +310,132 @@ export class Lock extends deviceBase {
|
|
|
316
310
|
*/
|
|
317
311
|
async refreshStatus(): Promise<void> {
|
|
318
312
|
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
319
|
-
await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`)
|
|
313
|
+
await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`)
|
|
320
314
|
} else if (this.BLE) {
|
|
321
|
-
await this.BLERefreshStatus()
|
|
315
|
+
await this.BLERefreshStatus()
|
|
322
316
|
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
323
|
-
await this.openAPIRefreshStatus()
|
|
317
|
+
await this.openAPIRefreshStatus()
|
|
324
318
|
} else {
|
|
325
|
-
await this.offlineOff()
|
|
326
|
-
await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`)
|
|
319
|
+
await this.offlineOff()
|
|
320
|
+
await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`)
|
|
327
321
|
}
|
|
328
322
|
}
|
|
329
323
|
|
|
330
324
|
async BLERefreshStatus(): Promise<void> {
|
|
331
|
-
await this.debugLog('BLERefreshStatus')
|
|
332
|
-
const switchbot = await this.switchbotBLE()
|
|
325
|
+
await this.debugLog('BLERefreshStatus')
|
|
326
|
+
const switchbot = await this.switchbotBLE()
|
|
333
327
|
if (switchbot === undefined) {
|
|
334
|
-
await this.BLERefreshConnection(switchbot)
|
|
328
|
+
await this.BLERefreshConnection(switchbot)
|
|
335
329
|
} else {
|
|
336
330
|
// Start to monitor advertisement packets
|
|
337
331
|
(async () => {
|
|
338
332
|
// Start to monitor advertisement packets
|
|
339
|
-
const serviceData = await this.monitorAdvertisementPackets(switchbot) as lockServiceData | lockProServiceData
|
|
333
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot) as lockServiceData | lockProServiceData
|
|
340
334
|
// Update HomeKit
|
|
341
335
|
if ((serviceData.model === SwitchBotBLEModel.Lock || SwitchBotBLEModel.LockPro)
|
|
342
336
|
&& (serviceData.modelName === SwitchBotBLEModelName.Lock || SwitchBotBLEModelName.LockPro)) {
|
|
343
|
-
this.serviceData = serviceData
|
|
344
|
-
await this.BLEparseStatus()
|
|
345
|
-
await this.updateHomeKitCharacteristics()
|
|
337
|
+
this.serviceData = serviceData
|
|
338
|
+
await this.BLEparseStatus()
|
|
339
|
+
await this.updateHomeKitCharacteristics()
|
|
346
340
|
} else {
|
|
347
|
-
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`)
|
|
348
|
-
await this.BLERefreshConnection(switchbot)
|
|
341
|
+
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`)
|
|
342
|
+
await this.BLERefreshConnection(switchbot)
|
|
349
343
|
}
|
|
350
|
-
})()
|
|
344
|
+
})()
|
|
351
345
|
}
|
|
352
346
|
}
|
|
353
347
|
|
|
354
348
|
async registerPlatformBLE(): Promise<void> {
|
|
355
|
-
await this.debugLog('registerPlatformBLE')
|
|
349
|
+
await this.debugLog('registerPlatformBLE')
|
|
356
350
|
if (this.config.options?.BLE) {
|
|
357
|
-
await this.debugLog('is listening to Platform BLE.')
|
|
358
|
-
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase()
|
|
359
|
-
await this.debugLog(`bleMac: ${this.device.bleMac}`)
|
|
351
|
+
await this.debugLog('is listening to Platform BLE.')
|
|
352
|
+
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase()
|
|
353
|
+
await this.debugLog(`bleMac: ${this.device.bleMac}`)
|
|
360
354
|
this.platform.bleEventHandler[this.device.bleMac] = async (context: lockServiceData | lockProServiceData) => {
|
|
361
355
|
try {
|
|
362
|
-
await this.debugLog(`received BLE: ${JSON.stringify(context)}`)
|
|
363
|
-
this.serviceData = context
|
|
364
|
-
await this.BLEparseStatus()
|
|
365
|
-
await this.updateHomeKitCharacteristics()
|
|
356
|
+
await this.debugLog(`received BLE: ${JSON.stringify(context)}`)
|
|
357
|
+
this.serviceData = context
|
|
358
|
+
await this.BLEparseStatus()
|
|
359
|
+
await this.updateHomeKitCharacteristics()
|
|
366
360
|
} catch (e: any) {
|
|
367
|
-
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`)
|
|
361
|
+
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`)
|
|
368
362
|
}
|
|
369
|
-
}
|
|
363
|
+
}
|
|
370
364
|
} else {
|
|
371
|
-
await this.debugLog('is not listening to Platform BLE')
|
|
365
|
+
await this.debugLog('is not listening to Platform BLE')
|
|
372
366
|
}
|
|
373
367
|
}
|
|
374
368
|
|
|
375
369
|
async openAPIRefreshStatus(): Promise<void> {
|
|
376
|
-
await this.debugLog('openAPIRefreshStatus')
|
|
370
|
+
await this.debugLog('openAPIRefreshStatus')
|
|
377
371
|
try {
|
|
378
|
-
const { body, statusCode } = await this.deviceRefreshStatus()
|
|
379
|
-
const deviceStatus: any = await body.json()
|
|
380
|
-
await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
372
|
+
const { body, statusCode } = await this.deviceRefreshStatus()
|
|
373
|
+
const deviceStatus: any = await body.json()
|
|
374
|
+
await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
381
375
|
if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
|
|
382
|
-
await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
383
|
-
this.deviceStatus = deviceStatus.body
|
|
384
|
-
await this.openAPIparseStatus()
|
|
385
|
-
await this.updateHomeKitCharacteristics()
|
|
376
|
+
await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
377
|
+
this.deviceStatus = deviceStatus.body
|
|
378
|
+
await this.openAPIparseStatus()
|
|
379
|
+
await this.updateHomeKitCharacteristics()
|
|
386
380
|
} else {
|
|
387
|
-
await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
388
|
-
await this.debugWarnLog(statusCode, deviceStatus)
|
|
381
|
+
await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
382
|
+
await this.debugWarnLog(statusCode, deviceStatus)
|
|
389
383
|
}
|
|
390
384
|
} catch (e: any) {
|
|
391
|
-
await this.apiError(e)
|
|
392
|
-
await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
385
|
+
await this.apiError(e)
|
|
386
|
+
await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
393
387
|
}
|
|
394
388
|
}
|
|
395
389
|
|
|
396
390
|
async registerWebhook() {
|
|
397
391
|
if (this.device.webhook) {
|
|
398
|
-
await this.debugLog('is listening webhook.')
|
|
392
|
+
await this.debugLog('is listening webhook.')
|
|
399
393
|
this.platform.webhookEventHandler[this.device.deviceId] = async (context: lockWebhookContext | lockProWebhookContext) => {
|
|
400
394
|
try {
|
|
401
|
-
await this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
|
|
402
|
-
this.webhookContext = context
|
|
403
|
-
await this.parseStatusWebhook()
|
|
404
|
-
await this.updateHomeKitCharacteristics()
|
|
395
|
+
await this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
|
|
396
|
+
this.webhookContext = context
|
|
397
|
+
await this.parseStatusWebhook()
|
|
398
|
+
await this.updateHomeKitCharacteristics()
|
|
405
399
|
} catch (e: any) {
|
|
406
|
-
await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`)
|
|
400
|
+
await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`)
|
|
407
401
|
}
|
|
408
|
-
}
|
|
402
|
+
}
|
|
409
403
|
} else {
|
|
410
|
-
await this.debugLog('is not listening webhook.')
|
|
404
|
+
await this.debugLog('is not listening webhook.')
|
|
411
405
|
}
|
|
412
406
|
}
|
|
413
407
|
|
|
414
408
|
/**
|
|
415
409
|
* Pushes the requested changes to the SwitchBot API
|
|
416
|
-
* deviceType
|
|
417
|
-
* Lock - "command" "lock" "default"
|
|
418
|
-
* Lock - "command" "unlock" "default"
|
|
410
|
+
* deviceType commandType Command command parameter Description
|
|
411
|
+
* Lock - "command" "lock" "default" = set to ???? state
|
|
412
|
+
* Lock - "command" "unlock" "default" = set to ???? state - LockCurrentState
|
|
419
413
|
*/
|
|
420
414
|
async pushChanges(): Promise<void> {
|
|
421
415
|
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
422
|
-
await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`)
|
|
416
|
+
await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`)
|
|
423
417
|
} else if (this.BLE) {
|
|
424
|
-
await this.BLEpushChanges()
|
|
418
|
+
await this.BLEpushChanges()
|
|
425
419
|
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
426
|
-
await this.openAPIpushChanges()
|
|
420
|
+
await this.openAPIpushChanges()
|
|
427
421
|
} else {
|
|
428
|
-
await this.offlineOff()
|
|
429
|
-
await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`)
|
|
422
|
+
await this.offlineOff()
|
|
423
|
+
await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`)
|
|
430
424
|
}
|
|
431
425
|
// Refresh the status from the API
|
|
432
426
|
interval(15000)
|
|
433
427
|
.pipe(skipWhile(() => this.lockUpdateInProgress))
|
|
434
428
|
.pipe(take(1))
|
|
435
429
|
.subscribe(async () => {
|
|
436
|
-
await this.refreshStatus()
|
|
437
|
-
})
|
|
430
|
+
await this.refreshStatus()
|
|
431
|
+
})
|
|
438
432
|
}
|
|
439
433
|
|
|
440
434
|
async BLEpushChanges(): Promise<void> {
|
|
441
|
-
await this.debugLog('BLEpushChanges')
|
|
435
|
+
await this.debugLog('BLEpushChanges')
|
|
442
436
|
if (this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) {
|
|
443
|
-
const switchbot = await this.platform.connectBLE(this.accessory, this.device)
|
|
444
|
-
await this.convertBLEAddress()
|
|
437
|
+
const switchbot = await this.platform.connectBLE(this.accessory, this.device)
|
|
438
|
+
await this.convertBLEAddress()
|
|
445
439
|
if (switchbot !== false) {
|
|
446
440
|
switchbot
|
|
447
441
|
.discover({ model: this.device.bleModel, id: this.device.bleMac })
|
|
@@ -450,61 +444,59 @@ export class Lock extends deviceBase {
|
|
|
450
444
|
max: await this.maxRetryBLE(),
|
|
451
445
|
fn: async () => {
|
|
452
446
|
if (this.LockMechanism.LockTargetState === this.hap.Characteristic.LockTargetState.SECURED) {
|
|
453
|
-
return await device_list[0].lock({ id: this.device.bleMac })
|
|
447
|
+
return await device_list[0].lock({ id: this.device.bleMac })
|
|
454
448
|
} else {
|
|
455
|
-
return await device_list[0].unlock({ id: this.device.bleMac })
|
|
449
|
+
return await device_list[0].unlock({ id: this.device.bleMac })
|
|
456
450
|
}
|
|
457
451
|
},
|
|
458
|
-
})
|
|
452
|
+
})
|
|
459
453
|
})
|
|
460
454
|
.then(async () => {
|
|
461
|
-
await this.successLog(`LockTargetState: ${this.LockMechanism.LockTargetState} sent over SwitchBot BLE, sent successfully`)
|
|
462
|
-
await this.updateHomeKitCharacteristics()
|
|
455
|
+
await this.successLog(`LockTargetState: ${this.LockMechanism.LockTargetState} sent over SwitchBot BLE, sent successfully`)
|
|
456
|
+
await this.updateHomeKitCharacteristics()
|
|
463
457
|
})
|
|
464
458
|
.catch(async (e: any) => {
|
|
465
|
-
await this.apiError(e)
|
|
466
|
-
await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
467
|
-
await this.BLEPushConnection()
|
|
468
|
-
})
|
|
459
|
+
await this.apiError(e)
|
|
460
|
+
await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
461
|
+
await this.BLEPushConnection()
|
|
462
|
+
})
|
|
469
463
|
} else {
|
|
470
|
-
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
|
|
471
|
-
await this.BLEPushConnection()
|
|
464
|
+
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
|
|
465
|
+
await this.BLEPushConnection()
|
|
472
466
|
}
|
|
473
467
|
} else {
|
|
474
|
-
await this.debugLog(`No changes (BLEpushChanges), LockTargetState: ${this.LockMechanism.LockTargetState}
|
|
475
|
-
+ ` LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
|
|
468
|
+
await this.debugLog(`No changes (BLEpushChanges), LockTargetState: ${this.LockMechanism.LockTargetState}, LockCurrentState: ${this.LockMechanism.LockCurrentState}`)
|
|
476
469
|
}
|
|
477
470
|
}
|
|
478
471
|
|
|
479
472
|
async openAPIpushChanges(LatchUnlock?: boolean): Promise<void> {
|
|
480
|
-
await this.debugLog('openAPIpushChanges')
|
|
473
|
+
await this.debugLog('openAPIpushChanges')
|
|
481
474
|
if ((this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) || LatchUnlock) {
|
|
482
475
|
// Determine the command based on the LockTargetState or the forceUnlock parameter
|
|
483
|
-
const command = LatchUnlock ? 'unlock' : this.LockMechanism.LockTargetState ? 'lock' : 'unlock'
|
|
476
|
+
const command = LatchUnlock ? 'unlock' : this.LockMechanism.LockTargetState ? 'lock' : 'unlock'
|
|
484
477
|
const bodyChange = JSON.stringify({
|
|
485
478
|
command: `${command}`,
|
|
486
479
|
parameter: 'default',
|
|
487
480
|
commandType: 'command',
|
|
488
|
-
})
|
|
489
|
-
await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`)
|
|
481
|
+
})
|
|
482
|
+
await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`)
|
|
490
483
|
try {
|
|
491
|
-
const { body, statusCode } = await this.pushChangeRequest(bodyChange)
|
|
492
|
-
const deviceStatus: any = await body.json()
|
|
493
|
-
await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
484
|
+
const { body, statusCode } = await this.pushChangeRequest(bodyChange)
|
|
485
|
+
const deviceStatus: any = await body.json()
|
|
486
|
+
await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
494
487
|
if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
|
|
495
|
-
await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
496
|
-
await this.updateHomeKitCharacteristics()
|
|
488
|
+
await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
489
|
+
await this.updateHomeKitCharacteristics()
|
|
497
490
|
} else {
|
|
498
|
-
await this.statusCode(statusCode)
|
|
499
|
-
await this.statusCode(deviceStatus.statusCode)
|
|
491
|
+
await this.statusCode(statusCode)
|
|
492
|
+
await this.statusCode(deviceStatus.statusCode)
|
|
500
493
|
}
|
|
501
494
|
} catch (e: any) {
|
|
502
|
-
await this.apiError(e)
|
|
503
|
-
await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
495
|
+
await this.apiError(e)
|
|
496
|
+
await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
504
497
|
}
|
|
505
498
|
} else {
|
|
506
|
-
await this.debugLog(`No changes (openAPIpushChanges), LockCurrentState: ${this.LockMechanism.LockCurrentState}
|
|
507
|
-
+ ` TargetPosition: ${this.LockMechanism.LockTargetState}`);
|
|
499
|
+
await this.debugLog(`No changes (openAPIpushChanges), LockCurrentState: ${this.LockMechanism.LockCurrentState}, TargetPosition: ${this.LockMechanism.LockTargetState}`)
|
|
508
500
|
}
|
|
509
501
|
}
|
|
510
502
|
|
|
@@ -513,106 +505,100 @@ export class Lock extends deviceBase {
|
|
|
513
505
|
*/
|
|
514
506
|
async LockTargetStateSet(value: CharacteristicValue): Promise<void> {
|
|
515
507
|
if (this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) {
|
|
516
|
-
await this.infoLog(`Set LockTargetState: ${value}`)
|
|
508
|
+
await this.infoLog(`Set LockTargetState: ${value}`)
|
|
517
509
|
} else {
|
|
518
|
-
await this.debugLog(`No Changes, LockTargetState: ${value}`)
|
|
510
|
+
await this.debugLog(`No Changes, LockTargetState: ${value}`)
|
|
519
511
|
}
|
|
520
512
|
|
|
521
|
-
this.LockMechanism.LockTargetState = value
|
|
522
|
-
this.doLockUpdate.next()
|
|
513
|
+
this.LockMechanism.LockTargetState = value
|
|
514
|
+
this.doLockUpdate.next()
|
|
523
515
|
}
|
|
524
516
|
|
|
525
517
|
/**
|
|
526
518
|
* Handle requests to set the value of the "On" characteristic
|
|
527
519
|
*/
|
|
528
520
|
async OnSet(value: CharacteristicValue): Promise<void> {
|
|
529
|
-
await this.debugLog(`Latch Button Set On: ${value}`)
|
|
521
|
+
await this.debugLog(`Latch Button Set On: ${value}`)
|
|
530
522
|
if (value) {
|
|
531
|
-
await this.debugLog('Attempting to open the latch')
|
|
523
|
+
await this.debugLog('Attempting to open the latch')
|
|
532
524
|
|
|
533
525
|
this.openAPIpushChanges(value as boolean).then(async () => {
|
|
534
|
-
await this.debugLog('Latch opened successfully')
|
|
535
|
-
await this.debugLog(`SwitchService is: ${this.Switch?.Service ? 'available' : 'not available'}`)
|
|
526
|
+
await this.debugLog('Latch opened successfully')
|
|
527
|
+
await this.debugLog(`SwitchService is: ${this.Switch?.Service ? 'available' : 'not available'}`)
|
|
536
528
|
|
|
537
529
|
// simulate button press to turn the switch back off
|
|
538
530
|
if (this.Switch?.Service) {
|
|
539
|
-
const SwitchService = this.Switch.Service
|
|
531
|
+
const SwitchService = this.Switch.Service
|
|
540
532
|
// Simulate a button press by waiting a short period before turning the switch off
|
|
541
|
-
setTimeout(async() => {
|
|
542
|
-
SwitchService.getCharacteristic(this.hap.Characteristic.On).updateValue(false)
|
|
543
|
-
await this.debugLog('Latch button switched off automatically.')
|
|
544
|
-
}, 500)
|
|
533
|
+
setTimeout(async () => {
|
|
534
|
+
SwitchService.getCharacteristic(this.hap.Characteristic.On).updateValue(false)
|
|
535
|
+
await this.debugLog('Latch button switched off automatically.')
|
|
536
|
+
}, 500) // 500 ms delay
|
|
545
537
|
}
|
|
546
538
|
}).catch(async (e: any) => {
|
|
547
539
|
// Log the error if the operation failed
|
|
548
|
-
await this.debugLog(`Error opening latch: ${e}`)
|
|
540
|
+
await this.debugLog(`Error opening latch: ${e}`)
|
|
549
541
|
// Ensure we turn the switch back off even in case of an error
|
|
550
542
|
if (this.Switch?.Service) {
|
|
551
|
-
this.Switch.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(false)
|
|
552
|
-
await this.debugLog('Latch button switched off after an error.')
|
|
543
|
+
this.Switch.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(false)
|
|
544
|
+
await this.debugLog('Latch button switched off after an error.')
|
|
553
545
|
}
|
|
554
|
-
})
|
|
546
|
+
})
|
|
555
547
|
} else {
|
|
556
|
-
await this.debugLog('Switch is off, nothing to do')
|
|
548
|
+
await this.debugLog('Switch is off, nothing to do')
|
|
557
549
|
}
|
|
558
550
|
|
|
559
|
-
this.Switch!.On = value
|
|
560
|
-
this.doLockUpdate.next()
|
|
551
|
+
this.Switch!.On = value
|
|
552
|
+
this.doLockUpdate.next()
|
|
561
553
|
}
|
|
562
554
|
|
|
563
555
|
async updateHomeKitCharacteristics(): Promise<void> {
|
|
564
556
|
// LockCurrentState
|
|
565
|
-
await this.updateCharacteristic(this.LockMechanism.Service, this.hap.Characteristic.LockTargetState,
|
|
566
|
-
this.LockMechanism.LockTargetState, 'LockTargetState');
|
|
557
|
+
await this.updateCharacteristic(this.LockMechanism.Service, this.hap.Characteristic.LockTargetState, this.LockMechanism.LockTargetState, 'LockTargetState')
|
|
567
558
|
// LockCurrentState
|
|
568
|
-
await this.updateCharacteristic(this.LockMechanism.Service, this.hap.Characteristic.LockCurrentState,
|
|
569
|
-
this.LockMechanism.LockCurrentState, 'LockCurrentState');
|
|
559
|
+
await this.updateCharacteristic(this.LockMechanism.Service, this.hap.Characteristic.LockCurrentState, this.LockMechanism.LockCurrentState, 'LockCurrentState')
|
|
570
560
|
// ContactSensorState
|
|
571
561
|
if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
|
|
572
|
-
await this.updateCharacteristic(this.ContactSensor.Service, this.hap.Characteristic.ContactSensorState,
|
|
573
|
-
this.ContactSensor.ContactSensorState, 'ContactSensorState');
|
|
562
|
+
await this.updateCharacteristic(this.ContactSensor.Service, this.hap.Characteristic.ContactSensorState, this.ContactSensor.ContactSensorState, 'ContactSensorState')
|
|
574
563
|
}
|
|
575
564
|
// BatteryLevel
|
|
576
|
-
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel,
|
|
577
|
-
this.Battery.BatteryLevel, 'BatteryLevel');
|
|
565
|
+
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel, 'BatteryLevel')
|
|
578
566
|
// StatusLowBattery
|
|
579
|
-
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery,
|
|
580
|
-
this.Battery.StatusLowBattery, 'StatusLowBattery');
|
|
567
|
+
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery, 'StatusLowBattery')
|
|
581
568
|
}
|
|
582
569
|
|
|
583
570
|
async BLEPushConnection() {
|
|
584
571
|
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
585
|
-
await this.warnLog('Using OpenAPI Connection to Push Changes')
|
|
586
|
-
await this.openAPIpushChanges()
|
|
572
|
+
await this.warnLog('Using OpenAPI Connection to Push Changes')
|
|
573
|
+
await this.openAPIpushChanges()
|
|
587
574
|
}
|
|
588
575
|
}
|
|
589
576
|
|
|
590
577
|
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
591
|
-
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
|
|
578
|
+
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
|
|
592
579
|
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
593
|
-
await this.warnLog('Using OpenAPI Connection to Refresh Status')
|
|
594
|
-
await this.openAPIRefreshStatus()
|
|
580
|
+
await this.warnLog('Using OpenAPI Connection to Refresh Status')
|
|
581
|
+
await this.openAPIRefreshStatus()
|
|
595
582
|
}
|
|
596
583
|
}
|
|
597
584
|
|
|
598
585
|
async offlineOff(): Promise<void> {
|
|
599
586
|
if (this.device.offline) {
|
|
600
|
-
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED)
|
|
601
|
-
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED)
|
|
587
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED)
|
|
588
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED)
|
|
602
589
|
if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
|
|
603
|
-
this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState,
|
|
604
|
-
this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED);
|
|
590
|
+
this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED)
|
|
605
591
|
}
|
|
606
592
|
}
|
|
607
593
|
}
|
|
608
594
|
|
|
609
595
|
async apiError(e: any): Promise<void> {
|
|
610
|
-
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, e)
|
|
611
|
-
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, e)
|
|
596
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, e)
|
|
597
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, e)
|
|
612
598
|
if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
|
|
613
|
-
this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e)
|
|
599
|
+
this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e)
|
|
614
600
|
}
|
|
615
|
-
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e)
|
|
616
|
-
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e)
|
|
601
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e)
|
|
602
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e)
|
|
617
603
|
}
|
|
618
604
|
}
|