@switchbot/homebridge-switchbot 3.5.0 → 3.5.1-beta.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 (137) hide show
  1. package/.github/npm-version-script.cjs +81 -0
  2. package/config.schema.json +4 -4
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +64 -189
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts.map +1 -1
  7. package/dist/device/bot.js +34 -68
  8. package/dist/device/bot.js.map +1 -1
  9. package/dist/device/ceilinglight.d.ts +1 -1
  10. package/dist/device/ceilinglight.d.ts.map +1 -1
  11. package/dist/device/ceilinglight.js +65 -158
  12. package/dist/device/ceilinglight.js.map +1 -1
  13. package/dist/device/colorbulb.d.ts +1 -1
  14. package/dist/device/colorbulb.d.ts.map +1 -1
  15. package/dist/device/colorbulb.js +47 -159
  16. package/dist/device/colorbulb.js.map +1 -1
  17. package/dist/device/contact.d.ts.map +1 -1
  18. package/dist/device/contact.js +42 -105
  19. package/dist/device/contact.js.map +1 -1
  20. package/dist/device/curtain.d.ts +1 -0
  21. package/dist/device/curtain.d.ts.map +1 -1
  22. package/dist/device/curtain.js +61 -182
  23. package/dist/device/curtain.js.map +1 -1
  24. package/dist/device/device.d.ts +41 -2
  25. package/dist/device/device.d.ts.map +1 -1
  26. package/dist/device/device.js +182 -5
  27. package/dist/device/device.js.map +1 -1
  28. package/dist/device/fan.d.ts.map +1 -1
  29. package/dist/device/fan.js +76 -145
  30. package/dist/device/fan.js.map +1 -1
  31. package/dist/device/hub.d.ts +7 -1
  32. package/dist/device/hub.d.ts.map +1 -1
  33. package/dist/device/hub.js +54 -17
  34. package/dist/device/hub.js.map +1 -1
  35. package/dist/device/humidifier.d.ts.map +1 -1
  36. package/dist/device/humidifier.js +55 -104
  37. package/dist/device/humidifier.js.map +1 -1
  38. package/dist/device/iosensor.d.ts.map +1 -1
  39. package/dist/device/iosensor.js +27 -46
  40. package/dist/device/iosensor.js.map +1 -1
  41. package/dist/device/lightstrip.d.ts +1 -1
  42. package/dist/device/lightstrip.d.ts.map +1 -1
  43. package/dist/device/lightstrip.js +56 -120
  44. package/dist/device/lightstrip.js.map +1 -1
  45. package/dist/device/lock.d.ts +1 -1
  46. package/dist/device/lock.d.ts.map +1 -1
  47. package/dist/device/lock.js +36 -66
  48. package/dist/device/lock.js.map +1 -1
  49. package/dist/device/meter.d.ts.map +1 -1
  50. package/dist/device/meter.js +27 -46
  51. package/dist/device/meter.js.map +1 -1
  52. package/dist/device/meterplus.d.ts.map +1 -1
  53. package/dist/device/meterplus.js +26 -45
  54. package/dist/device/meterplus.js.map +1 -1
  55. package/dist/device/motion.d.ts.map +1 -1
  56. package/dist/device/motion.js +24 -43
  57. package/dist/device/motion.js.map +1 -1
  58. package/dist/device/plug.d.ts.map +1 -1
  59. package/dist/device/plug.js +32 -66
  60. package/dist/device/plug.js.map +1 -1
  61. package/dist/device/robotvacuumcleaner.d.ts +1 -1
  62. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  63. package/dist/device/robotvacuumcleaner.js +43 -88
  64. package/dist/device/robotvacuumcleaner.js.map +1 -1
  65. package/dist/device/waterdetector.d.ts.map +1 -1
  66. package/dist/device/waterdetector.js +23 -43
  67. package/dist/device/waterdetector.js.map +1 -1
  68. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  69. package/dist/irdevice/airconditioner.js +10 -28
  70. package/dist/irdevice/airconditioner.js.map +1 -1
  71. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  72. package/dist/irdevice/airpurifier.js +8 -20
  73. package/dist/irdevice/airpurifier.js.map +1 -1
  74. package/dist/irdevice/camera.d.ts.map +1 -1
  75. package/dist/irdevice/camera.js +8 -20
  76. package/dist/irdevice/camera.js.map +1 -1
  77. package/dist/irdevice/fan.d.ts.map +1 -1
  78. package/dist/irdevice/fan.js +8 -20
  79. package/dist/irdevice/fan.js.map +1 -1
  80. package/dist/irdevice/irdevice.d.ts +7 -0
  81. package/dist/irdevice/irdevice.d.ts.map +1 -1
  82. package/dist/irdevice/irdevice.js +28 -0
  83. package/dist/irdevice/irdevice.js.map +1 -1
  84. package/dist/irdevice/light.d.ts.map +1 -1
  85. package/dist/irdevice/light.js +8 -20
  86. package/dist/irdevice/light.js.map +1 -1
  87. package/dist/irdevice/other.d.ts.map +1 -1
  88. package/dist/irdevice/other.js +8 -20
  89. package/dist/irdevice/other.js.map +1 -1
  90. package/dist/irdevice/tv.d.ts.map +1 -1
  91. package/dist/irdevice/tv.js +8 -20
  92. package/dist/irdevice/tv.js.map +1 -1
  93. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  94. package/dist/irdevice/vacuumcleaner.js +8 -20
  95. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  96. package/dist/irdevice/waterheater.d.ts.map +1 -1
  97. package/dist/irdevice/waterheater.js +8 -20
  98. package/dist/irdevice/waterheater.js.map +1 -1
  99. package/dist/settings.d.ts +4 -2
  100. package/dist/settings.d.ts.map +1 -1
  101. package/dist/settings.js.map +1 -1
  102. package/dist/utils.d.ts +19 -1
  103. package/dist/utils.d.ts.map +1 -1
  104. package/dist/utils.js +20 -1
  105. package/dist/utils.js.map +1 -1
  106. package/package.json +8 -8
  107. package/src/device/blindtilt.ts +71 -186
  108. package/src/device/bot.ts +32 -68
  109. package/src/device/ceilinglight.ts +67 -153
  110. package/src/device/colorbulb.ts +51 -155
  111. package/src/device/contact.ts +49 -104
  112. package/src/device/curtain.ts +70 -177
  113. package/src/device/device.ts +207 -8
  114. package/src/device/fan.ts +75 -147
  115. package/src/device/hub.ts +55 -19
  116. package/src/device/humidifier.ts +52 -104
  117. package/src/device/iosensor.ts +25 -46
  118. package/src/device/lightstrip.ts +54 -121
  119. package/src/device/lock.ts +35 -67
  120. package/src/device/meter.ts +25 -46
  121. package/src/device/meterplus.ts +24 -45
  122. package/src/device/motion.ts +22 -43
  123. package/src/device/plug.ts +30 -66
  124. package/src/device/robotvacuumcleaner.ts +40 -89
  125. package/src/device/waterdetector.ts +22 -43
  126. package/src/irdevice/airconditioner.ts +10 -26
  127. package/src/irdevice/airpurifier.ts +8 -20
  128. package/src/irdevice/camera.ts +8 -20
  129. package/src/irdevice/fan.ts +8 -20
  130. package/src/irdevice/irdevice.ts +29 -0
  131. package/src/irdevice/light.ts +8 -20
  132. package/src/irdevice/other.ts +8 -20
  133. package/src/irdevice/tv.ts +8 -20
  134. package/src/irdevice/vacuumcleaner.ts +8 -20
  135. package/src/irdevice/waterheater.ts +8 -20
  136. package/src/settings.ts +4 -2
  137. package/src/utils.ts +20 -1
