@switchbot/homebridge-switchbot 1.7.1-beta.1 → 1.7.1-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +7 -2
  2. package/config.schema.json +46 -33
  3. package/dist/devices/bots.d.ts +4 -2
  4. package/dist/devices/bots.d.ts.map +1 -1
  5. package/dist/devices/bots.js +40 -40
  6. package/dist/devices/bots.js.map +1 -1
  7. package/dist/devices/colorbulb.d.ts +6 -1
  8. package/dist/devices/colorbulb.d.ts.map +1 -1
  9. package/dist/devices/colorbulb.js +18 -11
  10. package/dist/devices/colorbulb.js.map +1 -1
  11. package/dist/devices/contact.d.ts +6 -7
  12. package/dist/devices/contact.d.ts.map +1 -1
  13. package/dist/devices/contact.js +69 -107
  14. package/dist/devices/contact.js.map +1 -1
  15. package/dist/devices/curtains.d.ts +10 -3
  16. package/dist/devices/curtains.d.ts.map +1 -1
  17. package/dist/devices/curtains.js +52 -34
  18. package/dist/devices/curtains.js.map +1 -1
  19. package/dist/devices/humidifiers.d.ts +8 -2
  20. package/dist/devices/humidifiers.d.ts.map +1 -1
  21. package/dist/devices/humidifiers.js +28 -35
  22. package/dist/devices/humidifiers.js.map +1 -1
  23. package/dist/devices/meters.d.ts +14 -12
  24. package/dist/devices/meters.d.ts.map +1 -1
  25. package/dist/devices/meters.js +63 -103
  26. package/dist/devices/meters.js.map +1 -1
  27. package/dist/devices/motion.d.ts +5 -6
  28. package/dist/devices/motion.d.ts.map +1 -1
  29. package/dist/devices/motion.js +61 -90
  30. package/dist/devices/motion.js.map +1 -1
  31. package/dist/devices/plugs.d.ts +3 -1
  32. package/dist/devices/plugs.d.ts.map +1 -1
  33. package/dist/devices/plugs.js +8 -1
  34. package/dist/devices/plugs.js.map +1 -1
  35. package/dist/irdevices/airconditioners.d.ts +1 -0
  36. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  37. package/dist/irdevices/airconditioners.js +6 -0
  38. package/dist/irdevices/airconditioners.js.map +1 -1
  39. package/dist/irdevices/airpurifiers.d.ts +1 -0
  40. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  41. package/dist/irdevices/airpurifiers.js +6 -0
  42. package/dist/irdevices/airpurifiers.js.map +1 -1
  43. package/dist/irdevices/cameras.d.ts +1 -0
  44. package/dist/irdevices/cameras.d.ts.map +1 -1
  45. package/dist/irdevices/cameras.js +6 -0
  46. package/dist/irdevices/cameras.js.map +1 -1
  47. package/dist/irdevices/fans.d.ts +1 -0
  48. package/dist/irdevices/fans.d.ts.map +1 -1
  49. package/dist/irdevices/fans.js +6 -0
  50. package/dist/irdevices/fans.js.map +1 -1
  51. package/dist/irdevices/lights.d.ts +1 -0
  52. package/dist/irdevices/lights.d.ts.map +1 -1
  53. package/dist/irdevices/lights.js +6 -0
  54. package/dist/irdevices/lights.js.map +1 -1
  55. package/dist/irdevices/others.d.ts +1 -0
  56. package/dist/irdevices/others.d.ts.map +1 -1
  57. package/dist/irdevices/others.js +6 -0
  58. package/dist/irdevices/others.js.map +1 -1
  59. package/dist/irdevices/tvs.d.ts +1 -0
  60. package/dist/irdevices/tvs.d.ts.map +1 -1
  61. package/dist/irdevices/tvs.js +6 -0
  62. package/dist/irdevices/tvs.js.map +1 -1
  63. package/dist/irdevices/vacuumcleaners.d.ts +1 -0
  64. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  65. package/dist/irdevices/vacuumcleaners.js +6 -0
  66. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  67. package/dist/irdevices/waterheaters.d.ts +1 -0
  68. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  69. package/dist/irdevices/waterheaters.js +6 -0
  70. package/dist/irdevices/waterheaters.js.map +1 -1
  71. package/dist/platform.d.ts +2 -1
  72. package/dist/platform.d.ts.map +1 -1
  73. package/dist/platform.js +14 -1
  74. package/dist/platform.js.map +1 -1
  75. package/dist/settings.d.ts +6 -0
  76. package/dist/settings.d.ts.map +1 -1
  77. package/dist/settings.js.map +1 -1
  78. package/package.json +5 -5
  79. package/src/devices/bots.ts +43 -44
  80. package/src/devices/colorbulb.ts +24 -14
  81. package/src/devices/contact.ts +72 -108
  82. package/src/devices/curtains.ts +60 -36
  83. package/src/devices/humidifiers.ts +36 -36
  84. package/src/devices/meters.ts +79 -113
  85. package/src/devices/motion.ts +66 -91
  86. package/src/devices/plugs.ts +11 -2
  87. package/src/irdevices/airconditioners.ts +7 -0
  88. package/src/irdevices/airpurifiers.ts +7 -0
  89. package/src/irdevices/cameras.ts +7 -0
  90. package/src/irdevices/fans.ts +7 -0
  91. package/src/irdevices/lights.ts +7 -0
  92. package/src/irdevices/others.ts +7 -0
  93. package/src/irdevices/tvs.ts +7 -0
  94. package/src/irdevices/vacuumcleaners.ts +7 -0
  95. package/src/irdevices/waterheaters.ts +7 -0
  96. package/src/platform.ts +14 -1
  97. package/src/settings.ts +6 -0
