@switchbot/homebridge-switchbot 3.5.0-beta.6 → 3.5.0-beta.61

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 (177) hide show
  1. package/.vscode/settings.json +4 -1
  2. package/CHANGELOG.md +4 -1
  3. package/config.schema.json +120 -17
  4. package/dist/device/blindtilt.d.ts +23 -96
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +408 -779
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +26 -72
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +696 -822
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +14 -68
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +237 -606
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +14 -75
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +280 -658
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +15 -66
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +242 -544
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +19 -88
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +402 -805
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/device.d.ts +59 -0
  29. package/dist/device/device.d.ts.map +1 -0
  30. package/dist/device/device.js +684 -0
  31. package/dist/device/device.js.map +1 -0
  32. package/dist/device/fan.d.ts +51 -0
  33. package/dist/device/fan.d.ts.map +1 -0
  34. package/dist/device/fan.js +535 -0
  35. package/dist/device/fan.js.map +1 -0
  36. package/dist/device/hub.d.ts +16 -60
  37. package/dist/device/hub.d.ts.map +1 -1
  38. package/dist/device/hub.js +246 -613
  39. package/dist/device/hub.js.map +1 -1
  40. package/dist/device/humidifier.d.ts +11 -66
  41. package/dist/device/humidifier.d.ts.map +1 -1
  42. package/dist/device/humidifier.js +232 -593
  43. package/dist/device/humidifier.js.map +1 -1
  44. package/dist/device/iosensor.d.ts +11 -64
  45. package/dist/device/iosensor.d.ts.map +1 -1
  46. package/dist/device/iosensor.js +185 -600
  47. package/dist/device/iosensor.js.map +1 -1
  48. package/dist/device/lightstrip.d.ts +11 -69
  49. package/dist/device/lightstrip.d.ts.map +1 -1
  50. package/dist/device/lightstrip.js +277 -586
  51. package/dist/device/lightstrip.js.map +1 -1
  52. package/dist/device/lock.d.ts +16 -63
  53. package/dist/device/lock.d.ts.map +1 -1
  54. package/dist/device/lock.js +241 -560
  55. package/dist/device/lock.js.map +1 -1
  56. package/dist/device/meter.d.ts +14 -64
  57. package/dist/device/meter.d.ts.map +1 -1
  58. package/dist/device/meter.js +181 -593
  59. package/dist/device/meter.js.map +1 -1
  60. package/dist/device/meterplus.d.ts +14 -65
  61. package/dist/device/meterplus.d.ts.map +1 -1
  62. package/dist/device/meterplus.js +170 -593
  63. package/dist/device/meterplus.js.map +1 -1
  64. package/dist/device/motion.d.ts +13 -69
  65. package/dist/device/motion.d.ts.map +1 -1
  66. package/dist/device/motion.js +178 -531
  67. package/dist/device/motion.js.map +1 -1
  68. package/dist/device/plug.d.ts +9 -57
  69. package/dist/device/plug.d.ts.map +1 -1
  70. package/dist/device/plug.js +92 -458
  71. package/dist/device/plug.js.map +1 -1
  72. package/dist/device/robotvacuumcleaner.d.ts +12 -63
  73. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  74. package/dist/device/robotvacuumcleaner.js +197 -521
  75. package/dist/device/robotvacuumcleaner.js.map +1 -1
  76. package/dist/device/waterdetector.d.ts +10 -65
  77. package/dist/device/waterdetector.d.ts.map +1 -1
  78. package/dist/device/waterdetector.js +139 -495
  79. package/dist/device/waterdetector.js.map +1 -1
  80. package/dist/homebridge-ui/public/index.html +22 -16
  81. package/dist/homebridge-ui/server.js +1 -1
  82. package/dist/homebridge-ui/server.js.map +1 -1
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +2 -2
  86. package/dist/index.js.map +1 -1
  87. package/dist/irdevice/airconditioner.d.ts +9 -49
  88. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  89. package/dist/irdevice/airconditioner.js +309 -419
  90. package/dist/irdevice/airconditioner.js.map +1 -1
  91. package/dist/irdevice/airpurifier.d.ts +8 -39
  92. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  93. package/dist/irdevice/airpurifier.js +72 -304
  94. package/dist/irdevice/airpurifier.js.map +1 -1
  95. package/dist/irdevice/camera.d.ts +7 -36
  96. package/dist/irdevice/camera.d.ts.map +1 -1
  97. package/dist/irdevice/camera.js +34 -278
  98. package/dist/irdevice/camera.js.map +1 -1
  99. package/dist/irdevice/fan.d.ts +10 -43
  100. package/dist/irdevice/fan.d.ts.map +1 -1
  101. package/dist/irdevice/fan.js +100 -338
  102. package/dist/irdevice/fan.js.map +1 -1
  103. package/dist/irdevice/irdevice.d.ts +40 -0
  104. package/dist/irdevice/irdevice.d.ts.map +1 -0
  105. package/dist/irdevice/irdevice.js +330 -0
  106. package/dist/irdevice/irdevice.js.map +1 -0
  107. package/dist/irdevice/light.d.ts +12 -45
  108. package/dist/irdevice/light.d.ts.map +1 -1
  109. package/dist/irdevice/light.js +87 -357
  110. package/dist/irdevice/light.js.map +1 -1
  111. package/dist/irdevice/other.d.ts +19 -48
  112. package/dist/irdevice/other.d.ts.map +1 -1
  113. package/dist/irdevice/other.js +352 -546
  114. package/dist/irdevice/other.js.map +1 -1
  115. package/dist/irdevice/tv.d.ts +8 -40
  116. package/dist/irdevice/tv.d.ts.map +1 -1
  117. package/dist/irdevice/tv.js +82 -321
  118. package/dist/irdevice/tv.js.map +1 -1
  119. package/dist/irdevice/vacuumcleaner.d.ts +7 -36
  120. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  121. package/dist/irdevice/vacuumcleaner.js +41 -284
  122. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  123. package/dist/irdevice/waterheater.d.ts +7 -36
  124. package/dist/irdevice/waterheater.d.ts.map +1 -1
  125. package/dist/irdevice/waterheater.js +42 -287
  126. package/dist/irdevice/waterheater.js.map +1 -1
  127. package/dist/platform.d.ts +19 -6
  128. package/dist/platform.d.ts.map +1 -1
  129. package/dist/platform.js +310 -169
  130. package/dist/platform.js.map +1 -1
  131. package/dist/settings.d.ts +62 -19
  132. package/dist/settings.d.ts.map +1 -1
  133. package/dist/settings.js +16 -552
  134. package/dist/settings.js.map +1 -1
  135. package/dist/utils.d.ts +77 -0
  136. package/dist/utils.d.ts.map +1 -1
  137. package/dist/utils.js +638 -1
  138. package/dist/utils.js.map +1 -1
  139. package/eslint.config.js +96 -0
  140. package/package.json +19 -15
  141. package/src/custom.d.ts +2 -1
  142. package/src/device/blindtilt.ts +442 -814
  143. package/src/device/bot.ts +754 -915
  144. package/src/device/ceilinglight.ts +255 -633
  145. package/src/device/colorbulb.ts +295 -685
  146. package/src/device/contact.ts +277 -571
  147. package/src/device/curtain.ts +431 -835
  148. package/src/device/device.ts +709 -0
  149. package/src/device/fan.ts +591 -0
  150. package/src/device/hub.ts +286 -644
  151. package/src/device/humidifier.ts +266 -646
  152. package/src/device/iosensor.ts +220 -625
  153. package/src/device/lightstrip.ts +305 -620
  154. package/src/device/lock.ts +280 -600
  155. package/src/device/meter.ts +216 -617
  156. package/src/device/meterplus.ts +205 -619
  157. package/src/device/motion.ts +206 -556
  158. package/src/device/plug.ts +107 -490
  159. package/src/device/robotvacuumcleaner.ts +223 -550
  160. package/src/device/waterdetector.ts +160 -519
  161. package/src/homebridge-ui/public/index.html +22 -16
  162. package/src/homebridge-ui/server.ts +1 -1
  163. package/src/index.ts +4 -3
  164. package/src/irdevice/airconditioner.ts +333 -447
  165. package/src/irdevice/airpurifier.ts +92 -322
  166. package/src/irdevice/camera.ts +45 -294
  167. package/src/irdevice/fan.ts +115 -353
  168. package/src/irdevice/irdevice.ts +346 -0
  169. package/src/irdevice/light.ts +110 -385
  170. package/src/irdevice/other.ts +399 -616
  171. package/src/irdevice/tv.ts +103 -340
  172. package/src/irdevice/vacuumcleaner.ts +52 -306
  173. package/src/irdevice/waterheater.ts +53 -311
  174. package/src/platform.ts +355 -216
  175. package/src/settings.ts +116 -611
  176. package/src/utils.ts +642 -1
  177. package/src/device/waterdetector.json +0 -11