@@ -1,12 +1,14 @@
1
- import { request } from 'undici';
1
+ /* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * lock.ts: @switchbot/homebridge-switchbot.
4
+ */
2
5
  import { deviceBase } from './device.js';
3
6
  import { interval, Subject } from 'rxjs';
4
- import { Devices } from '../settings.js';
5
7
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
6
8
 
7
9
  import type { SwitchBotPlatform } from '../platform.js';
8
10
  import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
9
- import type { device, devicesConfig, deviceStatus, serviceData } from '../settings.js';
11
+ import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
10
12
 
11
13
  export class Lock extends deviceBase {
12
14
  // Services
@@ -289,63 +291,43 @@ export class Lock extends deviceBase {
289
291
 
290
292
  async BLERefreshStatus(): Promise<void> {
291
293
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
292
- const switchbot = await this.platform.connectBLE();
293
- // Convert to BLE Address
294
- this.device.bleMac = this.device
295
- .deviceId!.match(/.{1,2}/g)!
296
- .join(':')
297
- .toLowerCase();
298
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
299
- this.getCustomBLEAddress(switchbot);
294
+ const switchbot = await this.switchbotBLE();
295
+
296
+ if (switchbot === undefined) {
297
+ await this.BLERefreshConnection(switchbot);
298
+ } else {
300
299
  // Start to monitor advertisement packets
301
- (async () => {
300
+ (async () => {
302
301
  // Start to monitor advertisement packets
303
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
304
- // Set an event handler
305
- switchbot.onadvertisement = (ad: any) => {
306
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
307
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
308
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
309
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
302
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
303
+ // Update HomeKit
304
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
305
+ await this.BLEparseStatus(serviceData);
306
+ await this.updateHomeKitCharacteristics();
310
307
  } else {
311
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
308
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
309
+ await this.BLERefreshConnection(switchbot);
312
310
  }
313
- };
314
- // Wait 10 seconds
315
- await switchbot.wait(this.scanDuration * 1000);
316
- // Stop to monitor
317
- await switchbot.stopScan();
318
- // Update HomeKit
319
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
320
- await this.updateHomeKitCharacteristics();
321
- })();
322
- if (switchbot === undefined) {
323
- await this.BLERefreshConnection(switchbot);
311
+ })();
324
312
  }
325
313
  }
326
314
 
327
315
  async openAPIRefreshStatus(): Promise<void> {
328
316
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
329
317
  try {
330
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
331
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
332
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
318
+ const { body, statusCode } = await this.deviceRefreshStatus();
333
319
  const deviceStatus: any = await body.json();
334
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
335
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
320
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
336
321
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
337
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
338
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
339
- this.openAPIparseStatus(deviceStatus);
340
- this.updateHomeKitCharacteristics();
322
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
323
+ await this.openAPIparseStatus(deviceStatus);
324
+ await this.updateHomeKitCharacteristics();
341
325
  } else {
342
- this.statusCode(statusCode);
343
- this.statusCode(deviceStatus.statusCode);
326
+ await this.statusCodes(statusCode, deviceStatus);
344
327
  }
345
328
  } catch (e: any) {
346
- this.apiError(e);
347
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
348
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
329
+ await this.apiError(e);
330
+ await this.openAPIRefreshError(e);
349
331
  }
350
332
  }
351
333
 
@@ -384,8 +366,7 @@ export class Lock extends deviceBase {
384
366
  await this.openAPIpushChanges();
385
367
  } else {
386
368
  await this.offlineOff();
387
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
388
- + ` ${this.device.connectionType}, pushChanges will not happen.`);
369
+ await this.pushChangeDisabled();
389
370
  }
