@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,8 +3,8 @@
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
  export class Lock extends deviceBase {
9
9
  platform;
10
10
  // Services
@@ -114,14 +114,14 @@ export class Lock extends deviceBase {
114
114
  this.refreshStatus();
115
115
  // Update Homekit
116
116
  this.updateHomeKitCharacteristics();
117
+ //regisiter webhook event handler
118
+ this.registerWebhook();
117
119
  // Start an update interval
118
120
  interval(this.deviceRefreshRate * 1000)
119
121
  .pipe(skipWhile(() => this.lockUpdateInProgress))
120
122
  .subscribe(async () => {
121
123
  await this.refreshStatus();
122
124
  });
123
- //regisiter webhook event handler
124
- this.registerWebhook(accessory, device);
125
125
  // Watch for Lock change events
126
126
  // We put in a debounce of 100ms so we don't make duplicate calls
127
127
  this.doLockUpdate
@@ -133,86 +133,64 @@ export class Lock extends deviceBase {
133
133
  await this.pushChanges();
134
134
  }
135
135
  catch (e) {
136
- this.apiError(e);
137
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
138
- + ` Error Message: ${JSON.stringify(e.message)}`);
136
+ await this.apiError(e);
137
+ await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
139
138
  }
140
139
  this.lockUpdateInProgress = false;
141
140
  });
142
141
  }
143
142
  async BLEparseStatus(serviceData) {
144
- // BLE Status
145
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
146
- switch (serviceData.status) {
147
- case 'locked':
148
- this.LockMechanism.LockCurrentState = this.hap.Characteristic.LockCurrentState.SECURED;
149
- this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
150
- break;
151
- default:
152
- this.LockMechanism.LockCurrentState = this.hap.Characteristic.LockCurrentState.UNSECURED;
153
- this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.UNSECURED;
154
- }
155
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
156
- + ` LockTargetState: ${this.LockMechanism.LockTargetState}, LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
143
+ await this.debugLog('BLEparseStatus');
144
+ // LockCurrentState
145
+ this.LockMechanism.LockCurrentState = serviceData.status === 'locked'
146
+ ? this.hap.Characteristic.LockCurrentState.SECURED : this.hap.Characteristic.LockCurrentState.UNSECURED;
147
+ await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
148
+ // LockTargetState
149
+ this.LockMechanism.LockTargetState = serviceData.status === 'locked'
150
+ ? this.hap.Characteristic.LockTargetState.SECURED : this.hap.Characteristic.LockTargetState.UNSECURED;
151
+ await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`);
157
152
  // Contact Sensor
158
- if (!this.device.lock?.hide_contactsensor) {
159
- switch (serviceData.door_open) {
160
- case 'opened':
161
- this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
162
- break;
163
- default:
164
- this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
165
- }
166
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
153
+ if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
154
+ this.ContactSensor.ContactSensorState = serviceData.door_open === 'opened'
155
+ ? this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED : this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
156
+ await this.debugLog(`ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
167
157
  }
168
- // Battery
158
+ // BatteryLevel
169
159
  this.Battery.BatteryLevel = Number(serviceData.battery);
170
- if (this.Battery.BatteryLevel < 10) {
171
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
172
- }
173
- else {
174
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
175
- }
176
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
177
- + ` BatteryLevel: ${this.Battery.BatteryLevel}, StatusLowBattery: ${this.Battery.StatusLowBattery}`);
160
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
161
+ // StatusLowBattery
162
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
163
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
164
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
178
165
  }
179
166
  async openAPIparseStatus(deviceStatus) {
180
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
181
- switch (deviceStatus.body.lockState) {
182
- case 'locked':
183
- this.LockMechanism.LockCurrentState = this.hap.Characteristic.LockCurrentState.SECURED;
184
- this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
185
- break;
186
- default:
187
- this.LockMechanism.LockCurrentState = this.hap.Characteristic.LockCurrentState.UNSECURED;
188
- this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.UNSECURED;
189
- }
190
- switch (deviceStatus.body.doorState) {
191
- case 'opened':
192
- this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
193
- break;
194
- default:
195
- this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
196
- }
197
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LockMechanism.LockTargetState}`);
198
- // Battery
199
- this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
200
- if (this.Battery.BatteryLevel < 10) {
201
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
202
- }
203
- else {
204
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
205
- }
206
- if (Number.isNaN(this.Battery.BatteryLevel)) {
207
- this.Battery.BatteryLevel = 100;
208
- }
209
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
210
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
167
+ await this.debugLog('openAPIparseStatus');
168
+ // LockCurrentState
169
+ this.LockMechanism.LockCurrentState = deviceStatus.lockState === 'locked'
170
+ ? this.hap.Characteristic.LockCurrentState.SECURED : this.hap.Characteristic.LockCurrentState.UNSECURED;
171
+ await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
172
+ // LockTargetState
173
+ this.LockMechanism.LockTargetState = deviceStatus.lockState === 'locked'
174
+ ? this.hap.Characteristic.LockTargetState.SECURED : this.hap.Characteristic.LockTargetState.UNSECURED;
175
+ await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`);
176
+ // ContactSensorState
177
+ if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
178
+ this.ContactSensor.ContactSensorState = deviceStatus.doorState === 'opened'
179
+ ? this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED : this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
180
+ await this.debugLog(`ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
181
+ }
182
+ // BatteryLevel
183
+ this.Battery.BatteryLevel = Number(deviceStatus.battery);
184
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
185
+ // StatusLowBattery
186
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
187
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
188
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
211
189
  // Firmware Version
