@switchbot/homebridge-switchbot 2.9.0-beta.2 → 2.9.0-beta.21

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 (135) hide show
  1. package/config.schema.json +18 -4
  2. package/dist/device/blindtilt.d.ts +1 -1
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +39 -18
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +1 -1
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +73 -20
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +1 -1
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +35 -18
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +1 -1
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +35 -18
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +1 -1
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +42 -18
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +1 -1
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +39 -18
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/hub.d.ts +8 -9
  27. package/dist/device/hub.d.ts.map +1 -1
  28. package/dist/device/hub.js +160 -56
  29. package/dist/device/hub.js.map +1 -1
  30. package/dist/device/humidifier.d.ts +1 -1
  31. package/dist/device/humidifier.d.ts.map +1 -1
  32. package/dist/device/humidifier.js +38 -18
  33. package/dist/device/humidifier.js.map +1 -1
  34. package/dist/device/iosensor.d.ts +1 -1
  35. package/dist/device/iosensor.d.ts.map +1 -1
  36. package/dist/device/iosensor.js +42 -19
  37. package/dist/device/iosensor.js.map +1 -1
  38. package/dist/device/lightstrip.d.ts +1 -1
  39. package/dist/device/lightstrip.d.ts.map +1 -1
  40. package/dist/device/lightstrip.js +35 -18
  41. package/dist/device/lightstrip.js.map +1 -1
  42. package/dist/device/lock.d.ts +1 -1
  43. package/dist/device/lock.d.ts.map +1 -1
  44. package/dist/device/lock.js +39 -18
  45. package/dist/device/lock.js.map +1 -1
  46. package/dist/device/meter.d.ts +1 -9
  47. package/dist/device/meter.d.ts.map +1 -1
  48. package/dist/device/meter.js +48 -33
  49. package/dist/device/meter.js.map +1 -1
  50. package/dist/device/meterplus.d.ts +4 -7
  51. package/dist/device/meterplus.d.ts.map +1 -1
  52. package/dist/device/meterplus.js +70 -51
  53. package/dist/device/meterplus.js.map +1 -1
  54. package/dist/device/motion.d.ts +1 -1
  55. package/dist/device/motion.d.ts.map +1 -1
  56. package/dist/device/motion.js +39 -18
  57. package/dist/device/motion.js.map +1 -1
  58. package/dist/device/plug.d.ts +1 -1
  59. package/dist/device/plug.d.ts.map +1 -1
  60. package/dist/device/plug.js +36 -18
  61. package/dist/device/plug.js.map +1 -1
  62. package/dist/device/robotvacuumcleaner.d.ts +1 -1
  63. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  64. package/dist/device/robotvacuumcleaner.js +38 -17
  65. package/dist/device/robotvacuumcleaner.js.map +1 -1
  66. package/dist/irdevice/airconditioner.d.ts +1 -1
  67. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  68. package/dist/irdevice/airconditioner.js +29 -15
  69. package/dist/irdevice/airconditioner.js.map +1 -1
  70. package/dist/irdevice/airpurifier.d.ts +1 -1
  71. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  72. package/dist/irdevice/airpurifier.js +29 -15
  73. package/dist/irdevice/airpurifier.js.map +1 -1
  74. package/dist/irdevice/camera.d.ts +1 -1
  75. package/dist/irdevice/camera.d.ts.map +1 -1
  76. package/dist/irdevice/camera.js +29 -15
  77. package/dist/irdevice/camera.js.map +1 -1
  78. package/dist/irdevice/fan.d.ts +1 -1
  79. package/dist/irdevice/fan.d.ts.map +1 -1
  80. package/dist/irdevice/fan.js +29 -15
  81. package/dist/irdevice/fan.js.map +1 -1
  82. package/dist/irdevice/light.d.ts +1 -1
  83. package/dist/irdevice/light.d.ts.map +1 -1
  84. package/dist/irdevice/light.js +29 -15
  85. package/dist/irdevice/light.js.map +1 -1
  86. package/dist/irdevice/other.d.ts +1 -1
  87. package/dist/irdevice/other.d.ts.map +1 -1
  88. package/dist/irdevice/other.js +50 -23
  89. package/dist/irdevice/other.js.map +1 -1
  90. package/dist/irdevice/tv.d.ts +1 -1
  91. package/dist/irdevice/tv.d.ts.map +1 -1
  92. package/dist/irdevice/tv.js +29 -15
  93. package/dist/irdevice/tv.js.map +1 -1
  94. package/dist/irdevice/vacuumcleaner.d.ts +1 -1
  95. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  96. package/dist/irdevice/vacuumcleaner.js +29 -15
  97. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  98. package/dist/irdevice/waterheater.d.ts +1 -1
  99. package/dist/irdevice/waterheater.d.ts.map +1 -1
  100. package/dist/irdevice/waterheater.js +29 -15
  101. package/dist/irdevice/waterheater.js.map +1 -1
  102. package/dist/platform.d.ts.map +1 -1
  103. package/dist/platform.js +4 -0
  104. package/dist/platform.js.map +1 -1
  105. package/dist/settings.d.ts +1 -0
  106. package/dist/settings.d.ts.map +1 -1
  107. package/dist/settings.js.map +1 -1
  108. package/package.json +10 -10
  109. package/src/device/blindtilt.ts +39 -19
  110. package/src/device/bot.ts +63 -21
  111. package/src/device/ceilinglight.ts +35 -20
  112. package/src/device/colorbulb.ts +35 -19
  113. package/src/device/contact.ts +42 -20
  114. package/src/device/curtain.ts +39 -19
  115. package/src/device/hub.ts +176 -66
  116. package/src/device/humidifier.ts +38 -20
  117. package/src/device/iosensor.ts +42 -21
  118. package/src/device/lightstrip.ts +35 -19
  119. package/src/device/lock.ts +40 -21
  120. package/src/device/meter.ts +49 -41
  121. package/src/device/meterplus.ts +75 -61
  122. package/src/device/motion.ts +39 -21
  123. package/src/device/plug.ts +36 -20
  124. package/src/device/robotvacuumcleaner.ts +38 -19
  125. package/src/irdevice/airconditioner.ts +29 -16
  126. package/src/irdevice/airpurifier.ts +31 -16
  127. package/src/irdevice/camera.ts +31 -16
  128. package/src/irdevice/fan.ts +31 -16
  129. package/src/irdevice/light.ts +31 -16
  130. package/src/irdevice/other.ts +50 -24
  131. package/src/irdevice/tv.ts +31 -16
  132. package/src/irdevice/vacuumcleaner.ts +31 -16
  133. package/src/irdevice/waterheater.ts +31 -16
  134. package/src/platform.ts +4 -0
  135. package/src/settings.ts +1 -0