@@ -4,7 +4,7 @@ import { interval, Subject } from 'rxjs';
4
4
  import { SwitchBotPlatform } from '../platform';
5
5
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
6
6
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
7
- import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, payload } from '../settings';
7
+ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, payload, deviceStatus } from '../settings';
8
8
 
9
9
  /**
10
10
  * Platform Accessory
@@ -33,11 +33,13 @@ export class Bot {
33
33
  StatusLowBattery!: CharacteristicValue;
34
34
 
35
35
  // OpenAPI Others
36
+ power: deviceStatus['power'];
36
37
  deviceStatus!: deviceStatusResponse;
37
38
 
38
39
  // BLE Others
39
40
  connected?: boolean;
40
41
  switchbot!: switchbot;
42
+ SwitchToOpenAPI?: boolean;
41
43
  serviceData!: serviceData;
42
44
  mode!: serviceData['mode'];
43
45
  state!: serviceData['state'];
@@ -66,7 +68,7 @@ export class Bot {
66
68
  this.scan();
67
69
  this.refreshRate();
68
70
  this.PressOrSwitch();
69
-
71
+ this.config(device);
70
72
  if (this.On === undefined) {
71
73
  this.On = false;
72
74
  this.accessory.context.On = this.On;
@@ -82,10 +84,6 @@ export class Bot {
82
84
  this.BatteryLevel = 100;
83
85
  this.StatusLowBattery = 0;
84
86
 
85
- // Bot Config
86
- this.debugLog(`Bot: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline}, mode: ${device.bot?.mode},`
87
- + ` deviceType: ${device.bot?.deviceType}, doublePress: ${this.doublePress})`);
88
-
89
87
  // this is subject we use to track when we need to POST changes to the SwitchBot API
90
88
  this.doBotUpdate = new Subject();
91
89
  this.botUpdateInProgress = false;
@@ -317,12 +315,21 @@ export class Bot {
317
315
  this.outletService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
318
316
  }
319
317
 
320
- if (device.ble) {
318
+ // Battery Service
319
+ if (!device.ble) {
320
+ this.debugLog(`Bot: ${accessory.displayName} Removing Battery Service`);
321
+ this.batteryService = this.accessory.getService(this.platform.Service.Battery);
322
+ accessory.removeService(this.batteryService!);
323
+ } else if (device.ble && !this.batteryService) {
324
+ this.debugLog(`Bot: ${accessory.displayName} Add Battery Service`);
321
325
  (this.batteryService =
322
- accessory.getService(this.platform.Service.Battery) ||
323
- accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
326
+ this.accessory.getService(this.platform.Service.Battery) ||
327
+ this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
324
328
 
325
329
  this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
330
+
331
+ } else {
332
+ this.debugLog(`Bot: ${accessory.displayName} Battery Service Not Added`);
326
333
  }
327
334
 
328
335
  // Retrieve initial values and updateHomekit
@@ -366,6 +373,12 @@ export class Bot {
366
373
  });
367
374
  }
368
375
 
376
+ config(device: device & devicesConfig) {
377
+ if (device.bot !== undefined || device.ble !== undefined) {
378
+ this.warnLog(`Bot: ${this.accessory.displayName} Config: ${JSON.stringify(device.bot)}, BLE: ${device.ble}`);
379
+ }
380
+ }
381
+
369
382
  public removeOutletService(accessory: PlatformAccessory) {
370
383
  // If outletService still pressent, then remove first
371
384
  this.outletService = this.accessory.getService(this.platform.Service.Outlet);
@@ -459,12 +472,12 @@ export class Bot {
459
472
  refreshRate() {
460
473
  if (this.device.refreshRate) {
461
474
  this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
462
- if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
475
+ if (this.deviceLogging === 'debug' || this.deviceLogging === 'standard') {
463
476
  this.warnLog(`Bot: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
464
477
  }
465
478
  } else if (this.platform.config.options!.refreshRate) {
466
479
  this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
467
- if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
480
+ if (this.deviceLogging === 'debug') {
468
481
  this.warnLog(`Bot: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
469
482
  }
470
483
  }
@@ -473,12 +486,12 @@ export class Bot {
473
486
  scan() {
474
487
  if (this.device.scanDuration) {
475
488
  this.scanDuration = this.accessory.context.scanDuration = this.device.scanDuration;
476
- if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
489
+ if (this.device.ble && (this.deviceLogging === 'debug' || this.deviceLogging === 'standard')) {
477
490
  this.warnLog(`Bot: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
478
491
  }
479
492
  } else {
480
493
  this.scanDuration = this.accessory.context.scanDuration = 1;
481
- if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
494
+ if (this.device.ble && this.deviceLogging === 'debug') {
482
495
  this.warnLog(`Bot: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
483
496
  }
484
497
  }
@@ -523,10 +536,10 @@ export class Bot {
523
536
  * Parse the device status from the SwitchBot api
524
537
  */