@@ -1,92 +1,37 @@
1
- import asyncmqtt from 'async-mqtt';
2
- import { hostname } from 'os';
3
- import { interval } from 'rxjs';
4
- import { request } from 'undici';
1
+ import { deviceBase } from './device.js';
5
2
  import { Devices } from '../settings.js';
6
- export class Hub {
3
+ import { convertUnits } from '../utils.js';
4
+ import { Subject, interval, skipWhile } from 'rxjs';
5
+ export class Hub extends deviceBase {
7
6
  platform;
8
- accessory;
9
- device;
10
- api;
11
- log;
12
- config;
13
- hap;
14
7
  // Services
15
- lightSensorService;
16
- humidityService;
17
- temperatureService;
18
- // Characteristic Values
19
- FirmwareRevision;
20
- CurrentTemperature;
21
- CurrentRelativeHumidity;
22
- CurrentAmbientLightLevel;
23
- // OpenAPI Status
24
- OpenAPI_FirmwareRevision;
25
- OpenAPI_CurrentTemperature;
26
- OpenAPI_CurrentRelativeHumidity;
27
- OpenAPI_CurrentAmbientLightLevel;
28
- // OpenAPI Others
29
- spaceBetweenLevels;
30
- //MQTT stuff
31
- mqttClient = null;
32
- // EVE history service handler
33
- historyService;
34
- // Config
35
- set_minStep;
36
- updateRate;
37
- set_minLux;
38
- set_maxLux;
39
- scanDuration;
40
- deviceLogging;
41
- deviceRefreshRate;
42
- // Connection
43
- OpenAPI;
44
- BLE;
8
+ LightSensor;
9
+ HumiditySensor;
10
+ TemperatureSensor;
11
+ // Updates
12
+ hubUpdateInProgress;
13
+ doHubUpdate;
45
14
  constructor(platform, accessory, device) {
15
+ super(platform, accessory, device);
46
16
  this.platform = platform;
47
- this.accessory = accessory;
48
- this.device = device;
49
- this.api = this.platform.api;
50
- this.log = this.platform.log;
51
- this.config = this.platform.config;
52
- this.hap = this.api.hap;
53
- // Connection
54
- this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
55
- this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
56
- // default placeholders
57
- this.deviceLogs(device);
58
- this.refreshRate(device);
59
- this.deviceContext();
60
- this.setupHistoryService(device);
61
- this.setupMqtt(device);
62
- this.deviceConfig(device);
63
- this.CurrentRelativeHumidity = accessory.context.CurrentRelativeHumidity;
64
- this.CurrentTemperature = accessory.context.CurrentTemperature;
65
- // Retrieve initial values and updateHomekit
66
- this.refreshStatus();
67
- // set accessory information
68
- accessory
69
- .getService(this.hap.Service.AccessoryInformation)
70
- .setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
71
- .setCharacteristic(this.hap.Characteristic.Model, accessory.context.model)
72
- .setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId)
73
- .setCharacteristic(this.hap.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision);
74
- // Temperature Sensor Service
17
+ // this is subject we use to track when we need to POST changes to the SwitchBot API
18
+ this.doHubUpdate = new Subject();
19
+ this.hubUpdateInProgress = false;
20
+ // Initialize Temperature Sensor Service
75
21
  if (device.hub?.hide_temperature) {
76
22
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Temperature Sensor Service`);
77
- this.temperatureService = this.accessory.getService(this.hap.Service.TemperatureSensor);
78
- accessory.removeService(this.temperatureService);
23
+ this.TemperatureSensor.Service = this.accessory.getService(this.hap.Service.TemperatureSensor);
24
+ accessory.removeService(this.TemperatureSensor.Service);
79
25
  }
80
- else if (!this.temperatureService) {
81
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Temperature Sensor Service`);
82
- const temperatureService = `${accessory.displayName} Temperature Sensor`;
83
- (this.temperatureService = this.accessory.getService(this.hap.Service.TemperatureSensor)
84
- || this.accessory.addService(this.hap.Service.TemperatureSensor)), temperatureService;
85
- this.temperatureService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
86
- if (!this.temperatureService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
87
- this.temperatureService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Temperature Sensor`);
88
- }
89
- this.temperatureService
26
+ else {
27
+ this.TemperatureSensor = {
28
+ Name: accessory.context.TemperatureSensorName ?? `${accessory.displayName} Temperature Sensor`,
29
+ Service: accessory.getService(this.hap.Service.TemperatureSensor) ?? this.accessory.addService(this.hap.Service.TemperatureSensor),
30
+ CurrentTemperature: accessory.context.CurrentTemperature ?? 0,
31
+ };
32
+ // Initialize Temperature Sensor Characteristic
33
+ this.TemperatureSensor.Service
34
+ .setCharacteristic(this.hap.Characteristic.Name, this.TemperatureSensor.Name)
90
35
  .getCharacteristic(this.hap.Characteristic.CurrentTemperature)
91
36
  .setProps({
92
37
  unit: "celsius" /* Units['CELSIUS'] */,
@@ -96,166 +41,99 @@ export class Hub {
96
41
  minStep: 0.1,
97
42
  })
98
43
  .onGet(() => {
99
- return this.CurrentTemperature;
44
+ return this.TemperatureSensor.CurrentTemperature;
100
45
  });
46
+ accessory.context.TemperatureSensorName = this.TemperatureSensor.Name;
101
47
  }
102
- else {
103
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Temperature Sensor Service Not Added`);
104
- }
105
- // Humidity Sensor Service
48
+ // Initialize Humidity Sensor Service
106
49
  if (device.hub?.hide_humidity) {
107
50
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Humidity Sensor Service`);
108
- this.humidityService = this.accessory.getService(this.hap.Service.HumiditySensor);
109
- accessory.removeService(this.humidityService);
51
+ this.HumiditySensor.Service = this.accessory.getService(this.hap.Service.HumiditySensor);
52
+ accessory.removeService(this.HumiditySensor.Service);
110
53
  }
111
- else if (!this.humidityService) {
112
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Humidity Sensor Service`);
113
- const humidityService = `${accessory.displayName} Humidity Sensor`;
114
- (this.humidityService = this.accessory.getService(this.hap.Service.HumiditySensor)
115
- || this.accessory.addService(this.hap.Service.HumiditySensor)), humidityService;
116
- this.humidityService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
117
- if (!this.humidityService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
118
- this.humidityService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Humidity Sensor`);
119
- }
120
- this.humidityService
54
+ else {
55
+ this.HumiditySensor = {
56
+ Name: accessory.context.HumiditySensorName ?? `${accessory.displayName} Humidity Sensor`,
57
+ Service: accessory.getService(this.hap.Service.HumiditySensor) ?? this.accessory.addService(this.hap.Service.HumiditySensor),
58
+ CurrentRelativeHumidity: accessory.context.CurrentRelativeHumidity ?? 0,
59
+ };
60
+ // Initialize Humidity Sensor Characteristics
61
+ this.HumiditySensor.Service
62
+ .setCharacteristic(this.hap.Characteristic.Name, this.HumiditySensor.Name)
121
63
  .getCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity)
122
64
  .setProps({
123
65
  minStep: 0.1,
124
66
  })
125
67
  .onGet(() => {
126
- return this.CurrentRelativeHumidity;
68
+ return this.HumiditySensor.CurrentRelativeHumidity;
127
69
  });
70
+ accessory.context.HumiditySensorName = this.HumiditySensor.Name;
128
71
  }
129
- else {
130
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Humidity Sensor Service Not Added`);
131
- }
132
- // Light Sensor Service
72
+ // Initialize Light Sensor Service
133
73
  if (device.hub?.hide_lightsensor) {
134
74
  this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
135
- this.lightSensorService = this.accessory.getService(this.hap.Service.LightSensor);
136
- accessory.removeService(this.lightSensorService);
137
- }
138
- else if (!this.lightSensorService) {
139
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
140
- const lightSensorService = `${accessory.displayName} Light Sensor`;
141
- (this.lightSensorService = this.accessory.getService(this.hap.Service.LightSensor)
142
- || this.accessory.addService(this.hap.Service.LightSensor)), lightSensorService;
143
- this.lightSensorService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Light Sensor`);
144
- this.lightSensorService.setCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Light Sensor`);
75
+ this.LightSensor.Service = this.accessory.getService(this.hap.Service.LightSensor);
76
+ accessory.removeService(this.LightSensor.Service);
145
77
  }
