@switchbot/homebridge-switchbot 3.5.1-beta.9 → 3.5.1

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 (159) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/config.schema.json +19 -3
  3. package/dist/device/blindtilt.d.ts +6 -4
  4. package/dist/device/blindtilt.d.ts.map +1 -1
  5. package/dist/device/blindtilt.js +60 -46
  6. package/dist/device/blindtilt.js.map +1 -1
  7. package/dist/device/bot.d.ts +6 -3
  8. package/dist/device/bot.d.ts.map +1 -1
  9. package/dist/device/bot.js +59 -25
  10. package/dist/device/bot.js.map +1 -1
  11. package/dist/device/ceilinglight.d.ts +6 -3
  12. package/dist/device/ceilinglight.d.ts.map +1 -1
  13. package/dist/device/ceilinglight.js +47 -29
  14. package/dist/device/ceilinglight.js.map +1 -1
  15. package/dist/device/colorbulb.d.ts +6 -3
  16. package/dist/device/colorbulb.d.ts.map +1 -1
  17. package/dist/device/colorbulb.js +53 -36
  18. package/dist/device/colorbulb.js.map +1 -1
  19. package/dist/device/contact.d.ts +6 -3
  20. package/dist/device/contact.d.ts.map +1 -1
  21. package/dist/device/contact.js +45 -31
  22. package/dist/device/contact.js.map +1 -1
  23. package/dist/device/curtain.d.ts +6 -4
  24. package/dist/device/curtain.d.ts.map +1 -1
  25. package/dist/device/curtain.js +41 -27
  26. package/dist/device/curtain.js.map +1 -1
  27. package/dist/device/device.d.ts +6 -3
  28. package/dist/device/device.d.ts.map +1 -1
  29. package/dist/device/device.js +59 -152
  30. package/dist/device/device.js.map +1 -1
  31. package/dist/device/fan.d.ts +6 -3
  32. package/dist/device/fan.d.ts.map +1 -1
  33. package/dist/device/fan.js +53 -32
  34. package/dist/device/fan.js.map +1 -1
  35. package/dist/device/hub.d.ts +6 -3
  36. package/dist/device/hub.d.ts.map +1 -1
  37. package/dist/device/hub.js +49 -30
  38. package/dist/device/hub.js.map +1 -1
  39. package/dist/device/humidifier.d.ts +6 -3
  40. package/dist/device/humidifier.d.ts.map +1 -1
  41. package/dist/device/humidifier.js +47 -28
  42. package/dist/device/humidifier.js.map +1 -1
  43. package/dist/device/iosensor.d.ts +6 -3
  44. package/dist/device/iosensor.d.ts.map +1 -1
  45. package/dist/device/iosensor.js +44 -27
  46. package/dist/device/iosensor.js.map +1 -1
  47. package/dist/device/lightstrip.d.ts +6 -3
  48. package/dist/device/lightstrip.d.ts.map +1 -1
  49. package/dist/device/lightstrip.js +46 -28
  50. package/dist/device/lightstrip.js.map +1 -1
  51. package/dist/device/lock.d.ts +6 -3
  52. package/dist/device/lock.d.ts.map +1 -1
  53. package/dist/device/lock.js +38 -25
  54. package/dist/device/lock.js.map +1 -1
  55. package/dist/device/meter.d.ts +6 -3
  56. package/dist/device/meter.d.ts.map +1 -1
  57. package/dist/device/meter.js +43 -27
  58. package/dist/device/meter.js.map +1 -1
  59. package/dist/device/meterplus.d.ts +6 -3
  60. package/dist/device/meterplus.d.ts.map +1 -1
  61. package/dist/device/meterplus.js +42 -27
  62. package/dist/device/meterplus.js.map +1 -1
  63. package/dist/device/motion.d.ts +6 -3
  64. package/dist/device/motion.d.ts.map +1 -1
  65. package/dist/device/motion.js +37 -24
  66. package/dist/device/motion.js.map +1 -1
  67. package/dist/device/plug.d.ts +6 -3
  68. package/dist/device/plug.d.ts.map +1 -1
  69. package/dist/device/plug.js +30 -17
  70. package/dist/device/plug.js.map +1 -1
  71. package/dist/device/robotvacuumcleaner.d.ts +6 -3
  72. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  73. package/dist/device/robotvacuumcleaner.js +37 -22
  74. package/dist/device/robotvacuumcleaner.js.map +1 -1
  75. package/dist/device/waterdetector.d.ts +6 -3
  76. package/dist/device/waterdetector.d.ts.map +1 -1
  77. package/dist/device/waterdetector.js +43 -26
  78. package/dist/device/waterdetector.js.map +1 -1
  79. package/dist/homebridge-ui/public/index.html +2 -2
  80. package/dist/irdevice/airconditioner.d.ts +1 -3
  81. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  82. package/dist/irdevice/airconditioner.js +67 -177
  83. package/dist/irdevice/airconditioner.js.map +1 -1
  84. package/dist/irdevice/airpurifier.d.ts +0 -1
  85. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  86. package/dist/irdevice/airpurifier.js +24 -53
  87. package/dist/irdevice/airpurifier.js.map +1 -1
  88. package/dist/irdevice/camera.d.ts.map +1 -1
  89. package/dist/irdevice/camera.js +12 -17
  90. package/dist/irdevice/camera.js.map +1 -1
  91. package/dist/irdevice/fan.d.ts.map +1 -1
  92. package/dist/irdevice/fan.js +22 -38
  93. package/dist/irdevice/fan.js.map +1 -1
  94. package/dist/irdevice/irdevice.d.ts +22 -10
  95. package/dist/irdevice/irdevice.d.ts.map +1 -1
  96. package/dist/irdevice/irdevice.js +94 -100
  97. package/dist/irdevice/irdevice.js.map +1 -1
  98. package/dist/irdevice/light.d.ts.map +1 -1
  99. package/dist/irdevice/light.js +20 -38
  100. package/dist/irdevice/light.js.map +1 -1
  101. package/dist/irdevice/other.d.ts.map +1 -1
  102. package/dist/irdevice/other.js +79 -77
  103. package/dist/irdevice/other.js.map +1 -1
  104. package/dist/irdevice/tv.d.ts.map +1 -1
  105. package/dist/irdevice/tv.js +38 -53
  106. package/dist/irdevice/tv.js.map +1 -1
  107. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  108. package/dist/irdevice/vacuumcleaner.js +11 -16
  109. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  110. package/dist/irdevice/waterheater.d.ts.map +1 -1
  111. package/dist/irdevice/waterheater.js +11 -16
  112. package/dist/irdevice/waterheater.js.map +1 -1
  113. package/dist/platform.d.ts +4 -6
  114. package/dist/platform.d.ts.map +1 -1
  115. package/dist/platform.js +564 -665
  116. package/dist/platform.js.map +1 -1
  117. package/dist/settings.d.ts +10 -8
  118. package/dist/settings.d.ts.map +1 -1
  119. package/dist/settings.js.map +1 -1
  120. package/dist/types/bledevicestatus.d.ts +2 -1
  121. package/dist/types/bledevicestatus.d.ts.map +1 -1
  122. package/dist/types/devicestatus.d.ts +1 -1
  123. package/dist/types/devicestatus.d.ts.map +1 -1
  124. package/package.json +11 -11
  125. package/src/device/blindtilt.ts +64 -48
  126. package/src/device/bot.ts +79 -26
  127. package/src/device/ceilinglight.ts +57 -31
  128. package/src/device/colorbulb.ts +57 -43
  129. package/src/device/contact.ts +49 -31
  130. package/src/device/curtain.ts +51 -28
  131. package/src/device/device.ts +61 -135
  132. package/src/device/fan.ts +67 -33
  133. package/src/device/hub.ts +62 -33
  134. package/src/device/humidifier.ts +60 -33
  135. package/src/device/iosensor.ts +51 -30
  136. package/src/device/lightstrip.ts +52 -29
  137. package/src/device/lock.ts +55 -26
  138. package/src/device/meter.ts +60 -29
  139. package/src/device/meterplus.ts +56 -29
  140. package/src/device/motion.ts +50 -26
  141. package/src/device/plug.ts +38 -18
  142. package/src/device/robotvacuumcleaner.ts +53 -24
  143. package/src/device/waterdetector.ts +62 -28
  144. package/src/homebridge-ui/public/index.html +2 -2
  145. package/src/irdevice/airconditioner.ts +76 -165
  146. package/src/irdevice/airpurifier.ts +29 -49
  147. package/src/irdevice/camera.ts +13 -16
  148. package/src/irdevice/fan.ts +25 -35
  149. package/src/irdevice/irdevice.ts +97 -96
  150. package/src/irdevice/light.ts +21 -35
  151. package/src/irdevice/other.ts +79 -77
  152. package/src/irdevice/tv.ts +40 -51
  153. package/src/irdevice/vacuumcleaner.ts +12 -15
  154. package/src/irdevice/waterheater.ts +12 -15
  155. package/src/platform.ts +566 -696
  156. package/src/settings.ts +11 -8
  157. package/src/types/bledevicestatus.ts +4 -2
  158. package/src/types/devicestatus.ts +1 -1
  159. package/.github/npm-version-script.cjs +0 -81