390
371
  // Refresh the status from the API
391
372
  interval(15000)
@@ -403,11 +384,7 @@ export class Lock extends deviceBase {
403
384
  + ` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
404
385
  const switchbot = await this.platform.connectBLE();
405
386
  // Convert to BLE Address
406
- this.device.bleMac = this.device
407
- .deviceId!.match(/.{1,2}/g)!
408
- .join(':')
409
- .toLowerCase();
410
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
387
+ await this.convertBLEAddress();
411
388
  switchbot
412
389
  .discover({
413
390
  model: '',
@@ -450,24 +427,15 @@ export class Lock extends deviceBase {
450
427
  });
451
428
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
452
429
  try {
453
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
454
- body: bodyChange,
455
- method: 'POST',
456
- headers: this.platform.generateHeaders(),
457
- });
458
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
430
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
459
431
  const deviceStatus: any = await body.json();
460
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
461
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
462
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
432
+ await this.pushStatusCodes(statusCode, deviceStatus);
463
433
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
464
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
465
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
466
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
467
- + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
434
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
435
+ await this.updateHomeKitCharacteristics();
468
436
  } else {
469
- this.statusCode(statusCode);
470
- this.statusCode(deviceStatus.statusCode);
437
+ await this.statusCode(statusCode);
438
+ await this.statusCode(deviceStatus.statusCode);
471
439
  }
472
440
  } catch (e: any) {
473
441
  this.apiError(e);
@@ -3,7 +3,6 @@
3
3
  * meter.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { Units } from 'homebridge';
6
- import { Devices } from '../settings.js';
7
6
  import { deviceBase } from './device.js';
8
7
  import { convertUnits } from '../utils.js';
9
8
  import { Subject, interval, skipWhile } from 'rxjs';
@@ -166,10 +165,10 @@ export class Meter extends deviceBase {
166
165
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.HumiditySensor!.CurrentRelativeHumidity}%`);
167
166
  }