146
78
  else {
147
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
79
+ this.LightSensor = {
80
+ Name: accessory.context.LightSensorName ?? `${accessory.displayName} Light Sensor`,
81
+ Service: accessory.getService(this.hap.Service.LightSensor) ?? this.accessory.addService(this.hap.Service.LightSensor),
82
+ CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel ?? 0.0001,
83
+ };
84
+ // Initialize Light Sensor Characteristics
85
+ this.LightSensor.Service
86
+ .setCharacteristic(this.hap.Characteristic.Name, this.LightSensor.Name)
87
+ .getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel)
88
+ .setProps({
89
+ minStep: 1,
90
+ })
91
+ .onGet(() => {
92
+ return this.LightSensor.CurrentAmbientLightLevel;
93
+ });
94
+ accessory.context.LightSensorName = this.LightSensor.Name;
148
95
  }
96
+ // Retrieve initial values and updateHomekit
97
+ this.refreshStatus();
149
98
  // Retrieve initial values and update Homekit
150
99
  this.updateHomeKitCharacteristics();
151
100
  // Start an update interval
152
101
  interval(this.deviceRefreshRate * 1000)
102
+ .pipe(skipWhile(() => this.hubUpdateInProgress))
153
103
  .subscribe(async () => {
154
104
  await this.refreshStatus();
155
105
  });