@@ -42,6 +42,15 @@ export class IOSensor extends deviceBase {
42
42
  CurrentTemperature: CharacteristicValue;
43
43
  };
44
44
 
45
+ // OpenAPI
46
+ deviceStatus!: outdoorMeterStatus;
47
+
48
+ //Webhook
49
+ webhookContext!: outdoorMeterWebhookContext;
50
+
51
+ // BLE
52
+ serviceData!: outdoorMeterServiceData;
53
+
45
54
  // Updates
46
55
  ioSensorUpdateInProgress!: boolean;
47
56
  doIOSensorUpdate: Subject<void>;
@@ -52,6 +61,9 @@ export class IOSensor extends deviceBase {
52
61
  device: device & devicesConfig,
53
62
  ) {
54
63
  super(platform, accessory, device);
64
+ // Set category
65
+ accessory.category = this.hap.Categories.SENSOR;
66
+
55
67
  // this is subject we use to track when we need to POST changes to the SwitchBot API
56
68
  this.doIOSensorUpdate = new Subject();
57
69
  this.ioSensorUpdateInProgress = false;
@@ -85,7 +97,7 @@ export class IOSensor extends deviceBase {
85
97
  // InitializeTemperature Sensor Service
86
98
  if (device.iosensor?.hide_temperature) {
87
99
  if (this.TemperatureSensor) {
88
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Temperature Sensor Service`);
100
+ this.debugLog('Removing Temperature Sensor Service');
89
101
  this.TemperatureSensor.Service = this.accessory.getService(this.hap.Service.TemperatureSensor) as Service;
90
102
  accessory.removeService(this.TemperatureSensor.Service);
91
103
  }
@@ -117,7 +129,7 @@ export class IOSensor extends deviceBase {
117
129
  // Initialize Humidity Sensor Service
118
130
  if (device.iosensor?.hide_humidity) {
119
131
  if (this.HumiditySensor) {
120
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Humidity Sensor Service`);
132
+ this.debugLog('Removing Humidity Sensor Service');
121
133
  this.HumiditySensor.Service = this.accessory.getService(this.hap.Service.HumiditySensor) as Service;
122
134
  accessory.removeService(this.HumiditySensor.Service);
123
135
  }
@@ -143,12 +155,11 @@ export class IOSensor extends deviceBase {
143
155
  }
144
156
 
145
157
  // Retrieve initial values and updateHomekit
158
+ this.debugLog('Retrieve initial values and update Homekit');
146
159
  this.refreshStatus();
147
160
 
148
- // Retrieve initial values and updateHomekit
149
- this.updateHomeKitCharacteristics();
150
-
151
161
  //regisiter webhook event handler
162
+ this.debugLog('Registering Webhook Event Handler');
152
163
  this.registerWebhook();
153
164
 
154
165
  // Start an update interval
@@ -159,11 +170,14 @@ export class IOSensor extends deviceBase {
159
170
  });
160
171
  }