525
538
  async parseStatus() {
526
- if (this.device.ble) {
527
- await this.BLEparseStatus();
528
- } else {
539
+ if (this.SwitchToOpenAPI || !this.device.ble) {
529
540
  await this.openAPIparseStatus();
541
+ } else {
542
+ await this.BLEparseStatus();
530
543
  }
531
544
  }
532
545
 
@@ -560,6 +573,9 @@ export class Bot {
560
573
  }
561
574
 
562
575
  private async openAPIparseStatus() {
576
+ if (this.device.ble) {
577
+ this.SwitchToOpenAPI = false;
578
+ }
563
579
  if (this.platform.config.credentials?.openToken) {
564
580
  this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI parseStatus`);
565
581
  if (this.botMode === 'press') {
@@ -567,7 +583,7 @@ export class Bot {
567
583
  this.OnCached = this.On;
568
584
  this.accessory.context.On = this.OnCached;
569
585
  } else {
570
- /*if (this.deviceStatus.body.power === 'on') {
586
+ /*if (this.power === 'on') {
571
587
  this.On = true;
572
588
  this.OnCached = this.On;
573
589
  this.accessory.context.On = this.OnCached;
@@ -597,35 +613,12 @@ export class Bot {
597
613
  }
598
614
  }
599
615
 
600
- public async connectBLE() {
601
- let switchbot: any;
602
- try {
603
- // eslint-disable-next-line @typescript-eslint/no-var-requires
604
- const Switchbot = require('node-switchbot');
605
- switchbot = new Switchbot();
606
- // Convert to BLE Address
607
- this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
608
- this.debugLog(`Bot: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
609
- } catch (e: any) {
610
- switchbot = false;
611
- this.errorLog(`Bot: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
612
- if (this.deviceLogging === 'debug') {
613
- this.errorLog(`Bot: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
614
- + ` Error Message: ${JSON.stringify(e.message)}`);
615
- }
616
- if (this.platform.debugMode) {
617
- this.errorLog(`Bot: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
618
- + ` Error: ${JSON.stringify(e)}`);
619
- }
620
- }
621
- return switchbot;
622
- }
623
-
624
616
  private async BLERefreshStatus() {
625
617
  this.debugLog(`Bot: ${this.accessory.displayName} BLE refreshStatus`);
626
-
618
+ const switchbot = await this.platform.connectBLE();
627
619
  // Convert to BLE Address
628
- const switchbot = await this.connectBLE();
620
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
621
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
629
622
  // Start to monitor advertisement packets
630
623
  if (switchbot === false) {
631
624
  this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection: ${switchbot}`);
@@ -664,6 +657,7 @@ export class Bot {
664
657
  this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
665
658
  if (this.platform.config.credentials?.openToken) {
666
659
  this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
660
+ this.SwitchToOpenAPI = true;
667
661
  await this.openAPIRefreshStatus();
668
662
  }
669
663
  }
@@ -679,6 +673,7 @@ export class Bot {
679
673
  }
680
674
  if (this.platform.config.credentials?.openToken) {
681
675
  this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
676
+ this.SwitchToOpenAPI = true;
682
677
  await this.openAPIRefreshStatus();
683
678
  }
684
679
  this.apiError(e);
@@ -691,6 +686,7 @@ export class Bot {
691
686
  try {
692
687
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
693
688
  this.debugLog(`Bot: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
689
+ this.power = this.deviceStatus.body.power;
694
690
  this.parseStatus();
695
691
  this.updateHomeKitCharacteristics();
696
692
  } catch (e: any) {
@@ -733,7 +729,10 @@ export class Bot {
733
729
  this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges On: ${this.On} OnCached: ${this.OnCached}`);
734
730
  if (this.On !== this.OnCached) {
735
731
  this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges`);
736
- const switchbot = await this.connectBLE();
732
+ const switchbot = await this.platform.connectBLE();
733
+ // Convert to BLE Address
734
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
735
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
737
736
  //if (switchbot !== false) {
738
737
  if (this.botMode === 'press') {
739
738
  this.debugLog(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
@@ -3,7 +3,7 @@ import { interval, Subject } from 'rxjs';
3
3
  import { SwitchBotPlatform } from '../platform';
4
4
  import { debounceTime, skipWhile, tap } from 'rxjs/operators';
5
5
  import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
6
- import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse, payload, hs2rgb, rgb2hs, m2hs } from '../settings';
6
+ import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse, payload, hs2rgb, rgb2hs, m2hs, deviceStatus } from '../settings';
7
7
 
8
8
  /**
9
9
  * Platform Accessory
@@ -27,6 +27,10 @@ export class ColorBulb {
27
27
  ColorTemperatureCached!: CharacteristicValue;
28
28
 
29
29
  // OpenAPI Others
30
+ power: deviceStatus['power'];
31
+ color: deviceStatus['color'];
32
+ brightness: deviceStatus['brightness'];
33
+ colorTemperature: deviceStatus['colorTemperature'];
30
34
  deviceStatus!: deviceStatusResponse;
31
35
 
32
36
  // BLE Others
@@ -57,6 +61,7 @@ export class ColorBulb {
57
61
  this.logs();
58
62
  this.refreshRate();
59
63
  this.adaptiveLighting();
64
+ this.config(device);
60
65
  if (this.On === undefined) {
61
66
  this.On = false;
62
67
  } else {
@@ -68,11 +73,6 @@ export class ColorBulb {
68
73
  this.ColorTemperature = 140;
69
74
  this.minKelvin = 2000;
70
75
  this.maxKelvin = 9000;
71
-
72
- // ColorBulb Config
73
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Config: (ble: ${device.ble}, set_minStep: ${device.colorbulb?.set_minStep},`
74
- + ` adaptiveLighting: ${device.colorbulb?.adaptiveLightingShift})`);
75
-
76
76
  // this is subject we use to track when we need to POST changes to the SwitchBot API
77
77
  this.doColorBulbUpdate = new Subject();
78
78
  this.colorBulbUpdateInProgress = false;
@@ -214,6 +214,12 @@ export class ColorBulb {
214
214
  });
215
215
  }
216
216
 
217
+ config(device: device & devicesConfig) {
218
+ if (device.colorbulb !== undefined) {
219
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} Config: ${JSON.stringify(device.colorbulb)}`);
220
+ }
221
+ }
222
+
217
223
  refreshRate() {
218
224
  if (this.device.refreshRate) {
219
225
  this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
@@ -267,7 +273,7 @@ export class ColorBulb {
267
273
  }
268
274
 
269
275
  parseStatus() {
270
- switch (this.deviceStatus.body.power) {
276
+ switch (this.power) {
271
277
  case 'on':
272
278
  this.On = true;
273
279
  break;
@@ -277,13 +283,13 @@ export class ColorBulb {
277
283
  this.debugLog(`Color Bulb: ${this.accessory.displayName} On: ${this.On}`);
278
284
 
279
285
  // Brightness
280
- this.Brightness = Number(this.deviceStatus.body.brightness);
286
+ this.Brightness = Number(this.brightness);
281
287
  this.debugLog(`Color Bulb: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
282
288
 
283
289
  // Color, Hue & Brightness
284
- if (this.deviceStatus.body.color) {
285
- this.debugLog(`Color Bulb: ${this.accessory.displayName} color: ${JSON.stringify(this.deviceStatus.body.color)}`);
286
- const [red, green, blue] = this.deviceStatus.body.color!.split(':');
290
+ if (this.color) {
291
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} color: ${JSON.stringify(this.color)}`);
292
+ const [red, green, blue] = this.color!.split(':');
287
293
  this.debugLog(`Color Bulb: ${this.accessory.displayName} red: ${JSON.stringify(red)}`);
288
294
  this.debugLog(`Color Bulb: ${this.accessory.displayName} green: ${JSON.stringify(green)}`);
289
295
  this.debugLog(`Color Bulb: ${this.accessory.displayName} blue: ${JSON.stringify(blue)}`);
@@ -301,9 +307,9 @@ export class ColorBulb {
301
307
  }
302
308
 
303
309
  // ColorTemperature
304
- if (!Number.isNaN(this.deviceStatus.body.colorTemperature)) {
305
- this.debugLog(`Color Bulb: ${this.accessory.displayName} OpenAPI ColorTemperature: ${this.deviceStatus.body.colorTemperature}`);
306
- const mired = Math.round(1000000 / this.deviceStatus.body.colorTemperature!);
310
+ if (!Number.isNaN(this.colorTemperature)) {
311
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} OpenAPI ColorTemperature: ${this.colorTemperature}`);
312
+ const mired = Math.round(1000000 / this.colorTemperature!);
307
313
 
308
314
  this.ColorTemperature = Number(mired);
309
315
 
@@ -316,6 +322,10 @@ export class ColorBulb {
316
322
  try {
317
323
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
318
324
  this.debugLog(`Color Bulb: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
325
+ this.power = this.deviceStatus.body.power;
326
+ this.color = this.deviceStatus.body.color;
327
+ this.brightness = this.deviceStatus.body.brightness;
328
+ this.colorTemperature = this.deviceStatus.body.colorTemperature;
319
329
  this.parseStatus();
320
330
  this.updateHomeKitCharacteristics();
321
331
  } catch (e: any) {
@@ -2,7 +2,7 @@ import { interval, Subject } from 'rxjs';
2
2
  import { skipWhile } from 'rxjs/operators';
3
3
  import { SwitchBotPlatform } from '../platform';
4
4
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
5
- import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
5
+ import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, deviceStatus } from '../settings';
6
6
 
7
7
  /**
8
8
  * Platform Accessory
@@ -24,11 +24,15 @@ export class Contact {
24
24
  StatusLowBattery!: CharacteristicValue;
25
25
 
26
26
  // OpenAPI others
27
+ openState: deviceStatus['openState'];
28
+ moveDetected: deviceStatus['moveDetected'];
29
+ brightness: deviceStatus['brightness'];
27
30
  deviceStatus!: deviceStatusResponse;
28
31
 
29
32
  // BLE Others
30
33
  connected?: boolean;
31
34
  switchbot!: switchbot;
35
+ SwitchToOpenAPI!: boolean;
32
36
  serviceData!: serviceData;
33
37
  battery!: serviceData['battery'];
34
38
  movement!: serviceData['movement'];
@@ -55,13 +59,9 @@ export class Contact {
55
59
  this.logs();
56
60
  this.scan();
57
61
  this.refreshRate();
62
+ this.config(device);
58
63
  this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
59
64
 
60
- // Contact Config
61
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline},`
62
- + ` hide_lightsensor: ${device.contact?.hide_lightsensor}, hide_motionsensor: ${device.contact?.hide_motionsensor},`
63
- + ` set_minLux: ${this.device.contact?.set_minLux}, set_maxLux: ${this.device.contact?.set_maxLux})`);
64
-
65
65
  // this is subject we use to track when we need to POST changes to the SwitchBot API
66
66
  this.doContactUpdate = new Subject();
67
67
  this.contactUbpdateInProgress = false;
@@ -128,12 +128,20 @@ export class Contact {
128
128
  }
129
129
 
130
130
  // Battery Service
131
- if (device.ble) {
131
+ if (!device.ble) {
132
+ this.debugLog(`Contact Sensor: ${accessory.displayName} Removing Battery Service`);
133
+ this.batteryService = this.accessory.getService(this.platform.Service.Battery);
134
+ accessory.removeService(this.batteryService!);
135
+ } else if (device.ble && !this.batteryService) {
136
+ this.debugLog(`Contact Sensor: ${accessory.displayName} Add Battery Service`);
132
137
  (this.batteryService =
133
- accessory.getService(this.platform.Service.Battery) ||
134
- accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
138
+ this.accessory.getService(this.platform.Service.Battery) ||
139
+ this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
135
140
 
136
141
  this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
142
+
143
+ } else {
144
+ this.debugLog(`Contact Sensor: ${accessory.displayName} Battery Service Not Added`);
137
145
  }
138
146
 
139
147
  // Retrieve initial values and updateHomekit
@@ -147,6 +155,12 @@ export class Contact {
147
155
  });
148
156
  }
149
157
 
158
+ config(device: device & devicesConfig) {
159
+ if (device.contact !== undefined) {
160
+ this.warnLog(`Contact Sensor: ${this.accessory.displayName} Config: ${JSON.stringify(device.contact)}`);
161
+ }
162
+ }
163
+
150
164
  refreshRate() {
151
165
  if (this.device.refreshRate) {
152
166
  this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
@@ -216,10 +230,10 @@ export class Contact {
216
230
  * Parse the device status from the SwitchBot api
217
231
  */
218
232
  async parseStatus() {
219
- if (this.device.ble) {
220
- await this.BLEparseStatus();
221
- } else {
233
+ if (this.SwitchToOpenAPI || !this.device.ble) {
222
234
  await this.openAPIparseStatus();
235
+ } else {
236
+ await this.BLEparseStatus();
223
237
  }
224
238
  }
225
239
 
@@ -240,27 +254,23 @@ export class Contact {
240
254
  }
241
255
  // Movement
242
256
  if (!this.device.contact?.hide_motionsensor) {
243
- if (this.movement === undefined && this.platform.config.credentials?.openToken) {
244
- this.openAPImotion();
245
- } else if (this.movement === undefined) {
246
- this.movement = false;
247
- this.BLEmotion();
248
- } else {
249
- this.BLEmotion();
250
- }
257
+ this.MotionDetected = Boolean(this.movement);
258
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
251
259
  }
252
260
  // Light Level
253
261
  if (!this.device.contact?.hide_lightsensor) {
254
262
  this.set_minLux = this.minLux();
255
263
  this.set_maxLux = this.maxLux();
256
- if (this.lightLevel === undefined && this.platform.config.credentials?.openToken) {
257
- this.openAPIlux();
258
- } else if (this.lightLevel === undefined) {
259
- this.lightLevel = 100;
260
- this.BLElux();
261
- } else {
262
- this.BLElux();
264
+ switch (this.lightLevel) {
265
+ case 'dark':
266
+ case 0:
267
+ this.CurrentAmbientLightLevel = this.set_minLux;
268
+ break;
269
+ default:
270
+ this.CurrentAmbientLightLevel = this.set_maxLux;
263
271
  }
272
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
273
+ + ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
264
274
  }
265
275
  // Battery
266
276
  if (this.battery === undefined) {
@@ -275,73 +285,44 @@ export class Contact {
275
285
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
276
286
  }
277
287
 
278
- private BLEmotion() {
279
- this.MotionDetected = Boolean(this.movement);
280
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
281
- }
282
-
283
- private BLElux() {
284
- switch (this.lightLevel) {
285
- case 'dark':
286
- case 0:
287
- this.CurrentAmbientLightLevel = this.set_minLux;
288
- break;
289
- default:
290
- this.CurrentAmbientLightLevel = this.set_maxLux;
291
- }
292
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
293
- + ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
294
- }
295
-
296
288
  private async openAPIparseStatus() {
289
+ if (this.device.ble) {
290
+ this.SwitchToOpenAPI = false;
291
+ }
297
292
  if (this.platform.config.credentials?.openToken) {
293
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
298
294
  // Contact State
299
- this.openAPIcontact();
295
+ if (this.openState === 'open') {
296
+ this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
297
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
298
+ } else if (this.openState === 'close') {
299
+ this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
300
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
301
+ } else {
302
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.openState}`);
303
+ }
300
304
  // Motion State
301
305
  if (!this.device.contact?.hide_motionsensor) {
302
- this.openAPImotion();
306
+ this.MotionDetected = this.moveDetected!;
307
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
303
308
  }
304
309
  // Light Level
305
310
  if (!this.device.contact?.hide_lightsensor) {
306
- this.openAPIlux();
311
+ this.set_minLux = this.minLux();
312
+ this.set_maxLux = this.maxLux();
313
+ switch (this.brightness) {
314
+ case 'dim':
315
+ this.CurrentAmbientLightLevel = this.set_minLux;
316
+ break;
317
+ case 'bright':
318
+ default:
319
+ this.CurrentAmbientLightLevel = this.set_maxLux;
320
+ }
321
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
307
322
  }
308
323
  }
309
324
  }
310
325
 
311
- private openAPIlux() {
312
- this.set_minLux = this.minLux();
313
- this.set_maxLux = this.maxLux();
314
- switch (this.deviceStatus.body.brightness) {
315
- case 'dim':
316
- this.CurrentAmbientLightLevel = this.set_minLux;
317
- break;
318
- case 'bright':
319
- default:
320
- this.CurrentAmbientLightLevel = this.set_maxLux;
321
- }
322
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
323
- }
324
-
325
- private openAPImotion() {
326
- if (typeof this.deviceStatus.body.moveDetected === 'boolean') {
327
- this.MotionDetected = this.deviceStatus.body.moveDetected;
328
- }
329
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
330
- }
331
-
332
- private openAPIcontact() {
333
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
334
- if (this.deviceStatus.body.openState === 'open') {
335
- this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
336
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
337
- } else if (this.deviceStatus.body.openState === 'close') {
338
- this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
339
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
340
- } else {
341
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.deviceStatus.body.openState}`);
342
- }
343
- }
344
-
345
326
  /**
346
327
  * Asks the SwitchBot API for the latest device information
347
328
  */
@@ -353,34 +334,12 @@ export class Contact {
353
334
  }
354
335
  }
355
336
 
356
- public async connectBLE() {
357
- let switchbot: any;
358
- try {
359
- // eslint-disable-next-line @typescript-eslint/no-var-requires
360
- const Switchbot = require('node-switchbot');
361
- switchbot = new Switchbot();
362
- // Convert to BLE Address
363
- this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
364
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
365
- } catch (e: any) {
366
- switchbot = false;
367
- this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
368
- if (this.deviceLogging === 'debug') {
369
- this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
370
- + ` Error Message: ${JSON.stringify(e.message)}`);
371
- }
372
- if (this.platform.debugMode) {
373
- this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
374
- + ` Error: ${JSON.stringify(e)}`);
375
- }
376
- }
377
- return switchbot;
378
- }
379
-
380
337
  private async BLERefreshStatus() {
381
338
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE refreshStatus`);
382
- // eslint-disable-next-line @typescript-eslint/no-var-requires
383
- const switchbot = await this.connectBLE();
339
+ const switchbot = await this.platform.connectBLE();
340
+ // Convert to BLE Address
341
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
342
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
384
343
  // Start to monitor advertisement packets
385
344
  if (switchbot !== false) {
386
345
  switchbot.startScan({
@@ -433,6 +392,7 @@ export class Contact {
433
392
  }
434
393
  if (this.platform.config.credentials?.openToken) {
435
394
  this.warnLog(`Contact Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
395
+ this.SwitchToOpenAPI = true;
436
396
  await this.openAPIRefreshStatus();
437
397
  }
438
398
  this.apiError(e);
@@ -446,6 +406,7 @@ export class Contact {
446
406
  this.errorLog(`Contact Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
447
407
  if (this.platform.config.credentials?.openToken) {
448
408
  this.warnLog(`Contact Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
409
+ this.SwitchToOpenAPI = true;
449
410
  await this.openAPIRefreshStatus();
450
411
  }
451
412
  }
@@ -456,6 +417,9 @@ export class Contact {
456
417
  try {
457
418
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
458
419
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
420
+ this.openState = this.deviceStatus.body.openState;
421
+ this.moveDetected = this.deviceStatus.body.moveDetected;
422
+ this.brightness = this.deviceStatus.body.brightness;
459
423
  this.parseStatus();
460
424
  this.updateHomeKitCharacteristics();
461
425
  } catch (e: any) {