156
106
  //regisiter webhook event handler
157
- if (this.device.webhook) {
158
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
107
+ if (device.webhook) {
108
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
159
109
  this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
160
110
  try {
161
111
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
162
- if (context.scale === 'CELSIUS') {
163
- const { temperature, humidity, lightLevel } = context;
164
- const { CurrentTemperature, CurrentRelativeHumidity, CurrentAmbientLightLevel } = this;
165
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
166
- '(temperature, humidity, lightLevel) = ' +
167
- `Webhook:(${temperature}, ${humidity}, ${lightLevel}), ` +
168
- `current:(${CurrentTemperature}, ${CurrentRelativeHumidity}, ${CurrentAmbientLightLevel})`);
169
- this.CurrentRelativeHumidity = humidity;
170
- this.CurrentTemperature = temperature;
171
- this.set_minLux = this.minLux();
172
- this.set_maxLux = this.maxLux();
173
- this.spaceBetweenLevels = 19;
174
- switch (lightLevel) {
175
- case 1:
176
- this.CurrentAmbientLightLevel = this.set_minLux;
177
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
178
- break;
179
- case 2:
180
- this.CurrentAmbientLightLevel = (this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels;
181
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel},` +
182
- ` Calculation: ${(this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels}`);
183
- break;
184
- case 3:
185
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 2;
186
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
187
- break;
188
- case 4:
189
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 3;
190
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
191
- break;
192
- case 5:
193
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 4;
194
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
195
- break;
196
- case 6:
197
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 5;
198
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
199
- break;
200
- case 7:
201
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 6;
202
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
203
- break;
204
- case 8:
205
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 7;
206
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
207
- break;
208
- case 9:
209
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 8;
210
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
211
- break;
212
- case 10:
213
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 9;
214
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
215
- break;
216
- case 11:
217
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 10;
218
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
219
- break;
220
- case 12:
221
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 11;
222
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
223
- break;
224
- case 13:
225
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 12;
226
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
227
- break;
228
- case 14:
229
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 13;
230
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
231
- break;
232
- case 15:
233
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 14;
234
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
235
- break;
236
- case 16:
237
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 15;
238
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
239
- break;
240
- case 17:
241
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 16;
242
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
243
- break;
244
- case 18:
245
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 17;
246
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
247
- break;
248
- case 19:
249
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 18;
250
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
251
- break;
252
- case 20:
253
- default:
254
- this.CurrentAmbientLightLevel = this.set_maxLux;
255
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
256
- }
257
- this.updateHomeKitCharacteristics();
112
+ const { temperature, humidity, lightLevel } = context;
113
+ const { CurrentTemperature } = this.TemperatureSensor || { CurrentTemperature: undefined };
114
+ const { CurrentAmbientLightLevel } = this.LightSensor || { CurrentAmbientLightLevel: undefined };
115
+ const { CurrentRelativeHumidity } = this.HumiditySensor || { CurrentRelativeHumidity: undefined };
116
+ if (context.scale !== 'CELCIUS' && device.hub?.convertUnitTo === undefined) {
117
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} received a non-CELCIUS Webhook scale: `
118
+ + `${context.scale}, Use the *convertUnitsTo* config under Hub settings, if displaying incorrectly in HomeKit.`);
119
+ }
120
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
121
+ '(scale, temperature, humidity, lightLevel) = ' +
122
+ `Webhook:(${context.scale}, ${convertUnits(temperature, context.scale, device.hub?.convertUnitTo)}, ${humidity}, ${lightLevel}), ` +
123
+ `current:(${CurrentTemperature}, ${CurrentRelativeHumidity}, ${CurrentAmbientLightLevel})`);
124
+ if (!this.device.hub?.hide_humidity) {
125
+ this.HumiditySensor.CurrentRelativeHumidity = humidity;
126
+ }
127
+ if (!this.device.hub?.hide_temperature) {
128
+ this.TemperatureSensor.CurrentTemperature = convertUnits(temperature, context.scale, device.hub?.convertUnitTo);
129
+ }
130
+ if (!this.device.hub?.hide_lightsensor) {
131
+ const set_minLux = await this.minLux();
132
+ const set_maxLux = await this.maxLux();
133
+ const spaceBetweenLevels = 19;
134
+ await this.getLightLevel(lightLevel, set_minLux, set_maxLux, spaceBetweenLevels);
258
135
  }
136
+ this.updateHomeKitCharacteristics();
259
137
  }
260
138
  catch (e) {
261
139
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
@@ -264,132 +142,44 @@ export class Hub {
264
142
  };
265
143
  }
266
144
  }
