@switchbot/homebridge-switchbot 3.5.1-beta.0 → 3.5.1-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/README.md +16 -0
  2. package/dist/device/blindtilt.d.ts +15 -6
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +224 -370
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +9 -4
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +197 -221
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +10 -5
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +214 -292
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +10 -5
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +335 -421
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +9 -4
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +121 -200
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +20 -7
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +229 -403
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/device.d.ts +41 -22
  27. package/dist/device/device.d.ts.map +1 -1
  28. package/dist/device/device.js +212 -181
  29. package/dist/device/device.js.map +1 -1
  30. package/dist/device/fan.d.ts +9 -4
  31. package/dist/device/fan.d.ts.map +1 -1
  32. package/dist/device/fan.js +204 -249
  33. package/dist/device/fan.js.map +1 -1
  34. package/dist/device/hub.d.ts +9 -5
  35. package/dist/device/hub.d.ts.map +1 -1
  36. package/dist/device/hub.js +107 -233
  37. package/dist/device/hub.js.map +1 -1
  38. package/dist/device/humidifier.d.ts +12 -4
  39. package/dist/device/humidifier.d.ts.map +1 -1
  40. package/dist/device/humidifier.js +193 -235
  41. package/dist/device/humidifier.js.map +1 -1
  42. package/dist/device/iosensor.d.ts +9 -4
  43. package/dist/device/iosensor.d.ts.map +1 -1
  44. package/dist/device/iosensor.js +92 -159
  45. package/dist/device/iosensor.js.map +1 -1
  46. package/dist/device/lightstrip.d.ts +10 -5
  47. package/dist/device/lightstrip.d.ts.map +1 -1
  48. package/dist/device/lightstrip.js +288 -370
  49. package/dist/device/lightstrip.js.map +1 -1
  50. package/dist/device/lock.d.ts +10 -5
  51. package/dist/device/lock.d.ts.map +1 -1
  52. package/dist/device/lock.js +172 -219
  53. package/dist/device/lock.js.map +1 -1
  54. package/dist/device/meter.d.ts +9 -4
  55. package/dist/device/meter.d.ts.map +1 -1
  56. package/dist/device/meter.js +94 -160
  57. package/dist/device/meter.js.map +1 -1
  58. package/dist/device/meterplus.d.ts +9 -4
  59. package/dist/device/meterplus.d.ts.map +1 -1
  60. package/dist/device/meterplus.js +95 -157
  61. package/dist/device/meterplus.js.map +1 -1
  62. package/dist/device/motion.d.ts +9 -4
  63. package/dist/device/motion.d.ts.map +1 -1
  64. package/dist/device/motion.js +85 -144
  65. package/dist/device/motion.js.map +1 -1
  66. package/dist/device/plug.d.ts +9 -4
  67. package/dist/device/plug.d.ts.map +1 -1
  68. package/dist/device/plug.js +100 -127
  69. package/dist/device/plug.js.map +1 -1
  70. package/dist/device/robotvacuumcleaner.d.ts +9 -6
  71. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  72. package/dist/device/robotvacuumcleaner.js +172 -259
  73. package/dist/device/robotvacuumcleaner.js.map +1 -1
  74. package/dist/device/waterdetector.d.ts +12 -4
  75. package/dist/device/waterdetector.d.ts.map +1 -1
  76. package/dist/device/waterdetector.js +106 -131
  77. package/dist/device/waterdetector.js.map +1 -1
  78. package/dist/irdevice/airconditioner.d.ts +2 -1
  79. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  80. package/dist/irdevice/airconditioner.js +2 -3
  81. package/dist/irdevice/airconditioner.js.map +1 -1
  82. package/dist/irdevice/airpurifier.d.ts +2 -1
  83. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  84. package/dist/irdevice/airpurifier.js +2 -3
  85. package/dist/irdevice/airpurifier.js.map +1 -1
  86. package/dist/irdevice/camera.d.ts +2 -1
  87. package/dist/irdevice/camera.d.ts.map +1 -1
  88. package/dist/irdevice/camera.js +2 -3
  89. package/dist/irdevice/camera.js.map +1 -1
  90. package/dist/irdevice/fan.d.ts +2 -1
  91. package/dist/irdevice/fan.d.ts.map +1 -1
  92. package/dist/irdevice/fan.js +2 -3
  93. package/dist/irdevice/fan.js.map +1 -1
  94. package/dist/irdevice/irdevice.d.ts +3 -1
  95. package/dist/irdevice/irdevice.d.ts.map +1 -1
  96. package/dist/irdevice/irdevice.js +5 -1
  97. package/dist/irdevice/irdevice.js.map +1 -1
  98. package/dist/irdevice/light.d.ts +2 -1
  99. package/dist/irdevice/light.d.ts.map +1 -1
  100. package/dist/irdevice/light.js +2 -3
  101. package/dist/irdevice/light.js.map +1 -1
  102. package/dist/irdevice/other.d.ts +2 -1
  103. package/dist/irdevice/other.d.ts.map +1 -1
  104. package/dist/irdevice/other.js +2 -3
  105. package/dist/irdevice/other.js.map +1 -1
  106. package/dist/irdevice/tv.d.ts +2 -1
  107. package/dist/irdevice/tv.d.ts.map +1 -1
  108. package/dist/irdevice/tv.js +2 -3
  109. package/dist/irdevice/tv.js.map +1 -1
  110. package/dist/irdevice/vacuumcleaner.d.ts +2 -1
  111. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  112. package/dist/irdevice/vacuumcleaner.js +2 -3
  113. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  114. package/dist/irdevice/waterheater.d.ts +2 -1
  115. package/dist/irdevice/waterheater.d.ts.map +1 -1
  116. package/dist/irdevice/waterheater.js +2 -3
  117. package/dist/irdevice/waterheater.js.map +1 -1
  118. package/dist/platform.d.ts +14 -14
  119. package/dist/platform.d.ts.map +1 -1
  120. package/dist/platform.js +102 -86
  121. package/dist/platform.js.map +1 -1
  122. package/dist/settings.d.ts +49 -190
  123. package/dist/settings.d.ts.map +1 -1
  124. package/dist/settings.js +19 -0
  125. package/dist/settings.js.map +1 -1
  126. package/dist/types/bledevicestatus.d.ts +279 -0
  127. package/dist/types/bledevicestatus.d.ts.map +1 -0
  128. package/dist/types/bledevicestatus.js +2 -0
  129. package/dist/types/bledevicestatus.js.map +1 -0
  130. package/dist/types/devicelist.d.ts +89 -0
  131. package/dist/types/devicelist.d.ts.map +1 -0
  132. package/dist/types/devicelist.js +6 -0
  133. package/dist/types/devicelist.js.map +1 -0
  134. package/dist/types/deviceresponse.d.ts +13 -0
  135. package/dist/types/deviceresponse.d.ts.map +1 -0
  136. package/dist/types/deviceresponse.js +2 -0
  137. package/dist/types/deviceresponse.js.map +1 -0
  138. package/dist/types/devicestatus.d.ts +149 -0
  139. package/dist/types/devicestatus.d.ts.map +1 -0
  140. package/dist/types/devicestatus.js +3 -0
  141. package/dist/types/devicestatus.js.map +1 -0
  142. package/dist/types/devicewebhookstatus.d.ts +156 -0
  143. package/dist/types/devicewebhookstatus.d.ts.map +1 -0
  144. package/dist/types/devicewebhookstatus.js +2 -0
  145. package/dist/types/devicewebhookstatus.js.map +1 -0
  146. package/dist/types/irdevicelist.d.ts +10 -0
  147. package/dist/types/irdevicelist.d.ts.map +1 -0
  148. package/dist/types/irdevicelist.js +2 -0
  149. package/dist/types/irdevicelist.js.map +1 -0
  150. package/dist/types/pushbody.d.ts +6 -0
  151. package/dist/types/pushbody.d.ts.map +1 -0
  152. package/dist/types/pushbody.js +2 -0
  153. package/dist/types/pushbody.js.map +1 -0
  154. package/dist/utils.d.ts +25 -0
  155. package/dist/utils.d.ts.map +1 -1
  156. package/dist/utils.js +28 -0
  157. package/dist/utils.js.map +1 -1
  158. package/package.json +11 -11
  159. package/src/device/blindtilt.ts +254 -376
  160. package/src/device/bot.ts +209 -224
  161. package/src/device/ceilinglight.ts +227 -297
  162. package/src/device/colorbulb.ts +345 -435
  163. package/src/device/contact.ts +139 -200
  164. package/src/device/curtain.ts +254 -414
  165. package/src/device/device.ts +221 -190
  166. package/src/device/fan.ts +222 -253
  167. package/src/device/hub.ts +127 -248
  168. package/src/device/humidifier.ts +217 -246
  169. package/src/device/iosensor.ts +115 -168
  170. package/src/device/lightstrip.ts +303 -380
  171. package/src/device/lock.ts +188 -224
  172. package/src/device/meter.ts +117 -179
  173. package/src/device/meterplus.ts +118 -176
  174. package/src/device/motion.ts +100 -146
  175. package/src/device/plug.ts +111 -131
  176. package/src/device/robotvacuumcleaner.ts +191 -258
  177. package/src/device/waterdetector.ts +124 -141
  178. package/src/irdevice/airconditioner.ts +4 -4
  179. package/src/irdevice/airpurifier.ts +4 -4
  180. package/src/irdevice/camera.ts +4 -4
  181. package/src/irdevice/fan.ts +4 -4
  182. package/src/irdevice/irdevice.ts +8 -2
  183. package/src/irdevice/light.ts +4 -4
  184. package/src/irdevice/other.ts +4 -4
  185. package/src/irdevice/tv.ts +4 -4
  186. package/src/irdevice/vacuumcleaner.ts +4 -4
  187. package/src/irdevice/waterheater.ts +4 -4
  188. package/src/platform.ts +104 -87
  189. package/src/settings.ts +30 -238
  190. package/src/types/bledevicestatus.ts +305 -0
  191. package/src/types/devicelist.ts +124 -0
  192. package/src/types/deviceresponse.ts +15 -0
  193. package/src/types/devicestatus.ts +178 -0
  194. package/src/types/devicewebhookstatus.ts +196 -0
  195. package/src/types/irdevicelist.ts +15 -0
  196. package/src/types/pushbody.ts +9 -0
  197. 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,42 +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
