@switchbot/homebridge-switchbot 5.0.0-beta.43 → 5.0.0-beta.45

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 (109) hide show
  1. package/config.schema.json +61 -9
  2. package/dist/devices-hap/airpurifier.d.ts.map +1 -1
  3. package/dist/devices-hap/airpurifier.js +12 -6
  4. package/dist/devices-hap/airpurifier.js.map +1 -1
  5. package/dist/devices-hap/blindtilt.js +3 -3
  6. package/dist/devices-hap/bot.d.ts.map +1 -1
  7. package/dist/devices-hap/bot.js +16 -5
  8. package/dist/devices-hap/bot.js.map +1 -1
  9. package/dist/devices-hap/ceilinglight.d.ts.map +1 -1
  10. package/dist/devices-hap/ceilinglight.js +13 -7
  11. package/dist/devices-hap/ceilinglight.js.map +1 -1
  12. package/dist/devices-hap/colorbulb.d.ts.map +1 -1
  13. package/dist/devices-hap/colorbulb.js +49 -9
  14. package/dist/devices-hap/colorbulb.js.map +1 -1
  15. package/dist/devices-hap/contact.js +3 -3
  16. package/dist/devices-hap/curtain.js +2 -2
  17. package/dist/devices-hap/curtain.js.map +1 -1
  18. package/dist/devices-hap/device.d.ts.map +1 -1
  19. package/dist/devices-hap/device.js +20 -1
  20. package/dist/devices-hap/device.js.map +1 -1
  21. package/dist/devices-hap/fan.d.ts.map +1 -1
  22. package/dist/devices-hap/fan.js +12 -6
  23. package/dist/devices-hap/fan.js.map +1 -1
  24. package/dist/devices-hap/hub.d.ts.map +1 -1
  25. package/dist/devices-hap/hub.js +6 -5
  26. package/dist/devices-hap/hub.js.map +1 -1
  27. package/dist/devices-hap/humidifier.d.ts +5 -0
  28. package/dist/devices-hap/humidifier.d.ts.map +1 -1
  29. package/dist/devices-hap/humidifier.js +92 -4
  30. package/dist/devices-hap/humidifier.js.map +1 -1
  31. package/dist/devices-hap/iosensor.d.ts.map +1 -1
  32. package/dist/devices-hap/iosensor.js +36 -21
  33. package/dist/devices-hap/iosensor.js.map +1 -1
  34. package/dist/devices-hap/lightstrip.d.ts.map +1 -1
  35. package/dist/devices-hap/lightstrip.js +38 -8
  36. package/dist/devices-hap/lightstrip.js.map +1 -1
  37. package/dist/devices-hap/lock.d.ts.map +1 -1
  38. package/dist/devices-hap/lock.js +14 -6
  39. package/dist/devices-hap/lock.js.map +1 -1
  40. package/dist/devices-hap/meter.d.ts.map +1 -1
  41. package/dist/devices-hap/meter.js +6 -5
  42. package/dist/devices-hap/meter.js.map +1 -1
  43. package/dist/devices-hap/meterplus.d.ts.map +1 -1
  44. package/dist/devices-hap/meterplus.js +6 -5
  45. package/dist/devices-hap/meterplus.js.map +1 -1
  46. package/dist/devices-hap/meterpro.d.ts.map +1 -1
  47. package/dist/devices-hap/meterpro.js +7 -6
  48. package/dist/devices-hap/meterpro.js.map +1 -1
  49. package/dist/devices-hap/motion.js +3 -3
  50. package/dist/devices-hap/plug.d.ts.map +1 -1
  51. package/dist/devices-hap/plug.js +11 -6
  52. package/dist/devices-hap/plug.js.map +1 -1
  53. package/dist/devices-hap/relayswitch.js +3 -3
  54. package/dist/devices-hap/robotvacuumcleaner.d.ts.map +1 -1
  55. package/dist/devices-hap/robotvacuumcleaner.js +13 -6
  56. package/dist/devices-hap/robotvacuumcleaner.js.map +1 -1
  57. package/dist/devices-hap/waterdetector.js +3 -3
  58. package/dist/homebridge-ui/public/index.html +13 -1
  59. package/dist/platform-hap.d.ts.map +1 -1
  60. package/dist/platform-hap.js +38 -2
  61. package/dist/platform-hap.js.map +1 -1
  62. package/dist/platform-matter.d.ts.map +1 -1
  63. package/dist/platform-matter.js +82 -3
  64. package/dist/platform-matter.js.map +1 -1
  65. package/dist/settings.d.ts +12 -1
  66. package/dist/settings.d.ts.map +1 -1
  67. package/dist/settings.js.map +1 -1
  68. package/dist/test/hap/device-webhook-context.test.d.ts +2 -0
  69. package/dist/test/hap/device-webhook-context.test.d.ts.map +1 -0
  70. package/dist/test/hap/device-webhook-context.test.js +128 -0
  71. package/dist/test/hap/device-webhook-context.test.js.map +1 -0
  72. package/dist/test/matter/platform-matter.webhook.test.d.ts +2 -0
  73. package/dist/test/matter/platform-matter.webhook.test.d.ts.map +1 -0
  74. package/dist/test/matter/platform-matter.webhook.test.js +46 -0
  75. package/dist/test/matter/platform-matter.webhook.test.js.map +1 -0
  76. package/dist/utils.d.ts.map +1 -1
  77. package/dist/utils.js +10 -4
  78. package/dist/utils.js.map +1 -1
  79. package/docs/variables/default.html +1 -1
  80. package/package.json +2 -2
  81. package/src/devices-hap/airpurifier.ts +11 -6
  82. package/src/devices-hap/blindtilt.ts +3 -3
  83. package/src/devices-hap/bot.ts +15 -5
  84. package/src/devices-hap/ceilinglight.ts +12 -7
  85. package/src/devices-hap/colorbulb.ts +46 -10
  86. package/src/devices-hap/contact.ts +3 -3
  87. package/src/devices-hap/curtain.ts +2 -2
  88. package/src/devices-hap/device.ts +20 -1
  89. package/src/devices-hap/fan.ts +11 -6
  90. package/src/devices-hap/hub.ts +6 -5
  91. package/src/devices-hap/humidifier.ts +97 -4
  92. package/src/devices-hap/iosensor.ts +36 -21
  93. package/src/devices-hap/lightstrip.ts +35 -8
  94. package/src/devices-hap/lock.ts +13 -6
  95. package/src/devices-hap/meter.ts +6 -5
  96. package/src/devices-hap/meterplus.ts +6 -5
  97. package/src/devices-hap/meterpro.ts +7 -6
  98. package/src/devices-hap/motion.ts +3 -3
  99. package/src/devices-hap/plug.ts +10 -6
  100. package/src/devices-hap/relayswitch.ts +3 -3
  101. package/src/devices-hap/robotvacuumcleaner.ts +12 -6
  102. package/src/devices-hap/waterdetector.ts +3 -3
  103. package/src/homebridge-ui/public/index.html +13 -1
  104. package/src/platform-hap.ts +38 -2
  105. package/src/platform-matter.ts +81 -3
  106. package/src/settings.ts +12 -1
  107. package/src/test/hap/device-webhook-context.test.ts +136 -0
  108. package/src/test/matter/platform-matter.webhook.test.ts +54 -0
  109. package/src/utils.ts +14 -4