267
- /**
268
- * Parse the device status from the SwitchBot api
269
- */
270
- async parseStatus() {
271
- if (this.BLE) {
272
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE not supported`);
273
- }
274
- else if (this.OpenAPI && this.platform.config.credentials?.token) {
275
- await this.openAPIparseStatus();
276
- }
277
- else {
278
- await this.offlineOff();
279
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`);
280
- }
281
- }
282
- async openAPIparseStatus() {
145
+ async openAPIparseStatus(deviceStatus) {
283
146
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
284
147
  // CurrentRelativeHumidity
285
148
  if (!this.device.hub?.hide_humidity) {
286
- this.CurrentRelativeHumidity = Number(this.OpenAPI_CurrentRelativeHumidity);
287
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
149
+ this.HumiditySensor.CurrentRelativeHumidity = Number(deviceStatus.body.humidity);
150
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
288
151
  }
289
152
  // CurrentTemperature
290
153
  if (!this.device.hub?.hide_temperature) {
291
- this.CurrentTemperature = Number(this.OpenAPI_CurrentTemperature);
292
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
154
+ this.TemperatureSensor.CurrentTemperature = Number(deviceStatus.body.temperature);
155
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor.CurrentTemperature}°c`);
293
156
  }
294
157
  // Brightness
295
158
  if (!this.device.hub?.hide_lightsensor) {
296
159
  if (!this.device.curtain?.hide_lightsensor) {
297
- this.set_minLux = this.minLux();
298
- this.set_maxLux = this.maxLux();
299
- this.spaceBetweenLevels = 19;
300
- switch (this.OpenAPI_CurrentAmbientLightLevel) {
301
- case 1:
302
- this.CurrentAmbientLightLevel = this.set_minLux;
303
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
304
- break;
305
- case 2:
306
- this.CurrentAmbientLightLevel = (this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels;
307
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel},` +
308
- ` Calculation: ${(this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels}`);
309
- break;
310
- case 3:
311
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 2;
312
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
313
- break;
314
- case 4:
315
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 3;
316
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
317
- break;
318
- case 5:
319
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 4;
320
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
321
- break;
322
- case 6:
323
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 5;
324
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
325
- break;
326
- case 7:
327
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 6;
328
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
329
- break;
330
- case 8:
331
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 7;
332
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
333
- break;
334
- case 9:
335
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 8;
336
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
337
- break;
338
- case 10:
339
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 9;
340
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
341
- break;
342
- case 11:
343
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 10;
344
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
345
- break;
346
- case 12:
347
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 11;
348
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
349
- break;
350
- case 13:
351
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 12;
352
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
353
- break;
354
- case 14:
355
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 13;
356
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
357
- break;
358
- case 15:
359
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 14;
360
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
361
- break;
362
- case 16:
363
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 15;
364
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
365
- break;
366
- case 17:
367
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 16;
368
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
369
- break;
370
- case 18:
371
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 17;
372
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
373
- break;
374
- case 19:
375
- this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 18;
376
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
377
- break;
378
- case 20:
379
- default:
380
- this.CurrentAmbientLightLevel = this.set_maxLux;
381
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel}`);
382
- }
383
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.OpenAPI_CurrentAmbientLightLevel},` +
384
- ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
160
+ const set_minLux = await this.minLux();
161
+ const set_maxLux = await this.maxLux();
162
+ const spaceBetweenLevels = 19;
163
+ const lightLevel = deviceStatus.body.lightLevel;
164
+ await this.getLightLevel(lightLevel, set_minLux, set_maxLux, spaceBetweenLevels);
165
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${deviceStatus.body.lightLevel},` +
166
+ ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
385
167
  }
386
168
  if (!this.device.hub?.hide_lightsensor) {
387
- this.lightSensorService?.setCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
169
+ this.LightSensor.Service.setCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor.CurrentAmbientLightLevel);
388
170
  }
389
171
  }
390
- // FirmwareRevision
391
- this.FirmwareRevision = this.OpenAPI_FirmwareRevision;
392
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
172
+ // Firmware Version
173
+ const version = deviceStatus.body.version?.toString();
174
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
175
+ if (deviceStatus.body.version) {
176
+ this.accessory.context.version = version?.replace(/^V|-.*$/g, '');
177
+ this.accessory
178
+ .getService(this.hap.Service.AccessoryInformation)
179
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.accessory.context.version)
180
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
181
+ .updateValue(this.accessory.context.version);
182
+ }
393
183
  }
394
184
  async refreshStatus() {
395
185
  if (this.BLE) {
@@ -406,7 +196,7 @@ export class Hub {
406
196
  async openAPIRefreshStatus() {
407
197
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
408
198
  try {
409
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
199
+ const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries, `${Devices}/${this.device.deviceId}/status`, {
410
200
  headers: this.platform.generateHeaders(),
411
201
  });
412
202
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
@@ -414,13 +204,9 @@ export class Hub {
414
204
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
415
205
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
416
206
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
417
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
207
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
418
208
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
419
- this.OpenAPI_CurrentTemperature = deviceStatus.body.temperature;
420
- this.OpenAPI_CurrentRelativeHumidity = deviceStatus.body.humidity;
421
- this.OpenAPI_CurrentAmbientLightLevel = deviceStatus.body.lightLevel;
422
- this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
423
- this.openAPIparseStatus();
209
+ this.openAPIparseStatus(deviceStatus);
424
210
  this.updateHomeKitCharacteristics();
425
211
  }
426
212
  else {
@@ -442,352 +228,199 @@ export class Hub {
442
228
  const entry = { time: Math.round(new Date().valueOf() / 1000) };
443
229
  // CurrentRelativeHumidity
444
230
  if (!this.device.hub?.hide_humidity) {
445
- if (this.CurrentRelativeHumidity === undefined) {
446
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
231
+ if (this.HumiditySensor.CurrentRelativeHumidity === undefined) {
232
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
233
+ + ` CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`);
447
234
  }
448
235
  else {
449
236
  if (this.device.mqttURL) {
450
- mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
237
+ mqttmessage.push(`"humidity": ${this.HumiditySensor.CurrentRelativeHumidity}`);
451
238
  }
452
239
  if (this.device.history) {
453
- entry['humidity'] = this.CurrentRelativeHumidity;
240
+ entry['humidity'] = this.HumiditySensor.CurrentRelativeHumidity;
454
241
  }
455
- this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
456
- this.humidityService?.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
242
+ this.accessory.context.CurrentRelativeHumidity = this.HumiditySensor.CurrentRelativeHumidity;
243
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, this.HumiditySensor.CurrentRelativeHumidity);
457
244
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
458
- + `updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
245
+ + `updateCharacteristic CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}`);
459
246
  }