- this.apiError(e);
330
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
331
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
323
+ await this.apiError(e);
324
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
332
325
  }
333
326
  }
334
327
 
335
- async registerWebhook(accessory: PlatformAccessory, device: device & devicesConfig) {
336
- if (device.webhook) {
337
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
338
- 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) => {
339
332
  try {
340
- this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
341
- const { lockState } = context;
342
- const { LockCurrentState } = this.LockMechanism;
343
- this.debugLog(`${device.deviceType}: ${accessory.displayName} (lockState) = Webhook:(${lockState}), current:(${LockCurrentState})`);
344
- this.LockMechanism.LockCurrentState = lockState === 'LOCKED' ? 1 : 0;
345
- this.updateHomeKitCharacteristics();
333
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
334
+ await this.parseStatusWebhook(context);
335
+ await this.updateHomeKitCharacteristics();
346
336
  } catch (e: any) {
347
- 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}`);
348
338
  }
349
339
  };
350
340
  } else {
351
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
341
+ await this.debugLog('is not listening webhook.');
352
342
  }
353
343
  }
354
344
 
@@ -360,15 +350,14 @@ export class Lock extends deviceBase {
360
350
  */
361
351
  async pushChanges(): Promise<void> {
362
352
  if (!this.device.enableCloudService && this.OpenAPI) {
363
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
353
+ await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`);
364
354
  } else if (this.BLE) {
365
355
  await this.BLEpushChanges();
366
356
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
367
357
  await this.openAPIpushChanges();
368
358
  } else {
369
359
  await this.offlineOff();
370
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
371
- + ` ${this.device.connectionType}, pushChanges will not happen.`);
360
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`);
372
361
  }
373
362
  // Refresh the status from the API
374
363
  interval(15000)
@@ -380,73 +369,73 @@ export class Lock extends deviceBase {
380
369
  }
381
370
 
382
371
  async BLEpushChanges(): Promise<void> {
383
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
372
+ await this.debugLog('BLEpushChanges');
384
373
  if (this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) {
385
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges LockTargetState: ${this.LockMechanism.LockTargetState}`
386
- + ` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
387
- const switchbot = await this.platform.connectBLE();
388
- // Convert to BLE Address
374
+ const switchbot = await this.platform.connectBLE(this.accessory, this.device);
389
375
  await this.convertBLEAddress();
390
- switchbot
391
- .discover({
392
- model: '',
393
- id: this.device.bleMac,
394
- })
395
- .then(() => {
396
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
397
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
398
- + `LockTargetState: ${this.LockMechanism.LockTargetState} sent over BLE, sent successfully`);
399
- this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
400
- })
401
- .catch(async (e: any) => {
402
- this.apiError(e);
403
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
404
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
405
- await this.BLEPushConnection();
406
- });
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
+ }
407
404
  } else {
408
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.`
409
- + `LockTargetState: ${this.LockMechanism.LockTargetState}, `
410
- + `LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
405
+ await this.debugLog(`No changes (BLEpushChanges), LockTargetState: ${this.LockMechanism.LockTargetState},`
406
+ + ` LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
411
407
  }