@@ -178,27 +178,41 @@ export class IOSensor extends deviceBase {
178
178
  async BLEparseStatus(): Promise<void> {
179
179
  this.debugLog('BLEparseStatus')
180
180
  this.debugLog(`(battery, temperature, humidity) = BLE:(${this.serviceData.battery}, ${this.serviceData.celsius}, ${this.serviceData.humidity}), current:(${this.Battery.BatteryLevel}, ${this.TemperatureSensor?.CurrentTemperature}, ${this.HumiditySensor?.CurrentRelativeHumidity})`)
181
+
181
182
  // Battery Info
182
183
  if ('battery' in this.serviceData) {
183
- // BatteryLevel
184
- this.Battery.BatteryLevel = this.serviceData.battery
185
- this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
186
- // StatusLowBattery
187
- this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
188
- ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
189
- : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
190
- this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
184
+ if (typeof this.serviceData.battery === 'number') {
185
+ this.Battery.BatteryLevel = this.serviceData.battery
186
+ this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
187
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
188
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
189
+ : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
190
+ this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
191
+ } else {
192
+ this.debugWarnLog(`BLE battery is undefined; skipping battery update.`)
193
+ }
191
194
  }
195
+
192
196
  // CurrentRelativeHumidity
193
197
  if (!(this.device as indoorOutdoorSensorConfig).hide_humidity && this.HumiditySensor?.Service) {
194
- this.HumiditySensor.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100)
195
- this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`)
198
+ if (typeof this.serviceData.humidity === 'number') {
199
+ this.HumiditySensor.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100)
200
+ this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`)
201
+ } else {
202
+ this.debugWarnLog(`BLE humidity is undefined; skipping humidity update.`)
203
+ }
196
204
  }
205
+
197
206
  // Current Temperature
198
207
  if (!(this.device as indoorOutdoorSensorConfig).hide_temperature && this.TemperatureSensor?.Service) {
199
- const CELSIUS = this.serviceData.celsius < 0 ? 0 : this.serviceData.celsius > 100 ? 100 : this.serviceData.celsius
200
- this.TemperatureSensor.CurrentTemperature = CELSIUS
201
- this.debugLog(`Temperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
208
+ if (typeof this.serviceData.celsius === 'number') {
209
+ const c = this.serviceData.celsius
210
+ const CELSIUS = c < 0 ? 0 : c > 100 ? 100 : c
211
+ this.TemperatureSensor.CurrentTemperature = CELSIUS
212
+ this.debugLog(`Temperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
213
+ } else {
214
+ this.debugWarnLog(`BLE temperature is undefined; skipping temperature update.`)
215
+ }
202
216
  }