161
172
 
162
- async BLEparseStatus(serviceData: outdoorMeterServiceData): Promise<void> {
173
+ async BLEparseStatus(): Promise<void> {
163
174
  await this.debugLog('BLEparseStatus');
175
+ await this.debugLog(`(battery, temperature, humidity) = BLE:(${this.serviceData.battery}, ${this.serviceData.temperature.c},`
176
+ + ` ${this.serviceData.humidity}), current:(${this.Battery.BatteryLevel}, ${this.TemperatureSensor?.CurrentTemperature},`
177
+ + ` ${this.HumiditySensor?.CurrentRelativeHumidity})`);
164
178
 
165
179
  // BatteryLevel
166
- this.Battery.BatteryLevel = Number(serviceData.battery);
180
+ this.Battery.BatteryLevel = this.serviceData.battery;
167
181
  await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
168
182
 
169
183
  // StatusLowBattery
@@ -173,23 +187,26 @@ export class IOSensor extends deviceBase {
173
187
 
174
188
  // CurrentRelativeHumidity
175
189
  if (!this.device.iosensor?.hide_humidity && this.HumiditySensor?.Service) {
176
- this.HumiditySensor.CurrentRelativeHumidity = serviceData.humidity;
190
+ this.HumiditySensor.CurrentRelativeHumidity = this.serviceData.humidity;
177
191
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
178
192
  }
179
193
 
180
194
  // Current Temperature
181
195
  if (!this.device.meter?.hide_temperature && this.TemperatureSensor?.Service) {
182
- const CELSIUS = serviceData.temperature.c < 0 ? 0 : serviceData.temperature.c > 100 ? 100 : serviceData.temperature.c;
196
+ const CELSIUS = this.serviceData.temperature.c < 0 ? 0 : this.serviceData.temperature.c > 100 ? 100 : this.serviceData.temperature.c;
183
197
  this.TemperatureSensor.CurrentTemperature = CELSIUS;
184
198
  await this.debugLog(`Temperature: ${this.TemperatureSensor.CurrentTemperature}°c`);
185
199
  }
186
200
  }
187
201
 
188
- async openAPIparseStatus(deviceStatus: outdoorMeterStatus): Promise<void> {
202
+ async openAPIparseStatus(): Promise<void> {
189
203
  await this.debugLog('openAPIparseStatus');
204
+ await this.debugLog(`(battery, temperature, humidity) = OpenAPI:(${this.deviceStatus.battery}, ${this.deviceStatus.temperature},`
205
+ + ` ${this.deviceStatus.humidity}), current:(${this.Battery.BatteryLevel}, ${this.TemperatureSensor?.CurrentTemperature},`
206
+ + ` ${this.HumiditySensor?.CurrentRelativeHumidity})`);
190
207
 
191
208
  // BatteryLevel
192
- this.Battery.BatteryLevel = Number(deviceStatus.battery);
209
+ this.Battery.BatteryLevel = this.deviceStatus.battery;
193
210
  await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
194
211
 
195
212
  // StatusLowBattery
@@ -199,20 +216,20 @@ export class IOSensor extends deviceBase {
199
216
 
200
217
  // CurrentRelativeHumidity
201
218
  if (!this.device.iosensor?.hide_humidity && this.HumiditySensor?.Service) {
202
- this.HumiditySensor.CurrentRelativeHumidity = deviceStatus.humidity;
219
+ this.HumiditySensor.CurrentRelativeHumidity = this.deviceStatus.humidity;
203
220
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
204
221
  }
205
222
 
206
223
  // Current Temperature
207
224
  if (!this.device.meter?.hide_temperature && this.TemperatureSensor?.Service) {
208
- this.TemperatureSensor.CurrentTemperature = deviceStatus.temperature;
225
+ this.TemperatureSensor.CurrentTemperature = this.deviceStatus.temperature;
209
226
  await this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`);
210
227
  }
211
228
 
212
229
  // Firmware Version
213
- const version = deviceStatus.version.toString();
214
- await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
215
- if (deviceStatus.version) {
230
+ if (this.deviceStatus.version) {
231
+ const version = this.deviceStatus.version.toString();
232
+ await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
216
233
  const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
217
234
  this.accessory
218
235
  .getService(this.hap.Service.AccessoryInformation)!
@@ -220,29 +237,30 @@ export class IOSensor extends deviceBase {
220
237
  .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
221
238
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
222
239
  .updateValue(deviceVersion);
223
- this.accessory.context.deviceVersion = deviceVersion;
224
- await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
240
+ this.accessory.context.version = deviceVersion;
241
+ await this.debugSuccessLog(`version: ${this.accessory.context.version}`);
225
242
  }
226
243
  }
227
244
 
228
- async parseStatusWebhook(context: outdoorMeterWebhookContext): Promise<void> {
245
+ async parseStatusWebhook(): Promise<void> {
229
246
  await this.debugLog('parseStatusWebhook');
230
- await this.debugLog(`(scale, temperature, humidity) = Webhook:(${context.scale}, ${convertUnits(context.temperature, context.scale,
231
- this.device.iosensor?.convertUnitTo)}, ${context.humidity}), current:(${this.TemperatureSensor?.CurrentTemperature},`
232
- + ` ${this.HumiditySensor?.CurrentRelativeHumidity})`);
247
+ await this.debugLog(`(scale, temperature, humidity) = Webhook:(${this.webhookContext.scale}, ${convertUnits(this.webhookContext.temperature,
248
+ this.webhookContext.scale, this.device.iosensor?.convertUnitTo)}, ${this.webhookContext.humidity}),`
249
+ + ` current:(${this.TemperatureSensor?.CurrentTemperature}, ${this.HumiditySensor?.CurrentRelativeHumidity})`);
233
250
 
234
- if (context.scale !== 'CELSIUS' && this.device.iosensor?.convertUnitTo === undefined) {
235
- await this.warnLog(`received a non-CELSIUS Webhook scale: ${context.scale}, Use the *convertUnitsTo* config under Hub settings,`
251
+ if (this.webhookContext.scale !== 'CELSIUS' && this.device.iosensor?.convertUnitTo === undefined) {
252
+ await this.warnLog(`received a non-CELSIUS Webhook scale: ${this.webhookContext.scale}, Use the *convertUnitsTo* config under Hub settings,`
236
253
  + ' if displaying incorrectly in HomeKit.');
237
254
  }
238
255
  // CurrentRelativeHumidity
239
256
  if (this.device.iosensor?.hide_humidity && this.HumiditySensor?.Service) {
240
- this.HumiditySensor.CurrentRelativeHumidity = context.humidity;
257
+ this.HumiditySensor.CurrentRelativeHumidity = this.webhookContext.humidity;
241
258
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
242
259
  }
243
260
  // CurrentTemperature
244
261
  if (this.device.iosensor?.hide_temperature && this.TemperatureSensor?.Service) {
245
- this.TemperatureSensor.CurrentTemperature = convertUnits(context.temperature, context.scale, this.device.iosensor?.convertUnitTo);
262
+ this.TemperatureSensor.CurrentTemperature = convertUnits(this.webhookContext.temperature, this.webhookContext.scale,
263
+ this.device.iosensor?.convertUnitTo);
246
264
  await this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`);
247
265
  }
248
266
  }
@@ -273,10 +291,11 @@ export class IOSensor extends deviceBase {
273
291
  // Start to monitor advertisement packets
274
292
  (async () => {
275
293
  // Start to monitor advertisement packets
276
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as unknown as outdoorMeterServiceData;
294
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as outdoorMeterServiceData;
277
295
  // Update HomeKit
278
296
  if (serviceData.model === SwitchBotBLEModel.OutdoorMeter && serviceData.modelName === SwitchBotBLEModelName.OutdoorMeter) {
279
- await this.BLEparseStatus(serviceData);
297
+ this.serviceData = serviceData;
298
+ await this.BLEparseStatus();
280
299
  await this.updateHomeKitCharacteristics();
281
300
  } else {
282
301
  await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
@@ -294,7 +313,8 @@ export class IOSensor extends deviceBase {
294
313
  await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);;
295
314
  if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
296
315
  await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
297
- await this.openAPIparseStatus(deviceStatus.body);
316
+ this.deviceStatus = deviceStatus.body;
317
+ await this.openAPIparseStatus();
298
318
  await this.updateHomeKitCharacteristics();
299
319
  } else {
300
320
  await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -312,7 +332,8 @@ export class IOSensor extends deviceBase {
312
332
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: outdoorMeterWebhookContext) => {
313
333
  try {
314
334
  await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
315
- await this.parseStatusWebhook(context);
335
+ this.webhookContext = context;
336
+ await this.parseStatusWebhook();
316
337
  await this.updateHomeKitCharacteristics();
317
338
  } catch (e: any) {
318
339
  await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
@@ -32,6 +32,15 @@ export class StripLight extends deviceBase {
32
32
  ColorTemperature?: CharacteristicValue;
33
33
  };
34
34
 
35
+ // OpenAPI
36
+ deviceStatus!: stripLightStatus;
37
+
38
+ //Webhook
39
+ webhookContext!: stripLightWebhookContext;
40
+
41
+ // BLE
42
+ serviceData!: stripLightServiceData;
43
+
35
44
  // Adaptive Lighting
36
45
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
37
46
  adaptiveLightingShift?: number;
@@ -46,6 +55,9 @@ export class StripLight extends deviceBase {
46
55
  device: device & devicesConfig,
47
56
  ) {
48
57
  super(platform, accessory, device);
58
+ // Set category
59
+ accessory.category = this.hap.Categories.LIGHTBULB;
60
+
49
61
  // Adaptive Lighting
50
62
  this.adaptiveLighting(device);
51
63
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -146,12 +158,11 @@ export class StripLight extends deviceBase {
146
158
  .onSet(this.SaturationSet.bind(this));
147
159
 
148
160
  // Retrieve initial values and updateHomekit
161
+ this.debugLog('Retrieve initial values and update Homekit');
149
162
  this.refreshStatus();
150
163
 
151
- // Update Homekit
152
- this.updateHomeKitCharacteristics();
153
-
154
164
  //regisiter webhook event handler
165
+ this.debugLog('Registering Webhook Event Handler');
155
166
  this.registerWebhook();
156
167
 
157
168
  // Start an update interval
@@ -181,20 +192,24 @@ export class StripLight extends deviceBase {
181
192
  });
182
193
  }
183
194
 
184
- async BLEparseStatus(serviceData: stripLightServiceData): Promise<void> {
195
+ async BLEparseStatus(): Promise<void> {
185
196
  await this.debugLog('BLEparseStatus');
197
+ await this.debugLog(`(power, brightness, color) = BLE:(${this.serviceData.power}, ${this.serviceData.brightness},`
198
+ + ` ${this.serviceData.red}:${this.serviceData.green}:${this.serviceData.blue}), current:(${this.LightBulb.On},`
199
+ + ` ${this.LightBulb.Brightness}, ${this.LightBulb.Hue}, ${this.LightBulb.Saturation})`);
200
+
186
201
  // On
187
- this.LightBulb.On = serviceData.power;
202
+ this.LightBulb.On = this.serviceData.power;
188
203
  await this.debugLog(`On: ${this.LightBulb.On}`);
189
204
 
190
205
  // Brightness
191
- this.LightBulb.Brightness = serviceData.brightness;
206
+ this.LightBulb.Brightness = this.serviceData.brightness;
192
207
  await this.debugLog(`Brightness: ${this.LightBulb.Brightness}`);
193
208
 
194
209
  // Color, Hue & Brightness
195
- await this.debugLog(`red: ${serviceData.red}, green: ${serviceData.green}, blue: ${serviceData.blue}`);
196
- const [hue, saturation] = rgb2hs(serviceData.red, serviceData.green, serviceData.blue);
197
- await this.debugLog(`hs: ${JSON.stringify(rgb2hs(serviceData.red, serviceData.green, serviceData.blue))}`);
210
+ await this.debugLog(`red: ${this.serviceData.red}, green: ${this.serviceData.green}, blue: ${this.serviceData.blue}`);
211
+ const [hue, saturation] = rgb2hs(this.serviceData.red, this.serviceData.green, this.serviceData.blue);
212
+ await this.debugLog(`hs: ${JSON.stringify(rgb2hs(this.serviceData.red, this.serviceData.green, this.serviceData.blue))}`);
198
213
 
199
214
  // Hue
200
215
  this.LightBulb.Hue = hue;
@@ -205,19 +220,23 @@ export class StripLight extends deviceBase {
205
220
  this.debugLog(`Saturation: ${this.LightBulb.Saturation}`);
206
221
  }
207
222
 
208
- async openAPIparseStatus(deviceStatus: stripLightStatus): Promise<void> {
223
+ async openAPIparseStatus(): Promise<void> {
209
224
  await this.debugLog('openAPIparseStatus');
225
+ await this.debugLog(`(power, brightness, color) = API:(${this.deviceStatus.power}, ${this.deviceStatus.brightness},`
226
+ + ` ${this.deviceStatus.color}), current:(${this.LightBulb.On}, ${this.LightBulb.Brightness}, ${this.LightBulb.Hue},`
227
+ + ` ${this.LightBulb.Saturation})`);
228
+
210
229
  // On
211
- this.LightBulb.On = deviceStatus.power === 'on' ? true : false;
230
+ this.LightBulb.On = this.deviceStatus.power === 'on' ? true : false;
212
231
  await this.debugLog(`On: ${this.LightBulb.On}`);
213
232
 
214
233
  // Brightness
215
- this.LightBulb.Brightness = deviceStatus.brightness;
234
+ this.LightBulb.Brightness = this.deviceStatus.brightness;
216
235
  await this.debugLog(`Brightness: ${this.LightBulb.Brightness}`);
217
236
 
218
237
  // Color, Hue & Brightness
219
- await this.debugLog(`color: ${JSON.stringify(deviceStatus.color)}`);
220
- const [red, green, blue] = deviceStatus.color.split(':');
238
+ await this.debugLog(`color: ${JSON.stringify(this.deviceStatus.color)}`);
239
+ const [red, green, blue] = this.deviceStatus.color.split(':');
221
240
  await this.debugLog(`red: ${JSON.stringify(red)}, green: ${JSON.stringify(green)}, blue: ${JSON.stringify(blue)}`);
222
241
  const [hue, saturation] = rgb2hs(red, green, blue);
223
242
  await this.debugLog(`hs: ${JSON.stringify(rgb2hs(red, green, blue))}`);
@@ -231,9 +250,9 @@ export class StripLight extends deviceBase {
231
250
  await this.debugLog(`Saturation: ${this.LightBulb.Saturation}`);
232
251
 
233
252
  // Firmware Version
234
- const version = deviceStatus.version.toString();
235
- await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
236
- if (deviceStatus.version) {
253
+ if (this.deviceStatus.version) {
254
+ const version = this.deviceStatus.version.toString();
255
+ await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
237
256
  const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
238
257
  this.accessory
239
258
  .getService(this.hap.Service.AccessoryInformation)!
@@ -241,27 +260,28 @@ export class StripLight extends deviceBase {
241
260
  .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
242
261
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
243
262
  .updateValue(deviceVersion);
244
- this.accessory.context.deviceVersion = deviceVersion;
245
- await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
263
+ this.accessory.context.version = deviceVersion;
264
+ await this.debugSuccessLog(`version: ${this.accessory.context.version}`);
246
265
  }
247
266
  }
248
267
 
249
- async parseStatusWebhook(context: stripLightWebhookContext): Promise<void> {
268
+ async parseStatusWebhook(): Promise<void> {
250
269
  await this.debugLog('parseStatusWebhook');
251
- await this.debugLog(`(powerState, brightness, color) = Webhook:(${context.powerState}, ${context.brightness}, ${context.color}),`
252
- + ` current:(${this.LightBulb.On}, ${this.LightBulb.Brightness}, ${this.LightBulb.Hue}, ${this.LightBulb.Saturation})`);
270
+ await this.debugLog(`(powerState, brightness, color) = Webhook:(${this.webhookContext.powerState}, ${this.webhookContext.brightness},`
271
+ + ` ${this.webhookContext.color}), current:(${this.LightBulb.On}, ${this.LightBulb.Brightness}, ${this.LightBulb.Hue},`
272
+ + ` ${this.LightBulb.Saturation})`);
253
273
 
254
274
  // On
255
- this.LightBulb.On = context.powerState === 'ON' ? true : false;
275
+ this.LightBulb.On = this.webhookContext.powerState === 'ON' ? true : false;
256
276
  await this.debugLog(`On: ${this.LightBulb.On}`);
257
277
 
258
278
  // Brightness
259
- this.LightBulb.Brightness = context.brightness;
279
+ this.LightBulb.Brightness = this.webhookContext.brightness;
260
280
  await this.debugLog(`Brightness: ${this.LightBulb.Brightness}`);
261
281
 
262
282
  // Color, Hue & Brightness
263
- await this.debugLog(`color: ${JSON.stringify(context.color)}`);
264
- const [red, green, blue] = context.color.split(':');
283
+ await this.debugLog(`color: ${JSON.stringify(this.webhookContext.color)}`);
284
+ const [red, green, blue] = this.webhookContext.color.split(':');
265
285
  await this.debugLog(`red: ${JSON.stringify(red)}, green: ${JSON.stringify(green)}, blue: ${JSON.stringify(blue)}`);
266
286
  const [hue, saturation] = rgb2hs(red, green, blue);
267
287
  await this.debugLog(`hs: ${JSON.stringify(rgb2hs(red, green, blue))}`);
@@ -304,7 +324,8 @@ export class StripLight extends deviceBase {
304
324
  const serviceData = await this.monitorAdvertisementPackets(switchbot) as stripLightServiceData;
305
325
  // Update HomeKit
306
326
  if (serviceData.model === SwitchBotBLEModel.StripLight && serviceData.modelName === SwitchBotBLEModelName.StripLight) {
307
- await this.BLEparseStatus(serviceData);
327
+ this.serviceData = serviceData;
328
+ await this.BLEparseStatus();
308
329
  await this.updateHomeKitCharacteristics();
309
330
  } else {
310
331
  await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
@@ -322,7 +343,8 @@ export class StripLight extends deviceBase {
322
343
  await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);;
323
344
  if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
324
345
  await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
325
- await this.openAPIparseStatus(deviceStatus.body);
346
+ this.deviceStatus = deviceStatus.body;
347
+ await this.openAPIparseStatus();
326
348
  await this.updateHomeKitCharacteristics();
327
349
  } else {
328
350
  await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -340,7 +362,8 @@ export class StripLight extends deviceBase {
340
362
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: stripLightWebhookContext) => {
341
363
  try {
342
364
  await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
343
- await this.parseStatusWebhook(context);
365
+ this.webhookContext = context;
366
+ await this.parseStatusWebhook();
344
367
  await this.updateHomeKitCharacteristics();
345
368
  } catch (e: any) {
346
369
  await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
@@ -42,6 +42,15 @@ export class Lock extends deviceBase {
42
42
  On: CharacteristicValue;
43
43
  };
44
44
 
45
+ // OpenAPI
46
+ deviceStatus!: lockStatus | lockProStatus;
47
+
48
+ //Webhook
49
+ webhookContext!: lockWebhookContext | lockProWebhookContext;
50
+
51
+ // BLE
52
+ serviceData!: lockServiceData | lockProServiceData;
53
+
45
54
  // Updates
46
55
  lockUpdateInProgress!: boolean;
47
56
  doLockUpdate!: Subject<void>;
@@ -52,6 +61,9 @@ export class Lock extends deviceBase {
52
61
  device: device & devicesConfig,
53
62
  ) {
54
63
  super(platform, accessory, device);
64
+ // Set category
65
+ accessory.category = this.hap.Categories.DOOR_LOCK;
66
+
55
67
  // this is subject we use to track when we need to POST changes to the SwitchBot API
56
68
  this.doLockUpdate = new Subject();
57
69
  this.lockUpdateInProgress = false;
@@ -103,7 +115,7 @@ export class Lock extends deviceBase {
103
115
  // Contact Sensor Service
104
116
  if (device.lock?.hide_contactsensor) {
105
117
  if (this.ContactSensor) {
106
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Contact Sensor Service`);
118
+ this.debugLog('Removing Contact Sensor Service');
107
119
  this.ContactSensor.Service = this.accessory.getService(this.hap.Service.ContactSensor) as Service;
108
120
  accessory.removeService(this.ContactSensor.Service);
109
121
  }
@@ -129,7 +141,7 @@ export class Lock extends deviceBase {
129
141
  // Initialize Latch Button Service
130
142
  if (device.lock?.activate_latchbutton === false) {
131
143
  if (this.Switch) {
132
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Latch Button Service`);
144
+ this.debugLog('Removing Latch Button Service');
133
145
  this.Switch.Service = accessory.getService(this.hap.Service.Switch) as Service;
134
146
  accessory.removeService(this.Switch.Service);
135
147
  }
@@ -153,12 +165,11 @@ export class Lock extends deviceBase {
153
165
  }
154
166
 
155
167
  // Retrieve initial values and updateHomekit
168
+ this.debugLog('Retrieve initial values and update Homekit');
156
169
  this.refreshStatus();
157
170
 
158
- // Update Homekit
159
- this.updateHomeKitCharacteristics();
160
-
161
171
  //regisiter webhook event handler
172
+ this.debugLog('Registering Webhook Event Handler');
162
173
  this.registerWebhook();
163
174
 
164
175
  // Start an update interval
@@ -188,57 +199,70 @@ export class Lock extends deviceBase {
188
199
  });
189
200
  }
190
201
 
191
- async BLEparseStatus(serviceData: lockServiceData | lockProServiceData): Promise<void> {
202
+ async BLEparseStatus(): Promise<void> {
192
203
  await this.debugLog('BLEparseStatus');
204
+ await this.debugLog(`(lockState) = BLE:(${this.serviceData.status}), current:(${this.LockMechanism.LockCurrentState})`);
205
+
193
206
  // LockCurrentState
194
- this.LockMechanism.LockCurrentState = serviceData.status === 'locked'
207
+ this.LockMechanism.LockCurrentState = this.serviceData.status === 'locked'
195
208
  ? this.hap.Characteristic.LockCurrentState.SECURED : this.hap.Characteristic.LockCurrentState.UNSECURED;
196
209
  await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
210
+
197
211
  // LockTargetState
198
- this.LockMechanism.LockTargetState = serviceData.status === 'locked'
212
+ this.LockMechanism.LockTargetState = this.serviceData.status === 'locked'
199
213
  ? this.hap.Characteristic.LockTargetState.SECURED : this.hap.Characteristic.LockTargetState.UNSECURED;
200
214
  await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`);
215
+
201
216
  // Contact Sensor
202
217
  if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
203
- this.ContactSensor.ContactSensorState = serviceData.door_open === 'opened'
218
+ this.ContactSensor.ContactSensorState = this.serviceData.door_open === 'opened'
204
219
  ? this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED : this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
205
220
  await this.debugLog(`ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
206
221
  }
222
+
207
223
  // BatteryLevel
208
- this.Battery.BatteryLevel = Number(serviceData.battery);
224
+ this.Battery.BatteryLevel = this.serviceData.battery;
209
225
  await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
226
+
210
227
  // StatusLowBattery
211
228
  this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
212
229
  ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
213
230
  await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
214
231
  }
215
232
 
216
- async openAPIparseStatus(deviceStatus: lockStatus | lockProStatus): Promise<void> {
233
+ async openAPIparseStatus(): Promise<void> {
217
234
  await this.debugLog('openAPIparseStatus');
235
+ await this.debugLog(`(lockState) = OpenAPI:(${this.deviceStatus.lockState}), current:(${this.LockMechanism.LockCurrentState})`);
236
+
218
237
  // LockCurrentState
219
- this.LockMechanism.LockCurrentState = deviceStatus.lockState === 'locked'
238
+ this.LockMechanism.LockCurrentState = this.deviceStatus.lockState === 'locked'
220
239
  ? this.hap.Characteristic.LockCurrentState.SECURED : this.hap.Characteristic.LockCurrentState.UNSECURED;
221
240
  await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
241
+
222
242
  // LockTargetState
223
- this.LockMechanism.LockTargetState = deviceStatus.lockState === 'locked'
243
+ this.LockMechanism.LockTargetState = this.deviceStatus.lockState === 'locked'
224
244
  ? this.hap.Characteristic.LockTargetState.SECURED : this.hap.Characteristic.LockTargetState.UNSECURED;
225
245
  await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`);
246
+
226
247
  // ContactSensorState
227
248
  if (!this.device.lock?.hide_contactsensor && this.ContactSensor?.Service) {
228
- this.ContactSensor.ContactSensorState = deviceStatus.doorState === 'opened'
249
+ this.ContactSensor.ContactSensorState = this.deviceStatus.doorState === 'opened'
229
250
  ? this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED : this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
230
251
  await this.debugLog(`ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
231
252
  }
253
+
232
254
  // BatteryLevel
233
- this.Battery.BatteryLevel = Number(deviceStatus.battery);
255
+ this.Battery.BatteryLevel = this.deviceStatus.battery;
234
256
  await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
257
+
235
258
  // StatusLowBattery
236
259
  this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
237
260
  ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
238
261
  await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
262
+
239
263
  // Firmware Version
240
- if (deviceStatus.version) {
241
- const version = deviceStatus.version.toString();
264
+ if (this.deviceStatus.version) {
265
+ const version = this.deviceStatus.version.toString();
242
266
  await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
243
267
  const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
244
268
  this.accessory
@@ -247,20 +271,22 @@ export class Lock extends deviceBase {
247
271
  .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
248
272
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
249
273
  .updateValue(deviceVersion);
250
- this.accessory.context.deviceVersion = deviceVersion;
251
- await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
274
+ this.accessory.context.version = deviceVersion;
275
+ await this.debugSuccessLog(`version: ${this.accessory.context.version}`);
252
276
  }
253
277
  }
254
278
 
255
- async parseStatusWebhook(context: lockWebhookContext | lockProWebhookContext): Promise<void> {
279
+ async parseStatusWebhook(): Promise<void> {
256
280
  await this.debugLog('parseStatusWebhook');
257
- await this.debugLog(`(lockState) = Webhook:(${context.lockState}), current:(${this.LockMechanism.LockCurrentState})`);
281
+ await this.debugLog(`(lockState) = Webhook:(${this.webhookContext.lockState}), current:(${this.LockMechanism.LockCurrentState})`);
282
+
258
283
  // LockCurrentState
259
- this.LockMechanism.LockCurrentState = context.lockState === 'LOCKED'
284
+ this.LockMechanism.LockCurrentState = this.webhookContext.lockState === 'LOCKED'
260
285
  ? this.hap.Characteristic.LockCurrentState.SECURED : this.hap.Characteristic.LockCurrentState.UNSECURED;
261
286
  await this.debugLog(`LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
287
+
262
288
  // LockTargetState
263
- this.LockMechanism.LockTargetState = context.lockState === 'LOCKED'
289
+ this.LockMechanism.LockTargetState = this.webhookContext.lockState === 'LOCKED'
264
290
  ? this.hap.Characteristic.LockTargetState.SECURED : this.hap.Characteristic.LockTargetState.UNSECURED;
265
291
  await this.debugLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`);
266
292
  }
@@ -295,7 +321,8 @@ export class Lock extends deviceBase {
295
321
  // Update HomeKit
296
322
  if ((serviceData.model === SwitchBotBLEModel.Lock || SwitchBotBLEModel.LockPro)
297
323
  && (serviceData.modelName === SwitchBotBLEModelName.Lock || SwitchBotBLEModelName.LockPro)) {
298
- await this.BLEparseStatus(serviceData);
324
+ this.serviceData = serviceData;
325
+ await this.BLEparseStatus();
299
326
  await this.updateHomeKitCharacteristics();
300
327
  } else {
301
328
  await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
@@ -313,7 +340,8 @@ export class Lock extends deviceBase {
313
340
  await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);;
314
341
  if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
315
342
  await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
316
- await this.openAPIparseStatus(deviceStatus.body);
343
+ this.deviceStatus = deviceStatus.body;
344
+ await this.openAPIparseStatus();
317
345
  await this.updateHomeKitCharacteristics();
318
346
  } else {
319
347
  await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -331,7 +359,8 @@ export class Lock extends deviceBase {
331
359
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: lockWebhookContext | lockProWebhookContext) => {
332
360
  try {
333
361
  await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
334
- await this.parseStatusWebhook(context);
362
+ this.webhookContext = context;
363
+ await this.parseStatusWebhook();
335
364
  await this.updateHomeKitCharacteristics();
336
365
  } catch (e: any) {
337
366
  await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);