412
408
  }
413
409
 
414
- async openAPIpushChanges(LatchUnlock?): Promise<void> {
415
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
416
-
410
+ async openAPIpushChanges(LatchUnlock?: boolean): Promise<void> {
411
+ await this.debugLog('openAPIpushChanges');
417
412
  if ((this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) || LatchUnlock) {
418
413
  // Determine the command based on the LockTargetState or the forceUnlock parameter
419
- let command = '';
420
- if (LatchUnlock) {
421
- command = 'unlock';
422
- } else {
423
- command = this.LockMechanism.LockTargetState ? 'lock' : 'unlock';
424
- }
414
+ const command = LatchUnlock ? 'unlock' : this.LockMechanism.LockTargetState ? 'lock' : 'unlock';
425
415
  const bodyChange = JSON.stringify({
426
416
  command: `${command}`,
427
417
  parameter: 'default',
428
418
  commandType: 'command',
429
419
  });
430
- 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)}`);
431
421
  try {
432
422
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
433
423
  const deviceStatus: any = await body.json();
434
- await this.pushStatusCodes(statusCode, deviceStatus);
435
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
436
- 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)}`);
437
427
  await this.updateHomeKitCharacteristics();
438
428
  } else {
439
429
  await this.statusCode(statusCode);
440
430
  await this.statusCode(deviceStatus.statusCode);
441
431
  }