212
- const version = deviceStatus.body.version?.toString();
213
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
214
- if (deviceStatus.body.version) {
215
- const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
190
+ if (deviceStatus.version) {
191
+ const version = deviceStatus.version.toString();
192
+ await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
193
+ const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
216
194
  this.accessory
217
195
  .getService(this.hap.Service.AccessoryInformation)
218
196
  .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
@@ -220,15 +198,27 @@ export class Lock extends deviceBase {
220
198
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
221
199
  .updateValue(deviceVersion);
222
200
  this.accessory.context.deviceVersion = deviceVersion;
223
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
201
+ await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
224
202
  }
225
203
  }
204
+ async parseStatusWebhook(context) {
205
+ await this.debugLog('parseStatusWebhook');
206
+ await this.debugLog(`(lockState) = Webhook:(${context.lockState}), current:(${this.LockMechanism.LockCurrentState})`);
207
+ // LockCurrentState
208
+ this.LockMechanism.LockCurrentState = context.lockState === 'LOCKED'
209
+ ? this.hap.Characteristic.LockCurrentState.SECURED : this.hap.Characteristic.LockCurrentState.UNSECURED;
210
+ await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
211
+ // LockTargetState
212
+ this.LockMechanism.LockTargetState = context.lockState === 'LOCKED'
213
+ ? this.hap.Characteristic.LockTargetState.SECURED : this.hap.Characteristic.LockTargetState.UNSECURED;
214
+ await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`);
215
+ }
226
216
  /**
227
217
  * Asks the SwitchBot API for the latest device information
228
218
  */
229
219
  async refreshStatus() {
230
220
  if (!this.device.enableCloudService && this.OpenAPI) {
231
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus enableCloudService: ${this.device.enableCloudService}`);
221
+ await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`);
232
222
  }
233
223
  else if (this.BLE) {
234
224
  await this.BLERefreshStatus();
@@ -238,12 +228,11 @@ export class Lock extends deviceBase {
238
228
  }
239
229
  else {
240
230
  await this.offlineOff();
241
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
242
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
231
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`);
243
232
  }
244
233
  }
245
234
  async BLERefreshStatus() {
246
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
235
+ await this.debugLog('BLERefreshStatus');
247
236
  const switchbot = await this.switchbotBLE();
248
237
  if (switchbot === undefined) {
249
238
  await this.BLERefreshConnection(switchbot);
@@ -254,57 +243,56 @@ export class Lock extends deviceBase {
254
243
  // Start to monitor advertisement packets
255
244
  const serviceData = await this.monitorAdvertisementPackets(switchbot);
256
245
  // Update HomeKit
257
- if (serviceData.model !== '' && serviceData.modelName !== '') {
246
+ if ((serviceData.model === SwitchBotBLEModel.Lock || SwitchBotBLEModel.LockPro)
247
+ && (serviceData.modelName === SwitchBotBLEModelName.Lock || SwitchBotBLEModelName.LockPro)) {
258
248
  await this.BLEparseStatus(serviceData);
259
249
  await this.updateHomeKitCharacteristics();
260
250
  }
261
251
  else {
262
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
252
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
263
253
  await this.BLERefreshConnection(switchbot);
264
254
  }
265
255
  })();
266
256
  }
267
257
  }