@@ -83,10 +83,20 @@ export class Contact {
83
83
  .getService(this.platform.Service.AccessoryInformation)!
84
84
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
85
85
  .setCharacteristic(this.platform.Characteristic.Model, 'W1201500')
86
- .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
87
- .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.setFirmwareRevision(accessory, device))
88
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
89
- .updateValue(this.setFirmwareRevision(accessory, device));
86
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
87
+
88
+ if (accessory.context.FirmwareRevision) {
89
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName}`
90
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
91
+ accessory
92
+ .getService(this.platform.Service.AccessoryInformation)!
93
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
94
+ .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
95
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
96
+ .updateValue(accessory.context.FirmwareRevision);
97
+ } else {
98
+ this.setFirmwareRevision(accessory, device);
99
+ }
90
100
 
91
101
  // get the Contact service if it exists, otherwise create a new Contact service
92
102
  // you can create multiple services for each accessory
@@ -282,7 +292,7 @@ export class Contact {
282
292
  );
283
293
 
284
294
  // FirmwareRevision
285
- this.FirmwareRevision = JSON.stringify(this.OpenAPI_FirmwareRevision);
295
+ this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
286
296
  }
287
297
 
288
298
  /**
@@ -460,8 +470,14 @@ export class Contact {
460
470
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} FirmwareRevision: ${this.FirmwareRevision}`);
461
471
  } else {
462
472
  this.accessory.context.FirmwareRevision = this.FirmwareRevision;
463
- this.accessory.getService(this.platform.Service.AccessoryInformation)!
464
- .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
473
+ this.batteryService.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
474
+ this.contactSensorservice.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
475
+ if (!this.device.contact?.hide_motionsensor) {
476
+ this.motionService!.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
477
+ }
478
+ if (!this.device.contact?.hide_lightsensor) {
479
+ this.lightSensorService!.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
480
+ }
465
481
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
466
482
  + `updateCharacteristic FirmwareRevision: ${this.FirmwareRevision}`);