203
217
  }
204
218
 
@@ -224,8 +238,9 @@ export class IOSensor extends deviceBase {
224
238
 
225
239
  // Current Temperature
226
240
  if (!(this.device as indoorOutdoorSensorConfig).hide_temperature && this.TemperatureSensor?.Service) {
227
- this.TemperatureSensor.CurrentTemperature = this.deviceStatus.temperature
228
- this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
241
+ // OpenAPI returns Celsius; convert if user configured a different unit
242
+ this.TemperatureSensor.CurrentTemperature = convertUnits(this.deviceStatus.temperature as number, 'CELSIUS', (this.device as indoorOutdoorSensorConfig).convertUnitTo)
243
+ this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`)
229
244
  }
230
245
 
231
246
  // Firmware Version
@@ -252,12 +267,12 @@ export class IOSensor extends deviceBase {
252
267
  this.warnLog(`received a non-CELSIUS Webhook scale: ${this.webhookContext.scale}, Use the *convertUnitsTo* config under Hub settings, if displaying incorrectly in HomeKit.`)
253
268
  }
254
269
  // CurrentRelativeHumidity
255
- if ((this.device as indoorOutdoorSensorConfig).hide_humidity && this.HumiditySensor?.Service) {
270
+ if (!(this.device as indoorOutdoorSensorConfig).hide_humidity && this.HumiditySensor?.Service) {
256
271
  this.HumiditySensor.CurrentRelativeHumidity = this.webhookContext.humidity
257
272
  this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`)
258
273
  }
259
274
  // CurrentTemperature