268
258
  async openAPIRefreshStatus() {
269
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
259
+ await this.debugLog('openAPIRefreshStatus');
270
260
  try {
271
261
  const { body, statusCode } = await this.deviceRefreshStatus();
272
262
  const deviceStatus = await body.json();
273
- await this.refreshStatusCodes(statusCode, deviceStatus);
263
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
274
264
  ;
275
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
276
- await this.successfulRefreshStatus(statusCode, deviceStatus);
277
- await this.openAPIparseStatus(deviceStatus);
265
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
266
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
267
+ await this.openAPIparseStatus(deviceStatus.body);
278
268
  await this.updateHomeKitCharacteristics();
279
269
  }
280
270
  else {
281
- await this.statusCodes(statusCode, deviceStatus);
271
+ await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
272
+ await this.debugWarnLog(statusCode, deviceStatus);
282
273
  }
283
274
  }
284
275
  catch (e) {
285
276
  await this.apiError(e);
286
- await this.openAPIRefreshError(e);
277
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
287
278
  }
288
279
  }
289
- async registerWebhook(accessory, device) {
290
- if (device.webhook) {
291
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
292
- this.platform.webhookEventHandler[device.deviceId] = async (context) => {
280
+ async registerWebhook() {
281
+ if (this.device.webhook) {
282
+ await this.debugLog('is listening webhook.');
283
+ this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
293
284
  try {
294
- this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
295
- const { lockState } = context;
296
- const { LockCurrentState } = this.LockMechanism;
297
- this.debugLog(`${device.deviceType}: ${accessory.displayName} (lockState) = Webhook:(${lockState}), current:(${LockCurrentState})`);
298
- this.LockMechanism.LockCurrentState = lockState === 'LOCKED' ? 1 : 0;
299
- this.updateHomeKitCharacteristics();
285
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
286
+ await this.parseStatusWebhook(context);
287
+ await this.updateHomeKitCharacteristics();
300
288
  }
301
289
  catch (e) {
302
- this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
290
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
303
291
  }
304
292
  };
305
293
  }
306
294
  else {
307
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
295
+ await this.debugLog('is not listening webhook.');
308
296
  }
309
297
  }
310
298
  /**
@@ -315,7 +303,7 @@ export class Lock extends deviceBase {
315
303
  */
316
304
  async pushChanges() {
317
305
  if (!this.device.enableCloudService && this.OpenAPI) {
318
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
306
+ await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`);
319
307
  }
320
308
  else if (this.BLE) {
321
309
  await this.BLEpushChanges();
@@ -325,7 +313,7 @@ export class Lock extends deviceBase {
325
313
  }
326
314
  else {
327
315
  await this.offlineOff();
328
- await this.pushChangeDisabled();
316
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`);
329
317
  }
330
318
  // Refresh the status from the API
331
319
  interval(15000)
@@ -336,60 +324,63 @@ export class Lock extends deviceBase {
336
324
  });
337
325
  }
338
326
  async BLEpushChanges() {
339
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
327
+ await this.debugLog('BLEpushChanges');
340
328
  if (this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) {
341
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges LockTargetState: ${this.LockMechanism.LockTargetState}`
342
- + ` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
343
- const switchbot = await this.platform.connectBLE();
344
- // Convert to BLE Address
329
+ const switchbot = await this.platform.connectBLE(this.accessory, this.device);
345
330
  await this.convertBLEAddress();
346
- switchbot
347
- .discover({
348
- model: '',
349
- id: this.device.bleMac,
350
- })
351
- .then(() => {
352
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
353
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
354
- + `LockTargetState: ${this.LockMechanism.LockTargetState} sent over BLE, sent successfully`);
355
- this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
356
- })
357
- .catch(async (e) => {
358
- this.apiError(e);
359
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
360
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
331
+ if (switchbot !== false) {
332
+ switchbot
333
+ .discover({ model: this.device.bleModel, id: this.device.bleMac })
334
+ .then(async (device_list) => {
335
+ return await this.retryBLE({
336
+ max: await this.maxRetryBLE(),
337
+ fn: async () => {
338
+ if (this.LockMechanism.LockTargetState === this.hap.Characteristic.LockTargetState.SECURED) {
339
+ return await device_list[0].lock({ id: this.device.bleMac });
340
+ }
341
+ else {
342
+ return await device_list[0].unlock({ id: this.device.bleMac });
343
+ }
344
+ },
345
+ });
346
+ })
347
+ .then(async () => {
348
+ await this.successLog(`LockTargetState: ${this.LockMechanism.LockTargetState} sent over SwitchBot BLE, sent successfully`);
349
+ await this.updateHomeKitCharacteristics();
350
+ })
351
+ .catch(async (e) => {
352
+ await this.apiError(e);
353
+ await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
354
+ await this.BLEPushConnection();
355
+ });
356
+ }
357
+ else {
358
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
361
359
  await this.BLEPushConnection();
362
- });
360
+ }
363
361
  }