168
167
 
169
- // CurrentTemperature
168
+ // Current Temperature
170
169
  if (!this.device.meter?.hide_temperature) {
171
- serviceData.temperature!.c < 0 ? 0 : serviceData.temperature!.c > 100 ? 100 : serviceData.temperature!.c;
172
- this.TemperatureSensor!.CurrentTemperature = serviceData.temperature!.c;
170
+ const celcius = serviceData.temperature!.c < 0 ? 0 : serviceData.temperature!.c > 100 ? 100 : serviceData.temperature!.c;
171
+ this.TemperatureSensor!.CurrentTemperature = celcius;
173
172
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor!.CurrentTemperature}°c`);
174
173
  }
175
174
  }
@@ -237,63 +236,43 @@ export class Meter extends deviceBase {
237
236
 
238
237
  async BLERefreshStatus(): Promise<void> {
239
238
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
240
- const switchbot = await this.platform.connectBLE();
241
- // Convert to BLE Address
242
- this.device.bleMac = this.device
243
- .deviceId!.match(/.{1,2}/g)!
244
- .join(':')
245
- .toLowerCase();
246
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
247
- this.getCustomBLEAddress(switchbot);
239
+ const switchbot = await this.switchbotBLE();
240
+
241
+ if (switchbot === undefined) {
242
+ await this.BLERefreshConnection(switchbot);
243
+ } else {
248
244
  // Start to monitor advertisement packets
249
- (async () => {
245
+ (async () => {
250
246
  // Start to monitor advertisement packets
251
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
252
- // Set an event handler
253
- switchbot.onadvertisement = (ad: any) => {
254
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
255
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
256
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
257
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
247
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
248
+ // Update HomeKit
249
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
250
+ await this.BLEparseStatus(serviceData);
251
+ await this.updateHomeKitCharacteristics();
258
252
  } else {
259
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
253
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
254
+ await this.BLERefreshConnection(switchbot);
260
255
  }
261
- };
262
- // Wait 10 seconds
263
- await switchbot.wait(this.scanDuration * 1000);
264
- // Stop to monitor
265
- await switchbot.stopScan();
266
- // Update HomeKit
267
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
268
- await this.updateHomeKitCharacteristics();
269
- })();
270
- if (switchbot === undefined) {
271
- await this.BLERefreshConnection(switchbot);
256
+ })();
272
257
  }
273
258
  }
274
259
 
275
260
  async openAPIRefreshStatus(): Promise<void> {
276
261
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
277
262
  try {
278
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
279
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
280
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
263
+ const { body, statusCode } = await this.deviceRefreshStatus();
281
264
  const deviceStatus: any = await body.json();
282
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
283
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
265
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
284
266
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
285
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
286
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
287
- this.openAPIparseStatus(deviceStatus);
288
- this.updateHomeKitCharacteristics();
267
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
268
+ await this.openAPIparseStatus(deviceStatus);
269
+ await this.updateHomeKitCharacteristics();
289
270
  } else {
290
- this.statusCode(statusCode);
291
- this.statusCode(deviceStatus.statusCode);
271
+ await this.statusCodes(statusCode, deviceStatus);
292
272
  }
293
273
  } catch (e: any) {
294
- this.apiError(e);
295
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
296
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
274
+ await this.apiError(e);
275
+ await this.openAPIRefreshError(e);
297
276
  }
298
277
  }
299
278
 
@@ -3,7 +3,6 @@
3
3
  * meterplus.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { Units } from 'homebridge';
6
- import { Devices } from '../settings.js';
7
6
  import { deviceBase } from './device.js';
8
7
  import { Subject, interval, skipWhile } from 'rxjs';
9
8
 
@@ -172,8 +171,8 @@ export class MeterPlus extends deviceBase {
172
171
 
173
172
  // Current Temperature
174
173
  if (!this.device.meter?.hide_temperature) {
175
- serviceData.temperature!.c < 0 ? 0 : serviceData.temperature!.c > 100 ? 100 : serviceData.temperature!.c;
176
- this.TemperatureSensor!.CurrentTemperature = serviceData.temperature!.c;
174
+ const celcius = serviceData.temperature!.c < 0 ? 0 : serviceData.temperature!.c > 100 ? 100 : serviceData.temperature!.c;
175
+ this.TemperatureSensor!.CurrentTemperature = celcius;
177
176
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor!.CurrentTemperature}°c`);
178
177
  }