467
483
  }
@@ -596,24 +612,30 @@ export class Contact {
596
612
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
597
613
  }
598
614
 
599
- setFirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
600
-
601
- this.debugLog(
602
- `${this.device.deviceType}: ${this.accessory.displayName}` + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`,
603
- );
604
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
605
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
615
+ async setFirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig) {
616
+ await this.refreshStatus();
606
617
  if (device.firmware) {
607
- this.FirmwareRevision = device.firmware;
618
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
619
+ accessory.context.FirmwareRevision = device.firmware;
620
+ this.FirmwareRevision = accessory.context.FirmwareRevision;
621
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware, FirmwareRevision: ${this.FirmwareRevision}`);
608
622
  } else if (device.version) {
609
- this.FirmwareRevision = JSON.stringify(device.version);
610
- } else if (accessory.context.FirmwareRevision) {
623
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} device.version: ${device.version}`);
624
+ accessory.context.FirmwareRevision = device.version;
611
625
  this.FirmwareRevision = accessory.context.FirmwareRevision;
626
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} device.version, FirmwareRevision: ${this.FirmwareRevision}`);
612
627
  } else {
613
- this.FirmwareRevision = this.platform.version;
628
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
629
+ accessory.context.FirmwareRevision = this.platform.version;
630
+ this.FirmwareRevision = accessory.context.FirmwareRevision;
631
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version, FirmwareRevision: ${this.FirmwareRevision}`);
614
632
  }
615
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} setFirmwareRevision: ${this.FirmwareRevision}`);
616
- return this.FirmwareRevision;
633
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} setFirmwareRevision: ${this.FirmwareRevision}`);
634
+ accessory
635
+ .getService(this.platform.Service.AccessoryInformation)!
636
+ .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
637
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
638
+ .updateValue(this.FirmwareRevision);
617
639
  }
618
640
 
619
641
  async context() {
@@ -102,10 +102,20 @@ export class Curtain {
102
102
  .getService(this.platform.Service.AccessoryInformation)!
103
103
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
104
104
  .setCharacteristic(this.platform.Characteristic.Model, 'W0701600')
105
- .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId)
106
- .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.setFirmwareRevision(accessory, device))
107
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
108
- .updateValue(this.setFirmwareRevision(accessory, device));
105
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
106
+
107
+ if (accessory.context.FirmwareRevision) {
108
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName}`
109
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
110
+ accessory
111
+ .getService(this.platform.Service.AccessoryInformation)!
112
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
113
+ .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
114
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
115
+ .updateValue(accessory.context.FirmwareRevision);
116
+ } else {
117
+ this.setFirmwareRevision(accessory, device);
118
+ }
109
119
 
110
120
  // get the WindowCovering service if it exists, otherwise create a new WindowCovering service
111
121
  // you can create multiple services for each accessory
@@ -471,7 +481,7 @@ export class Curtain {
471
481
  + ` StatusLowBattery: ${this.StatusLowBattery}`);
472
482
 
473
483
  // FirmwareRevision
474
- this.FirmwareRevision = JSON.stringify(this.OpenAPI_FirmwareRevision);
484
+ this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
475
485
  }
476
486
 