460
247
  }
461
248
  // CurrentTemperature
462
249
  if (!this.device.hub?.hide_temperature) {
463
- if (this.CurrentTemperature === undefined) {
464
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
250
+ if (this.TemperatureSensor.CurrentTemperature === undefined) {
251
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`);
465
252
  }
466
253
  else {
467
254
  if (this.device.mqttURL) {
468
- mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
255
+ mqttmessage.push(`"temperature": ${this.TemperatureSensor.CurrentTemperature}`);
469
256
  }
470
257
  if (this.device.history) {
471
- entry['temp'] = this.CurrentTemperature;
258
+ entry['temp'] = this.TemperatureSensor.CurrentTemperature;
472
259
  }
473
- this.accessory.context.CurrentTemperature = this.CurrentTemperature;
474
- this.temperatureService?.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.CurrentTemperature);
475
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
260
+ this.accessory.context.CurrentTemperature = this.TemperatureSensor.CurrentTemperature;
261
+ this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.TemperatureSensor.CurrentTemperature);
262
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
263
+ + ` CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`);
476
264
  }
477
265
  }
478
266
  // CurrentAmbientLightLevel
479
267
  if (!this.device.hub?.hide_lightsensor) {
480
- if (this.CurrentAmbientLightLevel === undefined) {
481
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
268
+ if (this.LightSensor.CurrentAmbientLightLevel === undefined) {
269
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
270
+ + ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
482
271
  }
483
272
  else {
484
273
  if (this.device.mqttURL) {
485
- mqttmessage.push(`"light": ${this.CurrentAmbientLightLevel}`);
274
+ mqttmessage.push(`"light": ${this.LightSensor.CurrentAmbientLightLevel}`);
486
275
  }
487
276
  if (this.device.history) {
488
- entry['lux'] = this.CurrentAmbientLightLevel;
277
+ entry['lux'] = this.LightSensor.CurrentAmbientLightLevel;
489
278
  }
490
- this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
491
- this.lightSensorService?.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
279
+ this.accessory.context.CurrentAmbientLightLevel = this.LightSensor.CurrentAmbientLightLevel;
280
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor.CurrentAmbientLightLevel);
492
281
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
493
- + `updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
282
+ + `updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
494
283
  }
495
284
  }
496
285
  // MQTT
497
286
  if (this.device.mqttURL) {
498
287
  this.mqttPublish(`{${mqttmessage.join(',')}}`);
499
288
  }
500
- if (Number(this.CurrentRelativeHumidity) > 0) {
289
+ if (Number(this.HumiditySensor.CurrentRelativeHumidity) > 0) {
501
290
  // reject unreliable data
502
291
  if (this.device.history) {
503
292
  this.historyService?.addEntry(entry);
504
293
  }
505
294
  }
506
295
  }
507
- /*
508
- * Publish MQTT message for topics of
509
- * 'homebridge-switchbot/meter/xx:xx:xx:xx:xx:xx'
510
- */
511
- mqttPublish(message) {
512
- const mac = this.device.deviceId
513
- ?.toLowerCase()
514
- .match(/[\s\S]{1,2}/g)
515
- ?.join(':');
516
- const options = this.device.mqttPubOptions || {};
517
- this.mqttClient?.publish(`homebridge-switchbot/hub/${mac}`, `${message}`, options);
518
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
519
- }
520
- /*
521
- * Setup MQTT hadler if URL is specified.
522
- */
523
- async setupMqtt(device) {
524
- if (device.mqttURL) {
525
- try {
526
- const { connectAsync } = asyncmqtt;
527
- this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
528
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
529
- this.mqttClient.on('error', (e) => {
530
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
531
- });
296
+ async offlineOff() {
297
+ if (this.device.offline) {
298
+ if (!this.device.hub?.hide_temperature) {
299
+ this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.accessory.context.CurrentTemperature);
300
+ }
301
+ if (!this.device.hub?.hide_humidity) {
302
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, this.accessory.context.CurrentRelativeHumidity);
532
303
  }
533
- catch (e) {
534
- this.mqttClient = null;
535
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
304
+ if (!this.device.hub?.hide_lightsensor) {
305
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.accessory.context.CurrentAmbientLightLevel);
536
306
  }
537
307
  }
538
308
  }
539
- /*
540
- * Setup EVE history graph feature if enabled.
541
- */
542
- async setupHistoryService(device) {
543
- const mac = this.device
544
- .deviceId.match(/.{1,2}/g)
545
- .join(':')
546
- .toLowerCase();
547
- this.historyService = device.history
548
- ? new this.platform.fakegatoAPI('custom', this.accessory, {
549
- log: this.platform.log,
550
- storage: 'fs',
551
- filename: `${hostname().split('.')[0]}_${mac}_persist.json`,
552
- })
553
- : null;
309
+ async apiError(e) {
310
+ if (!this.device.hub?.hide_temperature) {
311
+ this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
312
+ }
313
+ if (!this.device.hub?.hide_humidity) {
314
+ this.HumiditySensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
315
+ }
316
+ if (!this.device.hub?.hide_lightsensor) {
317
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
318
+ }
554
319
  }
555
- async statusCode(statusCode) {
556
- switch (statusCode) {
557
- case 151:
558
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
320
+ async minLux() {
321
+ let set_minLux;
322
+ if (this.device.curtain?.set_minLux) {
323
+ set_minLux = this.device.curtain?.set_minLux;
324
+ }
325
+ else {
326
+ set_minLux = 1;
327
+ }
328
+ return set_minLux;
329
+ }
330
+ async maxLux() {
331
+ let set_maxLux;
332
+ if (this.device.curtain?.set_maxLux) {
333
+ set_maxLux = this.device.curtain?.set_maxLux;
334
+ }
335
+ else {
336
+ set_maxLux = 6001;
337
+ }
338
+ return set_maxLux;
339
+ }
340
+ async getLightLevel(lightLevel, set_minLux, set_maxLux, spaceBetweenLevels) {
341
+ switch (lightLevel) {
342
+ case 1:
343
+ this.LightSensor.CurrentAmbientLightLevel = set_minLux;
344
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
345
+ break;
346
+ case 2:
347
+ this.LightSensor.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
348
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel},` +
349
+ ` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`);
559
350
  break;
560
- case 152:
561
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
351
+ case 3:
352
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
353
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
562
354
  break;
563
- case 160:
564
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
355
+ case 4:
356
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
357
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
565
358
  break;
566
- case 161:
567
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
568
- this.offlineOff();
359
+ case 5:
360
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
361
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
569
362
  break;
570
- case 171:
571
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
572
- `Hub: ${this.device.hubDeviceId}`);
573
- this.offlineOff();
363
+ case 6:
364
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
365
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
574
366
  break;
575
- case 190:
576
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
577
- ` Or command format is invalid, statusCode: ${statusCode}`);
367
+ case 7:
368
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
369
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
578
370
  break;