364
362
  else {
365
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.`
366
- + `LockTargetState: ${this.LockMechanism.LockTargetState}, `
367
- + `LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
363
+ await this.debugLog(`No changes (BLEpushChanges), LockTargetState: ${this.LockMechanism.LockTargetState},`
364
+ + ` LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
368
365
  }
369
366
  }
370
367
  async openAPIpushChanges(LatchUnlock) {
371
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
368
+ await this.debugLog('openAPIpushChanges');
372
369
  if ((this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) || LatchUnlock) {
373
370
  // Determine the command based on the LockTargetState or the forceUnlock parameter
374
- let command = '';
375
- if (LatchUnlock) {
376
- command = 'unlock';
377
- }
378
- else {
379
- command = this.LockMechanism.LockTargetState ? 'lock' : 'unlock';
380
- }
371
+ const command = LatchUnlock ? 'unlock' : this.LockMechanism.LockTargetState ? 'lock' : 'unlock';
381
372
  const bodyChange = JSON.stringify({
382
373
  command: `${command}`,
383
374
  parameter: 'default',
384
375
  commandType: 'command',
385
376
  });
386
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
377
+ await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`);
387
378
  try {
388
379
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
389
380
  const deviceStatus = await body.json();
390
- await this.pushStatusCodes(statusCode, deviceStatus);
391
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
392
- await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
381
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
382
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
383
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
393
384
  await this.updateHomeKitCharacteristics();
394
385
  }
395
386
  else {
@@ -398,25 +389,24 @@ export class Lock extends deviceBase {
398
389
  }
399
390
  }
400
391
  catch (e) {
401
- this.apiError(e);
402
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
403
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
392
+ await this.apiError(e);
393
+ await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
404
394
  }
405
395
  }
406
396
  else {
407
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges, LockTargetState: `
408
- + `${this.LockMechanism.LockTargetState}, LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
397
+ await this.debugLog(`No changes (openAPIpushChanges), LockCurrentState: ${this.LockMechanism.LockCurrentState},`
398
+ + ` TargetPosition: ${this.LockMechanism.LockTargetState}`);
409
399
  }
410
400
  }
411
401
  /**
412
402
  * Handle requests to set the value of the "On" characteristic
413
403
  */
414
404
  async LockTargetStateSet(value) {
415
- if (this.LockMechanism.LockTargetState === this.accessory.context.LockTargetState) {
416
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set LockTargetState: ${value}`);
405
+ if (this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) {
406
+ await this.infoLog(`Set LockTargetState: ${value}`);
417
407
  }
418
408
  else {
419
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
409
+ await this.debugLog(`No Changes, LockTargetState: ${value}`);
420
410
  }
421
411
  this.LockMechanism.LockTargetState = value;
422
412
  this.doLockUpdate.next();
@@ -425,116 +415,81 @@ export class Lock extends deviceBase {
425
415
  * Handle requests to set the value of the "On" characteristic
426
416
  */
427
417
  async OnSet(value) {
428
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch Button Set On: ${value}`);
418
+ await this.debugLog(`Latch Button Set On: ${value}`);
429
419
  if (value) {
430
- this.debugLog('Attempting to open the latch');
431
- this.openAPIpushChanges(value).then(() => {
432
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch opened successfully`);
433
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
434
- + ` SwitchService is: ${this.Switch.Service ? 'available' : 'not available'}`);
420
+ await this.debugLog('Attempting to open the latch');
421
+ this.openAPIpushChanges(value).then(async () => {
422
+ await this.debugLog('Latch opened successfully');
423
+ await this.debugLog(`SwitchService is: ${this.Switch?.Service ? 'available' : 'not available'}`);
435
424
  // simulate button press to turn the switch back off
436
- if (this.Switch.Service) {
425
+ if (this.Switch?.Service) {
437
426
  const SwitchService = this.Switch.Service;
438
427
  // Simulate a button press by waiting a short period before turning the switch off
439
- setTimeout(() => {
428
+ setTimeout(async () => {
440
429
  SwitchService.getCharacteristic(this.hap.Characteristic.On).updateValue(false);
441
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch button switched off automatically.`);
430
+ await this.debugLog('Latch button switched off automatically.');
442
431
  }, 500); // 500 ms delay
443
432
  }