477
487
  async refreshStatus(): Promise<void> {
@@ -873,8 +883,11 @@ export class Curtain {
873
883
  this.mqttPublish('FirmwareRevision', this.FirmwareRevision);
874
884
  }
875
885
  this.accessory.context.FirmwareRevision = this.FirmwareRevision;
876
- this.accessory.getService(this.platform.Service.AccessoryInformation)!
877
- .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
886
+ this.batteryService.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
887
+ this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
888
+ if (this.device.curtain?.hide_lightsensor) {
889
+ this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
890
+ }
878
891
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
879
892
  + `updateCharacteristic FirmwareRevision: ${this.FirmwareRevision}`);
880
893
  }
@@ -1109,23 +1122,30 @@ export class Curtain {
1109
1122
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
1110
1123
  }
1111
1124
 
1112
- setFirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
1113
- this.debugLog(
1114
- `${this.device.deviceType}: ${this.accessory.displayName}` + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`,
1115
- );
1116
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
1117
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
1125
+ async setFirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig) {
1126
+ await this.refreshStatus();
1118
1127
  if (device.firmware) {
1119
- this.FirmwareRevision = device.firmware;
1128
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
1129
+ accessory.context.FirmwareRevision = device.firmware;
1130
+ this.FirmwareRevision = accessory.context.FirmwareRevision;
1131
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware, FirmwareRevision: ${this.FirmwareRevision}`);
1120
1132
  } else if (device.version) {
1121
- this.FirmwareRevision = JSON.stringify(device.version);
1122
- } if (accessory.context.FirmwareRevision) {
1133
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} device.version: ${device.version}`);
1134
+ accessory.context.FirmwareRevision = device.version;
1123
1135
  this.FirmwareRevision = accessory.context.FirmwareRevision;
1136
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} device.version, FirmwareRevision: ${this.FirmwareRevision}`);
1124
1137
  } else {
1125
- this.FirmwareRevision = this.platform.version;
1138
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
1139
+ accessory.context.FirmwareRevision = this.platform.version;
1140
+ this.FirmwareRevision = accessory.context.FirmwareRevision;
1141
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version, FirmwareRevision: ${this.FirmwareRevision}`);
1126
1142
  }
1127
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} setFirmwareRevision: ${this.FirmwareRevision}`);
1128
- return this.FirmwareRevision;
1143
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} setFirmwareRevision: ${this.FirmwareRevision}`);
1144
+ accessory
1145
+ .getService(this.platform.Service.AccessoryInformation)!
1146
+ .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
1147
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
1148
+ .updateValue(this.FirmwareRevision);
1129
1149
  }
1130
1150
 
1131
1151
  async context() {
package/src/device/hub.ts CHANGED
@@ -1,10 +1,12 @@
1
+ import { connectAsync } from 'async-mqtt';
1
2
  import { CharacteristicValue, PlatformAccessory, Service, Units } from 'homebridge';
3
+ import { MqttClient } from 'mqtt';
4
+ import { hostname } from 'os';
2
5
  import { interval } from 'rxjs';
3
6
  import { request } from 'undici';
4
7
  import { Context } from 'vm';
5
8
  import { SwitchBotPlatform } from '../platform';
6
9
  import { Devices, device, deviceStatus, devicesConfig } from '../settings';
7
- import { sleep } from '../utils';
8
10
 
9
11
  export class Hub {
10
12
  // Services
@@ -27,6 +29,12 @@ export class Hub {
27
29
  // OpenAPI Others
28
30
  spaceBetweenLevels!: number;
29
31
 
32
+ //MQTT stuff
33
+ mqttClient: MqttClient | null = null;
34
+
35
+ // EVE history service handler
36
+ historyService?: any;
37
+
30
38
  // Config
31
39
  set_minStep!: number;
32
40
  updateRate!: number;
@@ -48,6 +56,9 @@ export class Hub {
48
56
  // default placeholders
49
57
  this.logs(device);
50
58
  this.refreshRate(device);
59
+ this.context(accessory, device);
60
+ this.setupHistoryService(device);
61
+ this.setupMqtt(device);
51
62
  this.config(device);
52
63
 
53
64
  this.CurrentRelativeHumidity = accessory.context.CurrentRelativeHumidity;
@@ -61,10 +72,20 @@ export class Hub {
61
72
  .getService(this.platform.Service.AccessoryInformation)!
62
73
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
63
74
  .setCharacteristic(this.platform.Characteristic.Model, accessory.context.model)
64
- .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId)
65
- .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.setFirmwareRevision(accessory, device))
66
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
67
- .updateValue(this.setFirmwareRevision(accessory, device));
75
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
76
+
77
+ if (accessory.context.FirmwareRevision) {
78
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName}`
79
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
80
+ accessory
81
+ .getService(this.platform.Service.AccessoryInformation)!
82
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
83
+ .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
84
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
85
+ .updateValue(accessory.context.FirmwareRevision);
86
+ } else {
87
+ this.setFirmwareRevision(accessory, device);
88
+ }
68
89
 