579
- case 100:
580
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
371
+ case 8:
372
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
373
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
581
374
  break;
582
- case 200:
583
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
375
+ case 9:
376
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
377
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
584
378
  break;
585
- case 400:
586
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
587
- + `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
379
+ case 10:
380
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 9;
381
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
588
382
  break;
589
- case 401:
590
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
591
- + `but the request has not been authenticated, statusCode: ${statusCode}`);
383
+ case 11:
384
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 10;
385
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
592
386
  break;
593
- case 403:
594
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
595
- + `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
387
+ case 12:
388
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 11;
389
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
596
390
  break;
597
- case 404:
598
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
599
- + `statusCode: ${statusCode}`);
391
+ case 13:
392
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 12;
393
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
600
394
  break;
601
- case 406:
602
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
603
- + `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
395
+ case 14:
396
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 13;
397
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
604
398
  break;
605
- case 415:
606
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
607
- + `header that is not supported by the server, statusCode: ${statusCode}`);
399
+ case 15:
400
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 14;
401
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
608
402
  break;
609
- case 422:
610
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
611
- + `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
403
+ case 16:
404
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 15;
405
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
612
406
  break;
613
- case 429:
614
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
615
- + `requests allowed for a given time window, statusCode: ${statusCode}`);
407
+ case 17:
408
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 16;
409
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
616
410
  break;