444
- }).catch((e) => {
433
+ }).catch(async (e) => {
445
434
  // Log the error if the operation failed
446
- this.debugLog(`Error opening latch: ${e}`);
435
+ await this.debugLog(`Error opening latch: ${e}`);
447
436
  // Ensure we turn the switch back off even in case of an error
448
- if (this.Switch.Service) {
437
+ if (this.Switch?.Service) {
449
438
  this.Switch.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(false);
450
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch button switched off after an error.`);
439
+ await this.debugLog('Latch button switched off after an error.');
451
440
  }
452
441
  });
453
442
  }
454
443
  else {
455
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch is off, nothing to do`);
444
+ await this.debugLog('Switch is off, nothing to do');
456
445
  }
457
446
  this.Switch.On = value;
458
447
  this.doLockUpdate.next();
459
448
  }
460
449
  async updateHomeKitCharacteristics() {
461
- if (!this.device.lock?.hide_contactsensor) {
462
- if (this.ContactSensor.ContactSensorState === undefined) {
463
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
464
- }
465
- else {
466
- this.accessory.context.ContactSensorState = this.ContactSensor.ContactSensorState;
467
- this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.ContactSensor.ContactSensorState);
468
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
469
- + ` ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
470
- }
471
- }
472
- if (this.LockMechanism.LockTargetState === undefined) {
473
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockTargetState: ${this.LockMechanism.LockTargetState}`);
474
- }
475
- else {
476
- this.accessory.context.LockTargetState = this.LockMechanism.LockTargetState;
477
- this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.LockMechanism.LockTargetState);
478
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
479
- + ` LockTargetState: ${this.LockMechanism.LockTargetState}`);
480
- }
481
- if (this.LockMechanism.LockCurrentState === undefined) {
482
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
483
- }
484
- else {
485
- this.accessory.context.LockCurrentState = this.LockMechanism.LockCurrentState;
486
- this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.LockMechanism.LockCurrentState);
487
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
488
- + ` LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
489
- }
490
- if (this.Battery.BatteryLevel === undefined) {
491
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
492
- }
493
- else {
494
- this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
495
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
496
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
497
- + ` BatteryLevel: ${this.Battery.BatteryLevel}`);
498
- }
499
- if (this.Battery.StatusLowBattery === undefined) {
500
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
501
- }
502
- else {
503
- this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
504
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
505
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
506
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
507
- }
450
+ // LockCurrentState
451
+ await this.updateCharacteristic(this.LockMechanism.Service, this.hap.Characteristic.LockTargetState, this.LockMechanism.LockTargetState, 'LockTargetState');
452
+ // LockCurrentState
453
+ await this.updateCharacteristic(this.LockMechanism.Service, this.hap.Characteristic.LockCurrentState, this.LockMechanism.LockCurrentState, 'LockCurrentState');
454
+ // ContactSensorState
455
+ if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
456
+ await this.updateCharacteristic(this.ContactSensor.Service, this.hap.Characteristic.ContactSensorState, this.ContactSensor.ContactSensorState, 'ContactSensorState');
457
+ }
458
+ // BatteryLevel
459
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel, 'BatteryLevel');
460
+ // StatusLowBattery
461
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery, 'StatusLowBattery');
508
462
  }
509
463
  async BLEPushConnection() {
510
464
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
511
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
465
+ await this.warnLog('Using OpenAPI Connection to Push Changes');
512
466
  await this.openAPIpushChanges();
513
467
  }
514
468
  }
515
469
  async BLERefreshConnection(switchbot) {
516
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
517
- + ` ${JSON.stringify(switchbot)}`);
470
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchbot)}`);
518
471
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
519
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
472
+ await this.warnLog('Using OpenAPI Connection to Refresh Status');
520
473
  await this.openAPIRefreshStatus();
521
474
  }
522
475
  }
523
476
  async offlineOff() {
524
477
  if (this.device.offline) {
525
- if (!this.device.lock?.hide_contactsensor) {
526
- this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED);
527
- }
528
478
  this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED);
529
479
  this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED);
480
+ if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
481
+ this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED);
482
+ }
530
483
  }
531
484
  }
532
485
  async apiError(e) {
533
- if (!this.device.lock?.hide_contactsensor) {
534
- this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e);
535
- }
536
486
  this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, e);
537
487
  this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, e);
488
+ if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
489
+ this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e);
490
+ }
491
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
492
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
538
493
  }
539
494
  }
540
495
  //# sourceMappingURL=lock.js.map