69
90
  // Temperature Sensor Service
70
91
  if (device.hub?.hide_temperature) {
@@ -124,7 +145,7 @@ export class Hub {
124
145
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Humidity Sensor Service Not Added`);
125
146
  }
126
147
 
127
- // Humidity Sensor Service
148
+ // Light Sensor Service
128
149
  if (device.hub?.hide_lightsensor) {
129
150
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
130
151
  this.lightSensorService = this.accessory.getService(this.platform.Service.LightSensor);
@@ -141,13 +162,14 @@ export class Hub {
141
162
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
142
163
  }
143
164
 
144
- // Update Homekit
165
+ // Retrieve initial values and update Homekit
145
166
  this.updateHomeKitCharacteristics();
146
167
 
147
168
  // Start an update interval
148
- interval(this.deviceRefreshRate * 1000).subscribe(async () => {
149
- await this.refreshStatus();
150
- });
169
+ interval(this.deviceRefreshRate * 1000)
170
+ .subscribe(async () => {
171
+ await this.refreshStatus();
172
+ });
151
173
  }
152
174
 
153
175
  /**
@@ -166,14 +188,16 @@ export class Hub {
166
188
 
167
189
  async openAPIparseStatus(): Promise<void> {
168
190
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
169
- // Temperature
170
- if (!this.device.hub?.hide_temperature) {
171
- this.CurrentTemperature = Number(this.OpenAPI_CurrentTemperature);
172
- }
173
-
174
- // Humidity
191
+ // CurrentRelativeHumidity
175
192
  if (!this.device.hub?.hide_humidity) {
176
193
  this.CurrentRelativeHumidity = Number(this.OpenAPI_CurrentRelativeHumidity);
194
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
195
+ }
196
+
197
+ // CurrentTemperature
198
+ if (!this.device.hub?.hide_temperature) {
199
+ this.CurrentTemperature = Number(this.OpenAPI_CurrentTemperature);
200
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
177
201
  }
178
202
 
179
203
  // Brightness
@@ -191,7 +215,7 @@ export class Hub {
191
215
  this.CurrentAmbientLightLevel = (this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels;
192
216
  this.debugLog(
193
217
  `${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel},` +
194
- ` Calculation: ${(this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels}`,
218
+ ` Calculation: ${(this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels}`,
195
219
  );
196
220
  break;
197
221
  case 3:
@@ -269,7 +293,7 @@ export class Hub {
269
293
  }
270
294
  this.debugLog(
271
295
  `${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel},` +
272
- ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
296
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
273
297
  );
274
298
  }
275
299
  if (!this.device.hub?.hide_lightsensor) {
@@ -278,7 +302,7 @@ export class Hub {
278
302
  }
279
303
 
280
304
  // FirmwareRevision
281
- this.FirmwareRevision = JSON.stringify(this.OpenAPI_FirmwareRevision);
305
+ this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
282
306
  }
283
307
 
284
308
  async refreshStatus(): Promise<void> {
@@ -325,49 +349,46 @@ export class Hub {
325
349
  }
326
350
  }
327
351
 
328
- async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
329
- return fn().catch(async (e: any) => {
330
- if (max === 0) {
331
- throw e;
332
- }
333
- this.infoLog(e);
334
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Retrying`);
335
- await sleep(1000);
336
- return this.retry({ max: max - 1, fn });
337
- });
338
- }
339
-
340
- maxRetry(): number {
341
- if (this.device.maxRetry) {
342
- return this.device.maxRetry;
343
- } else {
344
- return 5;
345
- }
346
- }
347
-
348
352
  /**
349
353
  * Handle requests to set the value of the "Target Position" characteristic
350
354
  */