617
- case 500:
618
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
619
- + `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
411
+ case 18:
412
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 17;
413
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
620
414
  break;
415
+ case 19:
416
+ this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 18;
417
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
418
+ break;
419
+ case 20:
621
420
  default:
622
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
623
- `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
624
- }
625
- }
626
- async offlineOff() {
627
- if (this.device.offline) {
628
- await this.deviceContext();
629
- await this.updateHomeKitCharacteristics();
421
+ this.LightSensor.CurrentAmbientLightLevel = set_maxLux;
422
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${lightLevel}`);
630
423
  }
631
424
  }
632
- async apiError(e) {
633
- if (!this.device.hub?.hide_temperature) {
634
- this.temperatureService?.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
635
- }
636
- if (!this.device.hub?.hide_humidity) {
637
- this.humidityService?.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
638
- }
639
- if (!this.device.hub?.hide_lightsensor) {
640
- this.lightSensorService?.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
641
- }
642
- }
643
- minLux() {
644
- if (this.device.curtain?.set_minLux) {
645
- this.set_minLux = this.device.curtain?.set_minLux;
646
- }
647
- else {
648
- this.set_minLux = 1;
649
- }
650
- return this.set_minLux;
651
- }
652
- maxLux() {
653
- if (this.device.curtain?.set_maxLux) {
654
- this.set_maxLux = this.device.curtain?.set_maxLux;
655
- }
656
- else {
657
- this.set_maxLux = 6001;
658
- }
659
- return this.set_maxLux;
660
- }
661
- async deviceContext() {
662
- if (this.CurrentRelativeHumidity === undefined) {
663
- this.CurrentRelativeHumidity = 0;
664
- }
665
- else {
666
- this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity;
667
- }
668
- if (this.CurrentTemperature === undefined) {
669
- this.CurrentTemperature = 0;
670
- }
671
- else {
672
- this.CurrentTemperature = this.accessory.context.CurrentTemperature;
673
- }
674
- if (this.CurrentAmbientLightLevel === undefined) {
675
- this.CurrentAmbientLightLevel = this.set_minLux;
676
- }
677
- else {
678
- this.CurrentAmbientLightLevel = this.accessory.context.CurrentAmbientLightLevel;
679
- }
680
- if (this.FirmwareRevision === undefined) {
681
- this.FirmwareRevision = this.platform.version;
682
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
683
- }
684
- }
685
- async refreshRate(device) {
686
- // refreshRate
687
- if (device.refreshRate) {
688
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
689
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
690
- }
691
- else if (this.platform.config.options.refreshRate) {
692
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
693
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
694
- }
695
- // updateRate
696
- if (device?.curtain?.updateRate) {
697
- this.updateRate = device?.curtain?.updateRate;
698
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Curtain updateRate: ${this.updateRate}`);
699
- }
700
- else {
701
- this.updateRate = 7;
702
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Curtain updateRate: ${this.updateRate}`);
703
- }
704
- }
705
- async deviceConfig(device) {
706
- let config = {};
707
- if (device.hub) {
708
- config = device.hub;
709
- }
710
- if (device.connectionType !== undefined) {
711
- config['connectionType'] = device.connectionType;
712
- }
713
- if (device.external !== undefined) {
714
- config['external'] = device.external;
715
- }
716
- if (device.logging !== undefined) {
717
- config['logging'] = device.logging;
718
- }
719
- if (device.refreshRate !== undefined) {
720
- config['refreshRate'] = device.refreshRate;
721
- }
722
- if (device.webhook !== undefined) {
723
- config['webhook'] = device.webhook;
724
- }
725
- if (Object.entries(config).length !== 0) {
726
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
727
- }
728
- }
729
- async deviceLogs(device) {
730
- if (this.platform.debugMode) {
731
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
732
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
733
- }
734
- else if (device.logging) {
735
- this.deviceLogging = this.accessory.context.logging = device.logging;
736
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
737
- }
738
- else if (this.platform.config.options?.logging) {
739
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
740
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
741
- }
742
- else {
743
- this.deviceLogging = this.accessory.context.logging = 'standard';
744
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
745
- }
746
- }
747
- /**
748
- * Logging for Device
749
- */
750
- infoLog(...log) {
751
- if (this.enablingDeviceLogging()) {
752
- this.platform.log.info(String(...log));
753
- }
754
- }
755
- warnLog(...log) {
756
- if (this.enablingDeviceLogging()) {
757
- this.platform.log.warn(String(...log));
758
- }
759
- }
760
- debugWarnLog(...log) {
761
- if (this.enablingDeviceLogging()) {
762
- if (this.deviceLogging?.includes('debug')) {
763
- this.platform.log.warn('[DEBUG]', String(...log));
764
- }
765
- }
766
- }
767
- errorLog(...log) {
768
- if (this.enablingDeviceLogging()) {
769
- this.platform.log.error(String(...log));
770
- }
771
- }
772
- debugErrorLog(...log) {
773
- if (this.enablingDeviceLogging()) {
774
- if (this.deviceLogging?.includes('debug')) {
775
- this.platform.log.error('[DEBUG]', String(...log));
776
- }
777
- }
778
- }
779
- debugLog(...log) {
780
- if (this.enablingDeviceLogging()) {
781
- if (this.deviceLogging === 'debug') {
782
- this.platform.log.info('[DEBUG]', String(...log));
783
- }
784
- else {
785
- this.platform.log.debug(String(...log));
786
- }
787
- }
788
- }
789
- enablingDeviceLogging() {
790
- return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
791
- }
792
425
  }
793
426
  //# sourceMappingURL=hub.js.map