179
178
  }
@@ -241,63 +240,43 @@ export class MeterPlus extends deviceBase {
241
240
 
242
241
  async BLERefreshStatus(): Promise<void> {
243
242
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
244
- const switchbot = await this.platform.connectBLE();
245
- // Convert to BLE Address
246
- this.device.bleMac = this.device
247
- .deviceId!.match(/.{1,2}/g)!
248
- .join(':')
249
- .toLowerCase();
250
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
251
- this.getCustomBLEAddress(switchbot);
243
+ const switchbot = await this.switchbotBLE();
244
+
245
+ if (switchbot === undefined) {
246
+ await this.BLERefreshConnection(switchbot);
247
+ } else {
252
248
  // Start to monitor advertisement packets
253
- (async () => {
249
+ (async () => {
254
250
  // Start to monitor advertisement packets
255
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
256
- // Set an event handler
257
- switchbot.onadvertisement = (ad: any) => {
258
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
259
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
260
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
261
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
251
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
252
+ // Update HomeKit
253
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
254
+ await this.BLEparseStatus(serviceData);
255
+ await this.updateHomeKitCharacteristics();
262
256
  } else {
263
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
257
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
258
+ await this.BLERefreshConnection(switchbot);
264
259
  }
265
- };
266
- // Wait 10 seconds
267
- await switchbot.wait(this.scanDuration * 1000);
268
- // Stop to monitor
269
- await switchbot.stopScan();
270
- // Update HomeKit
271
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
272
- await this.updateHomeKitCharacteristics();
273
- })();
274
- if (switchbot === undefined) {
275
- await this.BLERefreshConnection(switchbot);
260
+ })();
276
261
  }
277
262
  }
278
263
 
279
264
  async openAPIRefreshStatus(): Promise<void> {
280
265
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
281
266
  try {
282
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
283
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
284
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
267
+ const { body, statusCode } = await this.deviceRefreshStatus();
285
268
  const deviceStatus: any = await body.json();
286
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
287
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
269
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
288
270
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
289
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
290
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
291
- this.openAPIparseStatus(deviceStatus);
292
- this.updateHomeKitCharacteristics();
271
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
272
+ await this.openAPIparseStatus(deviceStatus);
273
+ await this.updateHomeKitCharacteristics();
293
274
  } else {
294
- this.statusCode(statusCode);
295
- this.statusCode(deviceStatus.statusCode);
275
+ await this.statusCodes(statusCode, deviceStatus);
296
276
  }
297
277
  } catch (e: any) {
298
- this.apiError(e);
299
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
300
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
278
+ await this.apiError(e);
279
+ await this.openAPIRefreshError(e);
301
280
  }
302
281
  }