260
- if ((this.device as indoorOutdoorSensorConfig).hide_temperature && this.TemperatureSensor?.Service) {
275
+ if (!(this.device as indoorOutdoorSensorConfig).hide_temperature && this.TemperatureSensor?.Service) {
261
276
  this.TemperatureSensor.CurrentTemperature = convertUnits(this.webhookContext.temperature, this.webhookContext.scale, (this.device as indoorOutdoorSensorConfig).convertUnitTo)
262
277
  this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
263
278
  }
@@ -290,7 +305,7 @@ export class IOSensor extends deviceBase {
290
305
  // Update HomeKit
291
306
  if (serviceData.model === SwitchBotBLEModel.OutdoorMeter && serviceData.modelName === SwitchBotBLEModelName.OutdoorMeter) {
292
307
  this.serviceData = serviceData
293
- if (serviceData !== undefined || serviceData !== null) {
308
+ if (serviceData !== undefined && serviceData !== null) {
294
309
  await this.BLEparseStatus()
295
310
  await this.updateHomeKitCharacteristics()
296
311
  } else {
@@ -316,7 +331,7 @@ export class IOSensor extends deviceBase {
316
331
  this.platform.bleEventHandler[this.device.bleMac] = async (context: outdoorMeterServiceData) => {
317
332
  try {
318
333
  this.serviceData = context
319
- if (context !== undefined || context !== null) {
334
+ if (context !== undefined && context !== null) {
320
335
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
321
336
  await this.BLEparseStatus()
322
337
  await this.updateHomeKitCharacteristics()
@@ -351,7 +366,7 @@ export class IOSensor extends deviceBase {
351
366
  }
352
367
  } catch (e: any) {
353
368
  await this.apiError(e)
354
- this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
369
+ this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error: ${e.message ?? e}`)
355
370
  }
356
371
  }
357
372
 
@@ -361,7 +376,7 @@ export class IOSensor extends deviceBase {
361
376
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: outdoorMeterWebhookContext) => {
362
377
  try {
363
378
  this.webhookContext = context
364
- if (context !== undefined || context !== null) {
379
+ if (context !== undefined && context !== null) {
365
380
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
366
381
  await this.parseStatusWebhook()
367
382
  await this.updateHomeKitCharacteristics()
@@ -328,7 +328,7 @@ export class StripLight extends deviceBase {
328
328
  // Update HomeKit
329
329
  if (serviceData.model === SwitchBotBLEModel.StripLight && serviceData.modelName === SwitchBotBLEModelName.StripLight) {
330
330
  this.serviceData = serviceData
331
- if (serviceData !== undefined || serviceData !== null) {
331
+ if (serviceData !== undefined && serviceData !== null) {
332
332
  await this.BLEparseStatus()
333
333
  await this.updateHomeKitCharacteristics()
334
334
  } else {
@@ -354,7 +354,7 @@ export class StripLight extends deviceBase {
354
354
  this.platform.bleEventHandler[this.device.bleMac] = async (context: stripLightServiceData) => {
355
355
  try {
356
356
  this.serviceData = context
357
- if (context !== undefined || context !== null) {
357
+ if (context !== undefined && context !== null) {
358
358
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
359
359
  await this.BLEparseStatus()
360
360
  await this.updateHomeKitCharacteristics()
@@ -399,7 +399,7 @@ export class StripLight extends deviceBase {
399
399
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: stripLightWebhookContext) => {
400
400
  try {
401
401
  this.webhookContext = context
402
- if (context !== undefined || context !== null) {
402
+ if (context !== undefined && context !== null) {
403
403
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
404
404
  await this.parseStatusWebhook()
405
405
  await this.updateHomeKitCharacteristics()
@@ -485,13 +485,18 @@ export class StripLight extends deviceBase {
485
485
  .then(async (device_list: SwitchbotDevice[]) => {
486
486
  const deviceList = device_list as WoStrip[]
487
487
  this.infoLog(`On: ${this.LightBulb.On}`)
488
+ this.debugLog(`device_list: ${JSON.stringify(device_list)}`)
488
489
  return await this.retryBLE({
489
490
  max: this.maxRetryBLE(),
490
491
  fn: async () => {
491
- if (this.LightBulb.On) {
492
- return await deviceList[0].turnOn()
492
+ if (deviceList.length > 0) {
493
+ if (this.LightBulb.On) {
494
+ return await deviceList[0].turnOn()
495
+ } else {
496
+ return await deviceList[0].turnOff()
497
+ }
493
498
  } else {
494
- return await deviceList[0].turnOff()
499
+ throw new Error('No devices found during discovery.')
495
500
  }
496
501
  },
497
502
  })
@@ -529,8 +534,19 @@ export class StripLight extends deviceBase {
529
534
  switchBotBLE
530
535
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
531
536
  .then(async (device_list: SwitchbotDevice[]) => {
537
+ const deviceList = device_list as WoStrip[]
532
538
  this.infoLog(`Brightness: ${this.LightBulb.Brightness}`)
533
- return await (device_list[0] as WoStrip).setBrightness(Number(this.LightBulb.Brightness))
539
+ this.debugLog(`device_list: ${JSON.stringify(device_list)}`)
540
+ return await this.retryBLE({
541
+ max: this.maxRetryBLE(),
542
+ fn: async () => {
543
+ if (deviceList.length > 0) {
544
+ return await deviceList[0].setBrightness(Number(this.LightBulb.Brightness))
545
+ } else {
546
+ throw new Error('No devices found during discovery.')
547
+ }
548
+ },
549
+ })
534
550
  })
535
551
  .then(async () => {
536
552
  this.successLog(`Brightness: ${this.LightBulb.Brightness} sent over SwitchBot BLE, sent successfully`)
@@ -568,8 +584,19 @@ export class StripLight extends deviceBase {
568
584
  switchBotBLE
569
585
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
570
586
  .then(async (device_list: SwitchbotDevice[]) => {
587
+ const deviceList = device_list as WoStrip[]
571
588
  this.infoLog(`RGB: ${(this.LightBulb.Brightness, red, green, blue)}`)
572
- return await (device_list[0] as WoStrip).setRGB(Number(this.LightBulb.Brightness), red, green, blue)
589
+ this.debugLog(`device_list: ${JSON.stringify(device_list)}`)
590
+ return await this.retryBLE({
591
+ max: this.maxRetryBLE(),
592
+ fn: async () => {
593
+ if (deviceList.length > 0) {
594
+ return await deviceList[0].setRGB(Number(this.LightBulb.Brightness), red, green, blue)
595
+ } else {
596
+ throw new Error('No devices found during discovery.')
597
+ }
598
+ },
599
+ })
573
600
  })
574
601
  .then(async () => {
575
602
  this.successLog(`RGB: ${(this.LightBulb.Brightness, red, green, blue)} sent over SwitchBot BLE, sent successfully`)
@@ -332,7 +332,7 @@ export class Lock extends deviceBase {
332
332
  if ((serviceData.model === SwitchBotBLEModel.Lock || SwitchBotBLEModel.LockPro)
333
333
  && (serviceData.modelName === SwitchBotBLEModelName.Lock || SwitchBotBLEModelName.LockPro)) {
334
334
  this.serviceData = serviceData
335
- if (serviceData !== undefined || serviceData !== null) {
335
+ if (serviceData !== undefined && serviceData !== null) {
336
336
  await this.BLEparseStatus()
337
337
  await this.updateHomeKitCharacteristics()
338
338
  } else {
@@ -358,7 +358,7 @@ export class Lock extends deviceBase {
358
358
  this.platform.bleEventHandler[this.device.bleMac] = async (context: lockServiceData | lockProServiceData) => {
359
359
  try {
360
360
  this.serviceData = context
361
- if (context !== undefined || context !== null) {
361
+ if (context !== undefined && context !== null) {
362
362
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
363
363
  await this.BLEparseStatus()
364
364
  await this.updateHomeKitCharacteristics()
@@ -403,7 +403,7 @@ export class Lock extends deviceBase {
403
403
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: lockWebhookContext | lockProWebhookContext) => {
404
404
  try {
405
405
  this.webhookContext = context
406
- if (context !== undefined || context !== null) {
406
+ if (context !== undefined && context !== null) {
407
407
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
408
408
  await this.parseStatusWebhook()
409
409
  await this.updateHomeKitCharacteristics()
@@ -455,13 +455,20 @@ export class Lock extends deviceBase {
455
455
  switchBotBLE
456
456
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
457
457
  .then(async (device_list: SwitchbotDevice[]) => {
458
+ const deviceList = device_list as WoSmartLock[]
459
+ this.infoLog(`LockTargetState: ${this.LockMechanism.LockTargetState}`)
460
+ this.warnLog(`device_list: ${JSON.stringify(device_list)}`)
458
461
  return await this.retryBLE({
459
462
  max: this.maxRetryBLE(),
460
463
  fn: async () => {
461
- if (this.LockMechanism.LockTargetState === this.hap.Characteristic.LockTargetState.SECURED) {
462
- return await (device_list[0] as WoSmartLock).lock()
464
+ if (deviceList && Array.isArray(deviceList) && deviceList.length > 0) {
465
+ if (this.LockMechanism.LockTargetState === this.hap.Characteristic.LockTargetState.SECURED) {
466
+ return await deviceList[0].lock()
467
+ } else {
468
+ return await deviceList[0].unlock()
469
+ }
463
470
  } else {
464
- return await (device_list[0] as WoSmartLock).unlock()
471
+ throw new Error('No devices found during discovery.')
465
472
  }
466
473
  },
467
474
  })
@@ -209,8 +209,9 @@ export class Meter extends deviceBase {
209
209
 
210
210
  // CurrentTemperature
211
211
  if (!(this.device as meterConfig).hide_temperature && this.TemperatureSensor?.Service) {
212
- this.TemperatureSensor.CurrentTemperature = this.deviceStatus.temperature
213
- this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
212
+ // OpenAPI returns Celsius; convert if user configured a different unit
213
+ this.TemperatureSensor.CurrentTemperature = convertUnits(this.deviceStatus.temperature, 'CELSIUS', (this.device as meterConfig).convertUnitTo)
214
+ this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`)
214
215
  }
215
216
 
216
217
  // BatteryLevel
@@ -287,7 +288,7 @@ export class Meter extends deviceBase {
287
288
  // Update HomeKit
288
289
  if (serviceData.model === SwitchBotBLEModel.Meter && serviceData.modelName === SwitchBotBLEModelName.Meter) {
289
290
  this.serviceData = serviceData
290
- if (serviceData !== undefined || serviceData !== null) {
291
+ if (serviceData !== undefined && serviceData !== null) {
291
292
  await this.BLEparseStatus()
292
293
  await this.updateHomeKitCharacteristics()
293
294
  } else {
@@ -313,7 +314,7 @@ export class Meter extends deviceBase {
313
314
  this.platform.bleEventHandler[this.device.bleMac] = async (context: meterServiceData) => {
314
315
  try {
315
316
  this.serviceData = context
316
- if (context !== undefined || context !== null) {
317
+ if (context !== undefined && context !== null) {
317
318
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
318
319
  await this.BLEparseStatus()
319
320
  await this.updateHomeKitCharacteristics()
@@ -358,7 +359,7 @@ export class Meter extends deviceBase {
358
359
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: meterWebhookContext) => {
359
360
  try {
360
361
  this.webhookContext = context
361
- if (context !== undefined || context !== null) {
362
+ if (context !== undefined && context !== null) {
362
363
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
363
364
  await this.parseStatusWebhook()
364
365
  await this.updateHomeKitCharacteristics()
@@ -213,8 +213,9 @@ export class MeterPlus extends deviceBase {
213
213
 
214
214
  // CurrentTemperature
215
215
  if (!(this.device as meterConfig).hide_temperature && this.TemperatureSensor?.Service) {
216
- this.TemperatureSensor.CurrentTemperature = this.deviceStatus.temperature
217
- this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
216
+ // OpenAPI returns Celsius; convert if user configured a different unit
217
+ this.TemperatureSensor.CurrentTemperature = convertUnits(this.deviceStatus.temperature, 'CELSIUS', (this.device as meterConfig).convertUnitTo)
218
+ this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`)
218
219
  }
219
220
 
220
221
  // BatteryLevel
@@ -291,7 +292,7 @@ export class MeterPlus extends deviceBase {
291
292
  // Update HomeKit
292
293
  if (serviceData.model === SwitchBotBLEModel.MeterPlus && serviceData.modelName === SwitchBotBLEModelName.MeterPlus) {
293
294
  this.serviceData = serviceData
294
- if (serviceData !== undefined || serviceData !== null) {
295
+ if (serviceData !== undefined && serviceData !== null) {
295
296
  await this.BLEparseStatus()
296
297
  await this.updateHomeKitCharacteristics()
297
298
  } else {
@@ -317,7 +318,7 @@ export class MeterPlus extends deviceBase {
317
318
  this.platform.bleEventHandler[this.device.bleMac] = async (context: meterPlusServiceData) => {
318
319
  try {
319
320
  this.serviceData = context
320
- if (context !== undefined || context !== null) {
321
+ if (context !== undefined && context !== null) {
321
322
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
322
323
  await this.BLEparseStatus()
323
324
  await this.updateHomeKitCharacteristics()
@@ -362,7 +363,7 @@ export class MeterPlus extends deviceBase {
362
363
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: meterPlusWebhookContext) => {
363
364
  try {
364
365
  this.webhookContext = context
365
- if (context !== undefined || context !== null) {
366
+ if (context !== undefined && context !== null) {
366
367
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
367
368
  await this.parseStatusWebhook()
368
369
  await this.updateHomeKitCharacteristics()
@@ -263,8 +263,9 @@ export class MeterPro extends deviceBase {
263
263
 
264
264
  // CurrentTemperature
265
265
  if (!(this.device as meterProConfig).hide_temperature && this.TemperatureSensor?.Service) {
266
- this.TemperatureSensor.CurrentTemperature = this.deviceStatus.temperature
267
- this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}°c`)
266
+ // OpenAPI returns Celsius; convert if user configured a different unit
267
+ this.TemperatureSensor.CurrentTemperature = convertUnits(this.deviceStatus.temperature as number, 'CELSIUS', (this.device as meterProConfig).convertUnitTo)
268
+ this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`)
268
269
  }
269
270
 
270
271
  // Carbon Dioxide Sensor
@@ -367,7 +368,7 @@ export class MeterPro extends deviceBase {
367
368
  if ((serviceData.model === SwitchBotBLEModel.MeterPro && serviceData.modelName === SwitchBotBLEModelName.MeterPro)
368
369
  || (serviceData.model === SwitchBotBLEModel.MeterProCO2 && serviceData.modelName === SwitchBotBLEModelName.MeterProCO2)) {
369
370
  this.serviceData = serviceData
370
- if (serviceData !== undefined || serviceData !== null) {
371
+ if (serviceData !== undefined && serviceData !== null) {
371
372
  await this.BLEparseStatus()
372
373
  await this.updateHomeKitCharacteristics()
373
374
  } else {
@@ -393,7 +394,7 @@ export class MeterPro extends deviceBase {
393
394
  this.platform.bleEventHandler[this.device.bleMac] = async (context: meterProServiceData) => {
394
395
  try {
395
396
  this.serviceData = context
396
- if (context !== undefined || context !== null) {
397
+ if (context !== undefined && context !== null) {
397
398
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
398
399
  await this.BLEparseStatus()
399
400
  await this.updateHomeKitCharacteristics()
@@ -428,7 +429,7 @@ export class MeterPro extends deviceBase {
428
429
  }
429
430
  } catch (e: any) {
430
431
  await this.apiError(e)
431
- this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
432
+ this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error: ${e.message ?? e}`)
432
433
  }
433
434
  }
434
435
 
@@ -438,7 +439,7 @@ export class MeterPro extends deviceBase {
438
439
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: meterProWebhookContext) => {
439
440
  try {
440
441
  this.webhookContext = context
441
- if (context !== undefined || context !== null) {
442
+ if (context !== undefined && context !== null) {
442
443
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
443
444
  await this.parseStatusWebhook()
444
445
  await this.updateHomeKitCharacteristics()
@@ -262,7 +262,7 @@ export class Motion extends deviceBase {
262
262
  // Update HomeKit
263
263
  if (serviceData.model === SwitchBotBLEModel.MotionSensor && serviceData.modelName === SwitchBotBLEModelName.MotionSensor) {
264
264
  this.serviceData = serviceData
265
- if (serviceData !== undefined || serviceData !== null) {
265
+ if (serviceData !== undefined && serviceData !== null) {
266
266
  await this.BLEparseStatus()
267
267
  await this.updateHomeKitCharacteristics()
268
268
  } else {
@@ -288,7 +288,7 @@ export class Motion extends deviceBase {
288
288
  this.platform.bleEventHandler[this.device.bleMac] = async (context: motionSensorServiceData) => {
289
289
  try {
290
290
  this.serviceData = context
291
- if (context !== undefined || context !== null) {
291
+ if (context !== undefined && context !== null) {
292
292
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
293
293
  await this.BLEparseStatus()
294
294
  await this.updateHomeKitCharacteristics()
@@ -333,7 +333,7 @@ export class Motion extends deviceBase {
333
333
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: motionSensorWebhookContext) => {
334
334
  try {
335
335
  this.webhookContext = context
336
- if (context !== undefined || context !== null) {
336
+ if (context !== undefined && context !== null) {
337
337
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
338
338
  await this.parseStatusWebhook()
339
339
  await this.updateHomeKitCharacteristics()
@@ -187,7 +187,7 @@ export class Plug extends deviceBase {
187
187
  if ((serviceData.model === SwitchBotBLEModel.PlugMiniUS || SwitchBotBLEModel.PlugMiniJP)
188
188
  && serviceData.modelName === (SwitchBotBLEModelName.PlugMini || SwitchBotBLEModelName.PlugMini)) {
189
189
  this.serviceData = serviceData
190
- if (serviceData !== undefined || serviceData !== null) {
190
+ if (serviceData !== undefined && serviceData !== null) {
191
191
  await this.BLEparseStatus()
192
192
  await this.updateHomeKitCharacteristics()
193
193
  } else {
@@ -213,7 +213,7 @@ export class Plug extends deviceBase {
213
213
  this.platform.bleEventHandler[this.device.bleMac] = async (context: plugMiniUSServiceData | plugMiniJPServiceData) => {
214
214
  try {
215
215
  this.serviceData = context
216
- if (context !== undefined || context !== null) {
216
+ if (context !== undefined && context !== null) {
217
217
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
218
218
  await this.BLEparseStatus()
219
219
  await this.updateHomeKitCharacteristics()
@@ -258,7 +258,7 @@ export class Plug extends deviceBase {
258
258
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: plugWebhookContext | plugMiniUSWebhookContext | plugMiniJPWebhookContext) => {
259
259
  try {
260
260
  this.webhookContext = context
261
- if (context !== undefined || context !== null) {
261
+ if (context !== undefined && context !== null) {
262
262
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
263
263
  await this.parseStatusWebhook()
264
264
  await this.updateHomeKitCharacteristics()
@@ -320,10 +320,14 @@ export class Plug extends deviceBase {
320
320
  return await this.retryBLE({
321
321
  max: this.maxRetryBLE(),
322
322
  fn: async () => {
323
- if (this.Outlet.On) {
324
- return await deviceList[0].turnOn()
323
+ if (deviceList.length > 0) {
324
+ if (this.Outlet.On) {
325
+ return await deviceList[0].turnOn()
326
+ } else {
327
+ return await deviceList[0].turnOff()
328
+ }
325
329
  } else {
326
- return await deviceList[0].turnOff()
330
+ throw new Error('No devices found during discovery.')
327
331
  }
328
332
  },
329
333
  })
@@ -315,7 +315,7 @@ export class RelaySwitch extends deviceBase {
315
315
  // Update HomeKit
316
316
  if ((serviceData.model === SwitchBotBLEModel.RelaySwitch1PM && serviceData.modelName === SwitchBotBLEModelName.RelaySwitch1PM) ?? (serviceData.model === SwitchBotBLEModel.RelaySwitch1 && serviceData.modelName === SwitchBotBLEModelName.RelaySwitch1)) {
317
317
  this.serviceData = serviceData
318
- if (serviceData !== undefined || serviceData !== null) {
318
+ if (serviceData !== undefined && serviceData !== null) {
319
319
  await this.BLEparseStatus()
320
320
  await this.updateHomeKitCharacteristics()
321
321
  } else {
@@ -341,7 +341,7 @@ export class RelaySwitch extends deviceBase {
341
341
  this.platform.bleEventHandler[this.device.bleMac] = async (context: relaySwitch1ServiceData | relaySwitch1PMServiceData) => {
342
342
  try {
343
343
  this.serviceData = context
344
- if (context !== undefined || context !== null) {
344
+ if (context !== undefined && context !== null) {
345
345
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
346
346
  await this.BLEparseStatus()
347
347
  await this.updateHomeKitCharacteristics()
@@ -386,7 +386,7 @@ export class RelaySwitch extends deviceBase {
386
386
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: relaySwitch1Context | relaySwitch1PMContext) => {
387
387
  try {
388
388
  this.webhookContext = context
389
- if (context !== undefined || context !== null) {
389
+ if (context !== undefined && context !== null) {
390
390
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
391
391
  await this.parseStatusWebhook()
392
392
  await this.updateHomeKitCharacteristics()
@@ -275,7 +275,7 @@ export class RobotVacuumCleaner extends deviceBase {
275
275
  // Update HomeKit
276
276
  if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
277
277
  this.serviceData = serviceData
278
- if (serviceData !== undefined || serviceData !== null) {
278
+ if (serviceData !== undefined && serviceData !== null) {
279
279
  await this.BLEparseStatus()
280
280
  await this.updateHomeKitCharacteristics()
281
281
  } else {
@@ -301,7 +301,7 @@ export class RobotVacuumCleaner extends deviceBase {
301
301
  this.platform.bleEventHandler[this.device.bleMac] = async (context: robotVacuumCleanerServiceData) => {
302
302
  try {
303
303
  this.serviceData = context
304
- if (context !== undefined || context !== null) {
304
+ if (context !== undefined && context !== null) {
305
305
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
306
306
  await this.BLEparseStatus()
307
307
  await this.updateHomeKitCharacteristics()
@@ -346,7 +346,7 @@ export class RobotVacuumCleaner extends deviceBase {
346
346
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: robotVacuumCleanerS1WebhookContext | robotVacuumCleanerS1PlusWebhookContext | floorCleaningRobotS10WebhookContext) => {
347
347
  try {
348
348
  this.webhookContext = context
349
- if (context !== undefined || context !== null) {
349
+ if (context !== undefined && context !== null) {
350
350
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
351
351
  await this.parseStatusWebhook()
352
352
  await this.updateHomeKitCharacteristics()
@@ -400,14 +400,20 @@ export class RobotVacuumCleaner extends deviceBase {
400
400
  switchBotBLE
401
401
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
402
402
  .then(async (device_list: SwitchbotDevice[]) => {
403
+ const deviceList = device_list as any[]
403
404
  this.infoLog(`On: ${this.LightBulb.On}`)
405
+ this.warnLog(`device_list: ${JSON.stringify(device_list)}`)
404
406
  return await this.retryBLE({
405
407
  max: this.maxRetryBLE(),
406
408
  fn: async () => {
407
- if (this.LightBulb.On) {
408
- return await (device_list[0] as any).turnOn()
409
+ if (deviceList && Array.isArray(deviceList) && deviceList.length > 0) {
410
+ if (this.LightBulb.On) {
411
+ return await (deviceList[0] as any).turnOn()
412
+ } else {
413
+ return await (deviceList[0] as any).turnOff()
414
+ }
409
415
  } else {
410
- return await (device_list[0] as any).turnOff()
416
+ throw new Error('No devices found during discovery.')
411
417
  }
412
418
  },
413
419
  })
@@ -269,7 +269,7 @@ export class WaterDetector extends deviceBase {
269
269
  // Update HomeKit
270
270
  if (serviceData.model === SwitchBotBLEModel.Leak && serviceData.modelName === SwitchBotBLEModelName.Leak) {
271
271
  this.serviceData = serviceData
272
- if (serviceData !== undefined || serviceData !== null) {
272
+ if (serviceData !== undefined && serviceData !== null) {
273
273
  await this.BLEparseStatus()
274
274
  await this.updateHomeKitCharacteristics()
275
275
  } else {
@@ -295,7 +295,7 @@ export class WaterDetector extends deviceBase {
295
295
  this.platform.bleEventHandler[this.device.bleMac] = async (context: waterLeakDetectorServiceData) => {
296
296
  try {
297
297
  this.serviceData = context
298
- if (context !== undefined || context !== null) {
298
+ if (context !== undefined && context !== null) {
299
299
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
300
300
  await this.BLEparseStatus()
301
301
  await this.updateHomeKitCharacteristics()
@@ -340,7 +340,7 @@ export class WaterDetector extends deviceBase {
340
340
  this.platform.webhookEventHandler[this.device.deviceId] = async (context: waterLeakDetectorWebhookContext) => {
341
341
  try {
342
342
  this.webhookContext = context
343
- if (context !== undefined || context !== null) {
343
+ if (context !== undefined && context !== null) {
344
344
  this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
345
345
  await this.parseStatusWebhook()
346
346
  await this.updateHomeKitCharacteristics()
@@ -43,7 +43,7 @@
43
43
  </form>
44
44
  <table class="table w-100" id="deviceTable" style="display: none">
45
45
  <thead>
46
- <tr class="table-active">
46
+ <tr>
47
47
  <th scope="col" style="width: 40%">Device Name</th>
48
48
  <th scope="col" style="width: 60%" id="displayName"></th>
49
49
  </tr>
@@ -69,6 +69,18 @@
69
69
  <th scope="row">Connection Type</th>
70
70
  <td id="connectionType"></td>
71
71
  </tr>
72
+ <tr>
73
+ <th scope="row">Refresh Rate</th>
74
+ <td id="refreshRate"></td>
75
+ </tr>
76
+ <tr>
77
+ <th scope="row">Update Rate</th>
78
+ <td id="updateRate"></td>
79
+ </tr>
80
+ <tr>
81
+ <th scope="row">Push Rate</th>
82
+ <td id="pushRate"></td>
83
+ </tr>
72
84
  </tbody>
73
85
  </table>
74
86
  <p class="text-center">External accessories will not be displayed here.</p>