351
355
 
352
356
  async updateHomeKitCharacteristics(): Promise<void> {
353
- if (!this.device.hub?.hide_temperature) {
354
- if (this.CurrentTemperature === undefined) {
355
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
356
- } else {
357
- this.accessory.context.CurrentTemperature = this.CurrentTemperature;
358
- this.temperatureService?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
359
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
360
- }
361
- }
357
+ const mqttmessage: string[] = [];
358
+ const entry = { time: Math.round(new Date().valueOf() / 1000) };
359
+
360
+ // CurrentRelativeHumidity
362
361
  if (!this.device.hub?.hide_humidity) {
363
362
  if (this.CurrentRelativeHumidity === undefined) {
364
363
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
365
364
  } else {
365
+ if (this.device.mqttURL) {
366
+ mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
367
+ }
368
+ if (this.device.history) {
369
+ entry['humidity'] = this.CurrentRelativeHumidity;
370
+ }
366
371
  this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
367
372
  this.humidityService?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
368
373
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
369
- + `updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`,
370
- );
374
+ + `updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
375
+ }
376
+ }
377
+
378
+ // CurrentTemperature
379
+ if (!this.device.hub?.hide_temperature) {
380
+ if (this.CurrentTemperature === undefined) {
381
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
382
+ } else {
383
+ if (this.device.mqttURL) {
384
+ mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
385
+ }
386
+ if (this.device.history) {
387
+ entry['temp'] = this.CurrentTemperature;
388
+ }
389
+ this.accessory.context.CurrentTemperature = this.CurrentTemperature;
390
+ this.temperatureService?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
391
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
371
392
  }
372
393
  }
373
394
  if (!this.device.hub?.hide_lightsensor) {
@@ -378,7 +399,7 @@ export class Hub {
378
399
  this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
379
400
  this.debugLog(
380
401
  `${this.device.deviceType}: ${this.accessory.displayName} `
381
- + `updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
402
+ + `updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
382
403
  );
383
404
  }
384
405
  }
@@ -388,11 +409,79 @@ export class Hub {
388
409
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} FirmwareRevision: ${this.FirmwareRevision}`);
389
410
  } else {
390
411
  this.accessory.context.FirmwareRevision = this.FirmwareRevision;
391
- this.accessory.getService(this.platform.Service.AccessoryInformation)!
392
- .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
412
+
413
+ if (!this.device.hub?.hide_humidity) {
414
+ this.humidityService!.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
415
+ }
416
+ if (!this.device.hub?.hide_temperature) {
417
+ this.temperatureService!.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
418
+ }
419
+ if (!this.device.hub?.hide_lightsensor) {
420
+ this.lightSensorService!.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
421
+ }
393
422
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
394
423
  + `updateCharacteristic FirmwareRevision: ${this.FirmwareRevision}`);
395
424
  }
