@switchbot/homebridge-switchbot 3.5.1-beta.2 → 3.5.1-beta.4

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