442
432
  } catch (e: any) {
443
- this.apiError(e);
444
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
445
- + ` 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)}`);
446
435
  }
447
436
  } else {
448
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges, LockTargetState: `
449
- + `${this.LockMechanism.LockTargetState}, LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
437
+ await this.debugLog(`No changes (openAPIpushChanges), LockCurrentState: ${this.LockMechanism.LockCurrentState},`
438
+ + ` TargetPosition: ${this.LockMechanism.LockTargetState}`);
450
439
  }
451
440
  }
452
441
 
@@ -454,10 +443,10 @@ export class Lock extends deviceBase {
454
443
  * Handle requests to set the value of the "On" characteristic
455
444
  */
456
445
  async LockTargetStateSet(value: CharacteristicValue): Promise<void> {
457
- if (this.LockMechanism.LockTargetState === this.accessory.context.LockTargetState) {
458
- 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}`);
459
448
  } else {
460
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
449
+ await this.debugLog(`No Changes, LockTargetState: ${value}`);
461
450
  }
462
451
 
463
452
  this.LockMechanism.LockTargetState = value;
@@ -468,35 +457,34 @@ export class Lock extends deviceBase {
468
457
  * Handle requests to set the value of the "On" characteristic
469
458
  */
470
459
  async OnSet(value: CharacteristicValue): Promise<void> {
471
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch Button Set On: ${value}`);
460
+ await this.debugLog(`Latch Button Set On: ${value}`);
472
461
  if (value) {
473
- this.debugLog('Attempting to open the latch');
462
+ await this.debugLog('Attempting to open the latch');
474
463
 
475
- this.openAPIpushChanges(value).then(() => {
476
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch opened successfully`);
477
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
478
- + ` 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'}`);
479
467
 
480
468
  // simulate button press to turn the switch back off
481
- if (this.Switch!.Service) {
482
- const SwitchService = this.Switch!.Service;
469
+ if (this.Switch?.Service) {
470
+ const SwitchService = this.Switch.Service;
483
471
  // Simulate a button press by waiting a short period before turning the switch off
484
- setTimeout(() => {
472
+ setTimeout(async() => {
485
473
  SwitchService.getCharacteristic(this.hap.Characteristic.On).updateValue(false);
486
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch button switched off automatically.`);
474
+ await this.debugLog('Latch button switched off automatically.');
487
475
  }, 500); // 500 ms delay
488
476
  }
489
- }).catch((e: any) => {
477
+ }).catch(async (e: any) => {
490
478
  // Log the error if the operation failed
491
- this.debugLog(`Error opening latch: ${e}`);
479
+ await this.debugLog(`Error opening latch: ${e}`);
492
480
  // Ensure we turn the switch back off even in case of an error
493
- if (this.Switch!.Service) {
494
- this.Switch!.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(false);
495
- 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.');
496
484
  }
497
485
  });
498
486
  } else {
499
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch is off, nothing to do`);
487
+ await this.debugLog('Switch is off, nothing to do');
500
488
  }
501
489
 
502
490
  this.Switch!.On = value;
@@ -504,82 +492,58 @@ export class Lock extends deviceBase {
504
492
  }
505
493
 
506
494
  async updateHomeKitCharacteristics(): Promise<void> {
507
- if (!this.device.lock?.hide_contactsensor) {
508
- if (this.ContactSensor!.ContactSensorState === undefined) {
509
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor!.ContactSensorState}`);
510
- } else {
511
- this.accessory.context.ContactSensorState = this.ContactSensor!.ContactSensorState;
512
- this.ContactSensor!.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.ContactSensor!.ContactSensorState);
513
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
514
- + ` ContactSensorState: ${this.ContactSensor!.ContactSensorState}`);
515
- }
516
- }
517
- if (this.LockMechanism.LockTargetState === undefined) {
518
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockTargetState: ${this.LockMechanism.LockTargetState}`);
519
- } else {
520
- this.accessory.context.LockTargetState = this.LockMechanism.LockTargetState;
521
- this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.LockMechanism.LockTargetState);
522
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
523
- + ` LockTargetState: ${this.LockMechanism.LockTargetState}`);
524
- }
525
- if (this.LockMechanism.LockCurrentState === undefined) {
526
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
527
- } else {
528
- this.accessory.context.LockCurrentState = this.LockMechanism.LockCurrentState;
529
- this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.LockMechanism.LockCurrentState);
530
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
531
- + ` LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
532
- }
533
- if (this.Battery.BatteryLevel === undefined) {
534
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
535
- } else {
536
- this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
537
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
538
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
539
- + ` BatteryLevel: ${this.Battery.BatteryLevel}`);
540
- }
541
- if (this.Battery.StatusLowBattery === undefined) {
542
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
543
- } else {
544
- this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
545
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
546
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
547
- + ` 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');
548
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');
549
512
  }
550
513
 
551
514
  async BLEPushConnection() {
552
515
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
553
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
516
+ await this.warnLog('Using OpenAPI Connection to Push Changes');
554
517
  await this.openAPIpushChanges();
555
518
  }
556
519
  }
557
520
 
558
521
  async BLERefreshConnection(switchbot: any): Promise<void> {
559
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
560
- + ` ${JSON.stringify(switchbot)}`);
522
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchbot)}`);
561
523
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
562
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
524
+ await this.warnLog('Using OpenAPI Connection to Refresh Status');
563
525
  await this.openAPIRefreshStatus();
564
526
  }
565
527
  }
566
528
 
567
529
  async offlineOff(): Promise<void> {
568
530
  if (this.device.offline) {
569
- if (!this.device.lock?.hide_contactsensor) {
570
- this.ContactSensor!.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState,
571
- this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED);
572
- }
573
531
  this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED);
574
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
+ }
575
537
  }
576
538
  }
577
539
 
578
540
  async apiError(e: any): Promise<void> {
579
- if (!this.device.lock?.hide_contactsensor) {
580
- this.ContactSensor!.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e);
581
- }
582
541
  this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, e);
583
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);
584
548
  }
585
549
  }