303
282
 
@@ -3,7 +3,6 @@
3
3
  *
4
4
  * motion.ts: @switchbot/homebridge-switchbot.
5
5
  */
6
- import { Devices } from '../settings.js';
7
6
  import { deviceBase } from './device.js';
8
7
  import { Subject, interval, skipWhile } from 'rxjs';
9
8
 
@@ -250,63 +249,43 @@ export class Motion extends deviceBase {
250
249
 
251
250
  async BLERefreshStatus(): Promise<void> {
252
251
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
253
- const switchbot = await this.platform.connectBLE();
254
- // Convert to BLE Address
255
- this.device.bleMac = this.device
256
- .deviceId!.match(/.{1,2}/g)!
257
- .join(':')
258
- .toLowerCase();
259
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
260
- this.getCustomBLEAddress(switchbot);
252
+ const switchbot = await this.switchbotBLE();
253
+
254
+ if (switchbot === undefined) {
255
+ await this.BLERefreshConnection(switchbot);
256
+ } else {
261
257
  // Start to monitor advertisement packets
262
- (async () => {
258
+ (async () => {
263
259
  // Start to monitor advertisement packets
264
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
265
- // Set an event handler
266
- switchbot.onadvertisement = (ad: any) => {
267
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
268
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
269
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
270
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
260
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
261
+ // Update HomeKit
262
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
263
+ await this.BLEparseStatus(serviceData);
264
+ await this.updateHomeKitCharacteristics();
271
265
  } else {
272
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
266
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
267
+ await this.BLERefreshConnection(switchbot);
273
268
  }
274
- };
275
- // Wait 10 seconds
276
- await switchbot.wait(this.scanDuration * 1000);
277
- // Stop to monitor
278
- await switchbot.stopScan();
279
- // Update HomeKit
280
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
281
- await this.updateHomeKitCharacteristics();
282
- })();
283
- if (switchbot === undefined) {
284
- await this.BLERefreshConnection(switchbot);
269
+ })();
285
270
  }
286
271
  }
287
272
 
288
273
  async openAPIRefreshStatus(): Promise<void> {
289
274
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
290
275
  try {
291
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
292
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
293
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
276
+ const { body, statusCode } = await this.deviceRefreshStatus();
294
277
  const deviceStatus: any = await body.json();
295
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
296
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
278
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
297
279
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
298
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
299
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
300
- this.openAPIparseStatus(deviceStatus);
301
- this.updateHomeKitCharacteristics();
280
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
281
+ await this.openAPIparseStatus(deviceStatus);
282
+ await this.updateHomeKitCharacteristics();
302
283
  } else {
303
- this.statusCode(statusCode);
304
- this.statusCode(deviceStatus.statusCode);
284
+ await this.statusCodes(statusCode, deviceStatus);
305
285
  }
306
286
  } catch (e: any) {
307
- this.apiError(e);
308
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
309
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
287
+ await this.apiError(e);
288
+ await this.openAPIRefreshError(e);
310
289
  }
311
290
  }
312
291
 
@@ -2,8 +2,6 @@
2
2
  *
3
3
  * plug.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { request } from 'undici';
6
- import { Devices } from '../settings.js';
7
5
  import { deviceBase } from './device.js';
8
6
  import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
9
7
 