425
+
426
+ // MQTT
427
+ if (this.device.mqttURL) {
428
+ this.mqttPublish(`{${mqttmessage.join(',')}}`);
429
+ }
430
+ if (Number(this.CurrentRelativeHumidity) > 0) {
431
+ // reject unreliable data
432
+ if (this.device.history) {
433
+ this.historyService?.addEntry(entry);
434
+ }
435
+ }
436
+ }
437
+
438
+ /*
439
+ * Publish MQTT message for topics of
440
+ * 'homebridge-switchbot/meter/xx:xx:xx:xx:xx:xx'
441
+ */
442
+ mqttPublish(message: any) {
443
+ const mac = this.device.deviceId
444
+ ?.toLowerCase()
445
+ .match(/[\s\S]{1,2}/g)
446
+ ?.join(':');
447
+ const options = this.device.mqttPubOptions || {};
448
+ this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
449
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
450
+ }
451
+
452
+ /*
453
+ * Setup MQTT hadler if URL is specifed.
454
+ */
455
+ async setupMqtt(device: device & devicesConfig): Promise<void> {
456
+ if (device.mqttURL) {
457
+ try {
458
+ this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
459
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
460
+ this.mqttClient.on('error', (e: Error) => {
461
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
462
+ });
463
+ } catch (e) {
464
+ this.mqttClient = null;
465
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
466
+ }
467
+ }
468
+ }
469
+
470
+ /*
471
+ * Setup EVE history graph feature if enabled.
472
+ */
473
+ async setupHistoryService(device: device & devicesConfig): Promise<void> {
474
+ const mac = this.device
475
+ .deviceId!.match(/.{1,2}/g)!
476
+ .join(':')
477
+ .toLowerCase();
478
+ this.historyService = device.history
479
+ ? new this.platform.fakegatoAPI('room', this.accessory, {
480
+ log: this.platform.log,
481
+ storage: 'fs',
482
+ filename: `${hostname().split('.')[0]}_${mac}_persist.json`,
483
+ })
484
+ : null;
396
485
  }
397
486
 
398
487
  async statusCode(statusCode: number): Promise<void> {
@@ -439,6 +528,7 @@ export class Hub {
439
528
 
440
529
  async offlineOff(): Promise<void> {
441
530
  if (this.device.offline) {
531
+ await this.context(this.accessory, this.device);
442
532
  await this.updateHomeKitCharacteristics();
443
533
  }
444
534
  }
@@ -473,24 +563,44 @@ export class Hub {
473
563
  return this.set_maxLux;
474
564
  }
475
565
 
476
- setFirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
477
-
478
- this.debugLog(
479
- `${this.device.deviceType}: ${this.accessory.displayName}` + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`,
480
- );
481
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
482
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
566
+ async setFirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig) {
567
+ await this.refreshStatus();
483
568
  if (device.firmware) {
484
- this.FirmwareRevision = device.firmware;
485
- } else if (device.version) {
486
- this.FirmwareRevision = JSON.stringify(device.version);
487
- } else if (accessory.context.FirmwareRevision) {
569
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
570
+ accessory.context.FirmwareRevision = device.firmware;
488
571
  this.FirmwareRevision = accessory.context.FirmwareRevision;
572
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware, FirmwareRevision: ${this.FirmwareRevision}`);
573
+ } else {
574
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} device.version: ${device.version}`);
575
+ accessory.context.FirmwareRevision = device.version;
576
+ this.FirmwareRevision = accessory.context.FirmwareRevision;
577
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} device.version, FirmwareRevision: ${this.FirmwareRevision}`);
578
+ }
579
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} setFirmwareRevision: ${this.FirmwareRevision}`);
580
+ accessory
581
+ .getService(this.platform.Service.AccessoryInformation)!
582
+ .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
583
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
584
+ .updateValue(this.FirmwareRevision);
585
+ }
586
+
587
+ async context(accessory, device) {
588
+ if (this.CurrentRelativeHumidity === undefined) {
589
+ this.CurrentRelativeHumidity = 0;
489
590
  } else {
591
+ this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity;
592
+ }
593
+ if (this.CurrentTemperature === undefined) {
594
+ this.CurrentTemperature = 0;
595
+ } else {
596
+ this.CurrentTemperature = this.accessory.context.CurrentTemperature;
597
+ }
598
+ if (this.FirmwareRevision === undefined) {
490
599
  this.FirmwareRevision = this.platform.version;
600
+ } else {
601
+ this.setFirmwareRevision(accessory, device);
602
+ this.FirmwareRevision = this.accessory.context.FirmwareRevision;
491
603
  }
492
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} setFirmwareRevision: ${this.FirmwareRevision}`);
493
- return this.FirmwareRevision;
494
604
  }