@@ -146,63 +144,43 @@ export class Plug extends deviceBase {
146
144
 
147
145
  async BLERefreshStatus(): Promise<void> {
148
146
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
149
- const switchbot = await this.platform.connectBLE();
150
- // Convert to BLE Address
151
- this.device.bleMac = this.device
152
- .deviceId!.match(/.{1,2}/g)!
153
- .join(':')
154
- .toLowerCase();
155
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
156
- this.getCustomBLEAddress(switchbot);
147
+ const switchbot = await this.switchbotBLE();
148
+
149
+ if (switchbot === undefined) {
150
+ await this.BLERefreshConnection(switchbot);
151
+ } else {
157
152
  // Start to monitor advertisement packets
158
- (async () => {
153
+ (async () => {
159
154
  // Start to monitor advertisement packets
160
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
161
- // Set an event handler
162
- switchbot.onadvertisement = (ad: any) => {
163
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
164
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
165
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
166
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
155
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
156
+ // Update HomeKit
157
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
158
+ await this.BLEparseStatus(serviceData);
159
+ await this.updateHomeKitCharacteristics();
167
160
  } else {
168
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
161
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
162
+ await this.BLERefreshConnection(switchbot);
169
163
  }
170
- };
171
- // Wait 10 seconds
172
- await switchbot.wait(this.scanDuration * 1000);
173
- // Stop to monitor
174
- await switchbot.stopScan();
175
- // Update HomeKit
176
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
177
- await this.updateHomeKitCharacteristics();
178
- })();
179
- if (switchbot === undefined) {
180
- await this.BLERefreshConnection(switchbot);
164
+ })();
181
165
  }
182
166
  }
183
167
 
184
168
  async openAPIRefreshStatus(): Promise<void> {
185
169
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
186
170
  try {
187
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
188
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
189
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
171
+ const { body, statusCode } = await this.deviceRefreshStatus();
190
172
  const deviceStatus: any = await body.json();
191
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
192
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
173
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
193
174
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
194
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
195
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
196
- this.openAPIparseStatus(deviceStatus);
197
- this.updateHomeKitCharacteristics();
175
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
176
+ await this.openAPIparseStatus(deviceStatus);
177
+ await this.updateHomeKitCharacteristics();
198
178
  } else {
199
- this.statusCode(statusCode);
200
- this.statusCode(deviceStatus.statusCode);
179
+ await this.statusCodes(statusCode, deviceStatus);
201
180
  }
202
181
  } catch (e: any) {
203
- this.apiError(e);
204
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
205
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
182
+ await this.apiError(e);
183
+ await this.openAPIRefreshError(e);
206
184
  }
207
185
  }
208
186
 
@@ -245,8 +223,7 @@ export class Plug extends deviceBase {
245
223
  await this.openAPIpushChanges();
246
224
  } else {
247
225
  await this.offlineOff();
248
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
249
- + ` ${this.device.connectionType}, pushChanges will not happen.`);
226
+ await this.pushChangeDisabled();
250
227
  }
251
228
  // Refresh the status from the API
252
229
  interval(15000)
@@ -264,11 +241,7 @@ export class Plug extends deviceBase {
264
241
  + ` On: ${this.Outlet.On} OnCached: ${this.accessory.context.On}`);
265
242
  const switchbot = await this.platform.connectBLE();
266
243
  // Convert to BLE Address
267
- this.device.bleMac = this.device
268
- .deviceId!.match(/.{1,2}/g)!
269
- .join(':')
270
- .toLowerCase();
271
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
244
+ await this.convertBLEAddress();
272
245
  switchbot
273
246
  .discover({
274
247
  model: this.device.bleModel,
@@ -321,24 +294,15 @@ export class Plug extends deviceBase {
321
294
  });
322
295
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
323
296
  try {
324
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
325
- body: bodyChange,
326
- method: 'POST',
327
- headers: this.platform.generateHeaders(),
328
- });
329
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
297
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
330
298
  const deviceStatus: any = await body.json();
331
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
332
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
333
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
299
+ await this.pushStatusCodes(statusCode, deviceStatus);
334
300
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
335
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
336
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
337
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
338
- + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
301
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
302
+ await this.updateHomeKitCharacteristics();
339
303
  } else {
340
- this.statusCode(statusCode);
341
- this.statusCode(deviceStatus.statusCode);
304
+ await this.statusCode(statusCode);
305
+ await this.statusCode(deviceStatus.statusCode);
342
306
  }
343
307
  } catch (e: any) {
344
308
  this.apiError(e);