495
605
 
496
606
  async refreshRate(device: device & devicesConfig): Promise<void> {
@@ -81,10 +81,20 @@ export class Humidifier {
81
81
  .getService(this.platform.Service.AccessoryInformation)!
82
82
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
83
83
  .setCharacteristic(this.platform.Characteristic.Model, 'W0801800')
84
- .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
85
- .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.setFirmwareRevision(accessory, device))
86
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
87
- .updateValue(this.setFirmwareRevision(accessory, device));
84
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
85
+
86
+ if (accessory.context.FirmwareRevision) {
87
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName}`
88
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
89
+ accessory
90
+ .getService(this.platform.Service.AccessoryInformation)!
91
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
92
+ .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
93
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
94
+ .updateValue(accessory.context.FirmwareRevision);
95
+ } else {
96
+ this.setFirmwareRevision(accessory, device);
97
+ }
88
98
 
89
99
  // get the service if it exists, otherwise create a new service
90
100
  // you can create multiple services for each accessory
@@ -283,7 +293,7 @@ export class Humidifier {
283
293
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} WaterLevel: ${this.WaterLevel}`);
284
294
 
285
295
  // FirmwareRevision
286
- this.FirmwareRevision = JSON.stringify(this.OpenAPI_FirmwareRevision);
296
+ this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
287
297
  }
288
298
 
289
299
  /**
@@ -743,8 +753,10 @@ export class Humidifier {
743
753
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} FirmwareRevision: ${this.FirmwareRevision}`);
744
754
  } else {
745
755
  this.accessory.context.FirmwareRevision = this.FirmwareRevision;
746
- this.accessory.getService(this.platform.Service.AccessoryInformation)!
747
- .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
756
+ this.humidifierService.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
757
+ if (!this.device.humidifier?.hide_temperature) {
758
+ this.temperatureservice!.updateCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision);
759
+ }
748
760
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
749
761
  + `updateCharacteristic FirmwareRevision: ${this.FirmwareRevision}`);
750
762
  }
@@ -883,24 +895,30 @@ export class Humidifier {
883
895
  }
884
896
  }
885
897
 
886
- setFirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
887
-
888
- this.debugLog(
889
- `${this.device.deviceType}: ${this.accessory.displayName}` + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`,
890
- );
891
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
892
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
898
+ async setFirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig) {
899
+ await this.refreshStatus();
893
900
  if (device.firmware) {
894
- this.FirmwareRevision = device.firmware;
901
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
902
+ accessory.context.FirmwareRevision = device.firmware;
903
+ this.FirmwareRevision = accessory.context.FirmwareRevision;
904
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware, FirmwareRevision: ${this.FirmwareRevision}`);
895
905
  } else if (device.version) {
896
- this.FirmwareRevision = JSON.stringify(device.version);
897
- } else if (accessory.context.FirmwareRevision) {
906
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} device.version: ${device.version}`);
907
+ accessory.context.FirmwareRevision = device.version;
898
908
  this.FirmwareRevision = accessory.context.FirmwareRevision;
909
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} device.version, FirmwareRevision: ${this.FirmwareRevision}`);
899
910
  } else {
900
- this.FirmwareRevision = this.platform.version;
911
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
912
+ accessory.context.FirmwareRevision = this.platform.version;
913
+ this.FirmwareRevision = accessory.context.FirmwareRevision;
914
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version, FirmwareRevision: ${this.FirmwareRevision}`);
901
915
  }
902
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} setFirmwareRevision: ${this.FirmwareRevision}`);
903
- return this.FirmwareRevision;
916
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} setFirmwareRevision: ${this.FirmwareRevision}`);
917
+ accessory
918
+ .getService(this.platform.Service.AccessoryInformation)!
919
+ .updateCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision)
920
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
921
+ .updateValue(this.FirmwareRevision);
904
922
  }
905
923
 
906
924
  async context() {