@switchbot/homebridge-switchbot 2.0.0-beta.2 → 2.0.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 (113) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +75 -20
  4. package/dist/device/bot.d.ts +32 -28
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +646 -648
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +34 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +429 -304
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +16 -7
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +288 -230
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +21 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +519 -489
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +22 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +415 -360
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +22 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +253 -147
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +21 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +325 -255
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +23 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +346 -208
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +17 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +261 -209
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +24 -16
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +267 -242
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +51 -16
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +527 -185
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +7 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +261 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +3 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +137 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +9 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +116 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +8 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +143 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +9 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +120 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +9 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +128 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +10 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +126 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +7 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +115 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +6 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +115 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +5 -5
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +227 -199
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +15 -11
  89. package/dist/settings.d.ts.map +1 -1
  90. package/dist/settings.js.map +1 -1
  91. package/package.json +12 -10
  92. package/src/device/bot.ts +641 -657
  93. package/src/device/colorbulb.ts +440 -339
  94. package/src/device/contact.ts +289 -233
  95. package/src/device/curtain.ts +523 -503
  96. package/src/device/humidifier.ts +421 -396
  97. package/src/device/lock.ts +257 -147
  98. package/src/device/meter.ts +335 -268
  99. package/src/device/meterplus.ts +354 -213
  100. package/src/device/motion.ts +264 -213
  101. package/src/device/plug.ts +270 -251
  102. package/src/device/striplight.ts +552 -207
  103. package/src/irdevice/airconditioner.ts +263 -241
  104. package/src/irdevice/airpurifier.ts +132 -103
  105. package/src/irdevice/camera.ts +112 -85
  106. package/src/irdevice/fan.ts +138 -106
  107. package/src/irdevice/light.ts +116 -103
  108. package/src/irdevice/other.ts +124 -97
  109. package/src/irdevice/tv.ts +123 -93
  110. package/src/irdevice/vacuumcleaner.ts +112 -89
  111. package/src/irdevice/waterheater.ts +111 -89
  112. package/src/platform.ts +216 -214
  113. package/src/settings.ts +15 -11
@@ -2,9 +2,10 @@ import https from 'https';
2
2
  import crypto from 'crypto';
3
3
  import { Context } from 'vm';
4
4
  import { IncomingMessage } from 'http';
5
+ import superStringify from 'super-stringify';
5
6
  import { interval, Subject } from 'rxjs';
6
7
  import { SwitchBotPlatform } from '../platform';
7
- import { debounceTime, skipWhile, tap } from 'rxjs/operators';
8
+ import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
8
9
  import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
9
10
  import { device, devicesConfig, deviceStatus, switchbot, hs2rgb, rgb2hs, m2hs, serviceData, ad, HostDomain, DevicePath } from '../settings';
10
11
 
@@ -19,15 +20,10 @@ export class ColorBulb {
19
20
 
20
21
  // Characteristic Values
21
22
  On!: CharacteristicValue;
22
- OnCached!: CharacteristicValue;
23
23
  Hue!: CharacteristicValue;
24
- HueCached!: CharacteristicValue;
25
24
  Saturation!: CharacteristicValue;
26
- SaturationCached!: CharacteristicValue;
27
25
  Brightness!: CharacteristicValue;
28
- BrightnessCached!: CharacteristicValue;
29
26
  ColorTemperature?: CharacteristicValue;
30
- ColorTemperatureCached?: CharacteristicValue;
31
27
 
32
28
  // OpenAPI Others
33
29
  power: deviceStatus['power'];
@@ -65,6 +61,10 @@ export class ColorBulb {
65
61
  colorBulbUpdateInProgress!: boolean;
66
62
  doColorBulbUpdate!: Subject<void>;
67
63
 
64
+ // Connection
65
+ private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'Both');
66
+ private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'Both');
67
+
68
68
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
69
69
  // default placeholders
70
70
  this.logs(device);
@@ -72,17 +72,7 @@ export class ColorBulb {
72
72
  this.refreshRate(device);
73
73
  this.adaptiveLighting(device);
74
74
  this.config(device);
75
- if (this.On === undefined) {
76
- this.On = false;
77
- } else {
78
- this.On = this.accessory.context.On;
79
- }
80
- this.Hue = 0;
81
- this.Brightness = 0;
82
- this.Saturation = 0;
83
- this.ColorTemperature = 140;
84
- this.minKelvin = 2000;
85
- this.maxKelvin = 9000;
75
+ this.context();
86
76
  // this is subject we use to track when we need to POST changes to the SwitchBot API
87
77
  this.doColorBulbUpdate = new Subject();
88
78
  this.colorBulbUpdateInProgress = false;
@@ -109,7 +99,7 @@ export class ColorBulb {
109
99
  this.accessory.removeService(this.lightBulbService);
110
100
  this.lightBulbService = this.accessory.addService(this.platform.Service.Lightbulb);
111
101
  this.accessory.context.adaptiveLighting = false;
112
- this.debugLog(`Color Bulb: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting}`);
102
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting}`);
113
103
  }
114
104
 
115
105
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
@@ -138,7 +128,7 @@ export class ColorBulb {
138
128
  .onSet(this.BrightnessSet.bind(this));
139
129
 
140
130
  // handle ColorTemperature events using the ColorTemperature characteristic
141
- this.debugLog(`Color Bulb: ${accessory.displayName} Add ColorTemperature Characteristic`);
131
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add ColorTemperature Characteristic`);
142
132
  this.lightBulbService
143
133
  .getCharacteristic(this.platform.Characteristic.ColorTemperature)
144
134
  .setProps({
@@ -177,7 +167,7 @@ export class ColorBulb {
177
167
  })
178
168
  .onSet(this.SaturationSet.bind(this));
179
169
 
180
- this.debugLog(`Color Bulb: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
170
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
181
171
  if (this.adaptiveLightingShift !== -1) {
182
172
  this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.lightBulbService, {
183
173
  customTemperatureAdjustment: this.adaptiveLightingShift,
@@ -185,7 +175,7 @@ export class ColorBulb {
185
175
  this.accessory.configureController(this.AdaptiveLightingController);
186
176
  this.accessory.context.adaptiveLighting = true;
187
177
  this.debugLog(
188
- `Color Bulb: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting},` +
178
+ `${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting},` +
189
179
  ` adaptiveLightingShift: ${this.adaptiveLightingShift}`,
190
180
  );
191
181
  }
@@ -213,26 +203,38 @@ export class ColorBulb {
213
203
  try {
214
204
  await this.pushChanges();
215
205
  } catch (e: any) {
216
- this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges`);
217
- if (this.deviceLogging.includes('debug')) {
218
- this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
219
- }
220
206
  this.apiError(e);
207
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
208
+ + ` Error Message: ${superStringify(e.message)}`);
221
209
  }
222
210
  this.colorBulbUpdateInProgress = false;
211
+ // Refresh the status from the API
212
+ interval(15000)
213
+ .pipe(skipWhile(() => this.colorBulbUpdateInProgress))
214
+ .pipe(take(1))
215
+ .subscribe(async () => {
216
+ await this.refreshStatus();
217
+ });
223
218
  });
224
219
  }
225
220
 
221
+ /**
222
+ * Parse the device status from the SwitchBot api
223
+ */
226
224
  async parseStatus(): Promise<void> {
227
- if (this.SwitchToOpenAPI || !this.device.ble) {
225
+ /*if (this.BLE && !this.SwitchToOpenAPI) {
226
+ await this.BLEparseStatus();
227
+ } else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
228
+ this.SwitchToOpenAPI = false;
228
229
  await this.openAPIparseStatus();
229
230
  } else {
230
- await this.BLEparseStatus();
231
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
232
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
231
233
  }
232
234
  }
233
235
 
234
236
  async BLEparseStatus(): Promise<void> {
235
- this.debugLog(`Color Bulb: ${this.accessory.displayName} BLE parseStatus`);
237
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
236
238
  // State
237
239
  switch (this.state) {
238
240
  case 'on':
@@ -241,10 +243,11 @@ export class ColorBulb {
241
243
  default:
242
244
  this.On = false;
243
245
  }
244
- this.debugLog(`Color Bulb: ${this.accessory.displayName} On: ${this.On}`);
246
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
245
247
  }
246
248
 
247
249
  async openAPIparseStatus() {
250
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
248
251
  switch (this.power) {
249
252
  case 'on':
250
253
  this.On = true;
@@ -252,61 +255,68 @@ export class ColorBulb {
252
255
  default:
253
256
  this.On = false;
254
257
  }
255
- this.debugLog(`Color Bulb: ${this.accessory.displayName} On: ${this.On}`);
258
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
256
259
 
257
260
  // Brightness
258
261
  this.Brightness = Number(this.brightness);
259
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
262
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
260
263
 
261
264
  // Color, Hue & Brightness
262
265
  if (this.color) {
263
- this.debugLog(`Color Bulb: ${this.accessory.displayName} color: ${JSON.stringify(this.color)}`);
266
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} color: ${superStringify(this.color)}`);
264
267
  const [red, green, blue] = this.color!.split(':');
265
- this.debugLog(`Color Bulb: ${this.accessory.displayName} red: ${JSON.stringify(red)}`);
266
- this.debugLog(`Color Bulb: ${this.accessory.displayName} green: ${JSON.stringify(green)}`);
267
- this.debugLog(`Color Bulb: ${this.accessory.displayName} blue: ${JSON.stringify(blue)}`);
268
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} red: ${superStringify(red)}`);
269
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} green: ${superStringify(green)}`);
270
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} blue: ${superStringify(blue)}`);
268
271
 
269
272
  const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
270
- this.debugLog(`Color Bulb: ${this.accessory.displayName} hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
273
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
274
+ + ` hs: ${superStringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
271
275
 
272
276
  // Hue
273
277
  this.Hue = hue;
274
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Hue: ${this.Hue}`);
278
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
275
279
 
276
280
  // Saturation
277
281
  this.Saturation = saturation;
278
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
282
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
279
283
  }
280
284
 
281
285
  // ColorTemperature
282
286
  if (!Number.isNaN(this.colorTemperature)) {
283
- this.debugLog(`Color Bulb: ${this.accessory.displayName} OpenAPI ColorTemperature: ${this.colorTemperature}`);
287
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI ColorTemperature: ${this.colorTemperature}`);
284
288
  const mired = Math.round(1000000 / this.colorTemperature!);
285
289
 
286
290
  this.ColorTemperature = Number(mired);
287
291
 
288
292
  this.ColorTemperature = Math.max(Math.min(this.ColorTemperature, 500), 140);
289
- this.debugLog(`Color Bulb: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
293
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
290
294
  }
291
295
  }
292
296
 
297
+ /**
298
+ * Asks the SwitchBot API for the latest device information
299
+ */
293
300
  async refreshStatus(): Promise<void> {
294
- if (this.device.ble) {
301
+ /*if (this.BLE) {
295
302
  await this.BLERefreshStatus();
296
- } else {
303
+ } else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
297
304
  await this.openAPIRefreshStatus();
305
+ } else {
306
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
307
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
298
308
  }
299
309
  }
300
310
 
301
311
  async BLERefreshStatus(): Promise<void> {
302
- this.debugLog(`Color Bulb: ${this.accessory.displayName} BLE refreshStatus`);
312
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
303
313
  const switchbot = await this.platform.connectBLE();
304
314
  // Convert to BLE Address
305
315
  this.device.bleMac = this.device
306
316
  .deviceId!.match(/.{1,2}/g)!
307
317
  .join(':')
308
318
  .toLowerCase();
309
- this.debugLog(`Color Bulb: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
319
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
310
320
  this.getCustomBLEAddress(switchbot);
311
321
  // Start to monitor advertisement packets
312
322
  if (switchbot !== false) {
@@ -317,17 +327,15 @@ export class ColorBulb {
317
327
  })
318
328
  .then(() => {
319
329
  // Set an event hander
320
- this.errorLog(`Color Bulb: ${this.accessory.displayName} then switchbot: ${JSON.stringify(switchbot)}`);
321
330
  switchbot.onadvertisement = (ad: any) => {
322
- this.errorLog(`Color Bulb: ${this.accessory.displayName} switchbot: ${JSON.stringify(switchbot.onadvertisement)}`);
323
- this.errorLog(`Color Bulb: ${this.accessory.displayName} ad: ${JSON.stringify(ad)}`);
324
331
  this.address = ad.address;
325
332
  if (this.deviceLogging.includes('debug')) {
326
333
  this.infoLog(this.address);
327
334
  this.infoLog(this.device.bleMac);
328
- this.infoLog(`Color Bulb: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
329
- this.infoLog(`Color Bulb: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
335
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
336
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
330
337
  }
338
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
331
339
  this.serviceData = ad.serviceData;
332
340
  //this.state = ad.serviceData.state;
333
341
  //this.delay = ad.serviceData.delay;
@@ -336,19 +344,19 @@ export class ColorBulb {
336
344
  //this.wifiRssi = ad.serviceData.wifiRssi;
337
345
  //this.overload = ad.serviceData.overload;
338
346
  //this.currentPower = ad.serviceData.currentPower;
339
- this.debugLog(`Color Bulb: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
347
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
340
348
  /*this.debugLog(
341
- `Color Bulb: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
349
+ `${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
342
350
  `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
343
351
  `wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
344
352
  );*/
345
353
 
346
354
  if (this.serviceData) {
347
355
  this.connected = true;
348
- this.debugLog(`Color Bulb: ${this.accessory.displayName} connected: ${this.connected}`);
356
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
349
357
  } else {
350
358
  this.connected = false;
351
- this.debugLog(`Color Bulb: ${this.accessory.displayName} connected: ${this.connected}`);
359
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
352
360
  }
353
361
  };
354
362
  // Wait 2 seconds
@@ -361,69 +369,29 @@ export class ColorBulb {
361
369
  this.parseStatus();
362
370
  this.updateHomeKitCharacteristics();
363
371
  } else {
364
- this.errorLog(`Color Bulb: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
365
- if (this.platform.config.credentials?.token) {
366
- this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
367
- this.SwitchToOpenAPI = true;
368
- await this.openAPIRefreshStatus();
369
- }
372
+ await this.BLEconnection(switchbot);
370
373
  }
371
374
  })
372
375
  .catch(async (e: any) => {
373
- this.errorLog(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
374
- if (this.deviceLogging.includes('debug')) {
375
- this.errorLog(
376
- `Color Bulb: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
377
- );
378
- }
379
- if (this.platform.config.credentials?.token) {
380
- this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
381
- this.SwitchToOpenAPI = true;
382
- await this.openAPIRefreshStatus();
383
- }
384
376
  this.apiError(e);
377
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
378
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
379
+ await this.BLEconnection(switchbot);
385
380
  });
386
381
  } else {
387
382
  await this.BLEconnection(switchbot);
388
383
  }
389
384
  }
390
385
 
391
- async getCustomBLEAddress(switchbot: any) {
392
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
393
- this.debugLog(`Color Bulb: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
394
- (async () => {
395
- // Start to monitor advertisement packets
396
- await switchbot.startScan({
397
- model: 'u',
398
- });
399
- // Set an event handler
400
- switchbot.onadvertisement = (ad: any) => {
401
- this.warnLog(`Color Bulb: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
402
- };
403
- await switchbot.wait(10000);
404
- // Stop to monitor
405
- switchbot.stopScan();
406
- })();
407
- }
408
- }
409
-
410
- async BLEconnection(switchbot: any): Promise<void> {
411
- this.errorLog(`Color Bulb: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
412
- if (this.platform.config.credentials?.token) {
413
- this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
414
- this.SwitchToOpenAPI = true;
415
- await this.openAPIRefreshStatus();
416
- }
417
- }
418
-
419
- private async openAPIRefreshStatus() {
386
+ async openAPIRefreshStatus() {
387
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
420
388
  try {
421
389
  const t = Date.now();
422
390
  const nonce = 'requestID';
423
391
  const data = this.platform.config.credentials?.token + t + nonce;
424
392
  const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
425
393
  const sign = signTerm.toString('base64');
426
- this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
394
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
427
395
  const options = {
428
396
  hostname: HostDomain,
429
397
  port: 443,
@@ -438,16 +406,17 @@ export class ColorBulb {
438
406
  },
439
407
  };
440
408
  const req = https.request(options, (res) => {
441
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Refresh statusCode: ${res.statusCode}`);
409
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
410
+ this.statusCode({ res });
442
411
  let rawData = '';
443
412
  res.on('data', (d) => {
444
413
  rawData += d;
445
- this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
414
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
446
415
  });
447
416
  res.on('end', () => {
448
417
  try {
449
418
  this.deviceStatus = JSON.parse(rawData);
450
- this.debugLog(`Color Bulb: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
419
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
451
420
  this.power = this.deviceStatus.body.power;
452
421
  this.color = this.deviceStatus.body.color;
453
422
  this.brightness = this.deviceStatus.body.brightness;
@@ -455,22 +424,18 @@ export class ColorBulb {
455
424
  this.parseStatus();
456
425
  this.updateHomeKitCharacteristics();
457
426
  } catch (e: any) {
458
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
427
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
459
428
  }
460
429
  });
461
430
  });
462
431
  req.on('error', (e: any) => {
463
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
432
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
464
433
  });
465
434
  req.end();
466
435
  } catch (e: any) {
467
- this.errorLog(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
468
- if (this.deviceLogging.includes('debug')) {
469
- this.errorLog(
470
- `Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
471
- );
472
- }
473
436
  this.apiError(e);
437
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
438
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
474
439
  }
475
440
  }
476
441
 
@@ -486,8 +451,66 @@ export class ColorBulb {
486
451
  *
487
452
  */
488
453
  async pushChanges(): Promise<void> {
454
+ /*if (this.BLE) {
455
+ await this.BLERefreshStatus();
456
+ } else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
457
+ await this.openAPIpushChanges();
458
+ } else {
459
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
460
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
461
+ }
462
+ interval(5000)
463
+ .pipe(take(1))
464
+ .subscribe(async () => {
465
+ await this.refreshStatus();
466
+ });
467
+ }
468
+
469
+ async BLEpushChanges(): Promise<void> {
470
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
471
+ if (this.On !== this.accessory.context.On) {
472
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${this.On} OnCached: ${this.accessory.context.On}`);
473
+ const switchbot = await this.platform.connectBLE();
474
+ // Convert to BLE Address
475
+ this.device.bleMac = this.device
476
+ .deviceId!.match(/.{1,2}/g)!
477
+ .join(':')
478
+ .toLowerCase();
479
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
480
+ switchbot
481
+ .discover({
482
+ model: 'u',
483
+ id: this.device.bleMac,
484
+ })
485
+ .then((device_list: any) => {
486
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
487
+ return this.turnOnOff(device_list);
488
+ })
489
+ .then(() => {
490
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
491
+ this.On = false;
492
+ })
493
+ .catch(async (e: any) => {
494
+ this.apiError(e);
495
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
496
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
497
+ if (this.platform.config.credentials?.token && this.device.connectionType !== 'Both') {
498
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
499
+ await this.openAPIpushChanges();
500
+ }
501
+ });
502
+ } else {
503
+ this.debugLog(
504
+ `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, `
505
+ +`OnCached: ${this.accessory.context.On}`,
506
+ );
507
+ }
508
+ }
509
+
510
+ async openAPIpushChanges(): Promise<void> {
489
511
  try {
490
- if (this.On !== this.OnCached) {
512
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
513
+ if (this.On !== this.accessory.context.On) {
491
514
  // Make Push On request to the API
492
515
  const t = Date.now();
493
516
  const nonce = 'requestID';
@@ -496,7 +519,7 @@ export class ColorBulb {
496
519
  .update(Buffer.from(data, 'utf-8'))
497
520
  .digest();
498
521
  const sign = signTerm.toString('base64');
499
- this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
522
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
500
523
 
501
524
  let command = '';
502
525
  if (this.On) {
@@ -504,12 +527,12 @@ export class ColorBulb {
504
527
  } else {
505
528
  command = 'turnOff';
506
529
  }
507
- const body = JSON.stringify({
530
+ const body = superStringify({
508
531
  'command': `${command}`,
509
532
  'parameter': 'default',
510
533
  'commandType': 'command',
511
534
  });
512
- this.infoLog(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
535
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
513
536
  const options = {
514
537
  hostname: HostDomain,
515
538
  port: 443,
@@ -525,55 +548,53 @@ export class ColorBulb {
525
548
  },
526
549
  };
527
550
  const req = https.request(options, res => {
528
- this.debugLog(`Color Bulb: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
551
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
529
552
  this.statusCode({ res });
530
553
  res.on('data', d => {
531
- this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
554
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
532
555
  });
533
556
  });
534
557
  req.on('error', (e: any) => {
535
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
558
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
536
559
  });
537
560
  req.write(body);
538
561
  req.end();
539
- this.debugLog(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(req)}`);
540
- this.OnCached = this.On;
541
- this.accessory.context.On = this.OnCached;
562
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges: ${superStringify(req)}`);
563
+ } else {
564
+ this.debugLog(
565
+ `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `On: ${this.On}, `
566
+ +`OnCached: ${this.accessory.context.On}`,
567
+ );
542
568
  }
543
569
  // Push Brightness Update
544
570
  if (this.On) {
545
- //await this.pushBrightnessChanges();
571
+ await this.pushBrightnessChanges();
546
572
  }
547
-
548
573
  // Push ColorTemperature Update
549
574
  if (this.On) {
550
- //await this.pushColorTemperatureChanges();
575
+ await this.pushColorTemperatureChanges();
551
576
  }
552
-
553
577
  // Push Hue & Saturation Update
554
578
  if (this.On) {
555
579
  await this.pushHueSaturationChanges();
556
580
  }
557
581
  } catch (e: any) {
558
- this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
559
- if (this.deviceLogging.includes('debug')) {
560
- this.errorLog(
561
- `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
562
- );
563
- }
564
582
  this.apiError(e);
583
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
584
+ + ` Connection, Error Message: ${superStringify(e.message)}`,
585
+ );
565
586
  }
566
587
  }
567
588
 
568
589
  async pushHueSaturationChanges(): Promise<void> {
569
590
  try {
570
- if (this.Hue !== this.HueCached || this.Saturation !== this.SaturationCached) {
571
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Hue: ${JSON.stringify(this.Hue)}`);
572
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.Saturation)}`);
591
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges`);
592
+ if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
593
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${superStringify(this.Hue)}`);
594
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${superStringify(this.Saturation)}`);
573
595
 
574
596
  const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
575
- this.debugLog(`Color Bulb: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
576
-
597
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${superStringify([red, green, blue])}`);
577
598
  // Make Push Hue/Saturation request to the API
578
599
  const t = Date.now();
579
600
  const nonce = 'requestID';
@@ -582,13 +603,13 @@ export class ColorBulb {
582
603
  .update(Buffer.from(data, 'utf-8'))
583
604
  .digest();
584
605
  const sign = signTerm.toString('base64');
585
- this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
586
- const body = JSON.stringify({
606
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
607
+ const body = superStringify({
587
608
  'command': 'setColor',
588
609
  'parameter': `${red}:${green}:${blue}`,
589
610
  'commandType': 'command',
590
611
  });
591
- this.infoLog(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
612
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
592
613
  const options = {
593
614
  hostname: HostDomain,
594
615
  port: 443,
@@ -604,39 +625,32 @@ export class ColorBulb {
604
625
  },
605
626
  };
606
627
  const req = https.request(options, res => {
607
- this.debugLog(`Color Bulb: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
628
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges statusCode: ${res.statusCode}`);
608
629
  res.on('data', d => {
609
- this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
630
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
610
631
  });
611
632
  });
612
633
  req.on('error', (e: any) => {
613
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
634
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
614
635
  });
615
636
  req.write(body);
616
637
  req.end();
617
- this.debugLog(`Color Bulb: ${this.accessory.displayName} pushHueSaturationChanges: ${JSON.stringify(req)}`);
618
- this.HueCached = this.Hue;
619
- this.SaturationCached = this.Saturation;
638
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges: ${superStringify(req)}`);
620
639
  } else {
621
- this.debugLog(
622
- `Color Bulb: ${this.accessory.displayName} No Changes.` +
623
- `Hue: ${this.Hue}, HueCached: ${this.HueCached}, Saturation: ${this.Saturation}, SaturationCached: ${this.SaturationCached}`,
624
- );
640
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushHueSaturationChanges. Hue: ${this.Hue}, `
641
+ + `HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`);
625
642
  }
626
643
  } catch (e: any) {
627
- this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
628
- if (this.deviceLogging.includes('debug')) {
629
- this.errorLog(
630
- `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
631
- );
632
- }
633
644
  this.apiError(e);
645
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushHueSaturationChanges with ${this.device.connectionType}`
646
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
634
647
  }
635
648
  }
636
649
 
637
650
  async pushColorTemperatureChanges(): Promise<void> {
638
651
  try {
639
- if (this.ColorTemperature !== this.ColorTemperatureCached) {
652
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushColorTemperatureChanges`);
653
+ if (this.ColorTemperature !== this.accessory.context.ColorTemperature) {
640
654
  const kelvin = Math.round(1000000 / Number(this.ColorTemperature));
641
655
  this.cacheKelvin = kelvin;
642
656
 
@@ -648,13 +662,13 @@ export class ColorBulb {
648
662
  .update(Buffer.from(data, 'utf-8'))
649
663
  .digest();
650
664
  const sign = signTerm.toString('base64');
651
- this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
652
- const body = JSON.stringify({
665
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
666
+ const body = superStringify({
653
667
  'command': 'setColorTemperature',
654
668
  'parameter': `${kelvin}`,
655
669
  'commandType': 'command',
656
670
  });
657
- this.infoLog(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
671
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
658
672
  const options = {
659
673
  hostname: HostDomain,
660
674
  port: 443,
@@ -670,39 +684,33 @@ export class ColorBulb {
670
684
  },
671
685
  };
672
686
  const req = https.request(options, res => {
673
- this.debugLog(`Color Bulb: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
687
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
674
688
  res.on('data', d => {
675
- this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
689
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
676
690
  });
677
691
  });
678
692
  req.on('error', (e: any) => {
679
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
693
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
680
694
  });
681
695
  req.write(body);
682
696
  req.end();
683
-
684
- this.debugLog(`Color Bulb: ${this.accessory.displayName} pushColorTemperatureChanges: ${JSON.stringify(req)}`);
685
- this.ColorTemperatureCached = this.ColorTemperature;
697
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushColorTemperatureChanges: ${superStringify(req)}`);
698
+ this.accessory.context.ColorTemperature = this.ColorTemperature;
686
699
  } else {
687
- this.debugLog(
688
- `Color Bulb: ${this.accessory.displayName} No Changes.` +
689
- `ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.ColorTemperatureCached}`,
690
- );
700
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushColorTemperatureChanges.` +
701
+ `ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.accessory.context.ColorTemperature}`);
691
702
  }
692
703
  } catch (e: any) {
693
- this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
694
- if (this.deviceLogging.includes('debug')) {
695
- this.errorLog(
696
- `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
697
- );
698
- }
699
704
  this.apiError(e);
705
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushColorTemperatureChanges with ${this.device.connectionType}`
706
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
700
707
  }
701
708
  }
702
709
 
703
710
  async pushBrightnessChanges(): Promise<void> {
704
711
  try {
705
- if (this.Brightness !== this.BrightnessCached) {
712
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges`);
713
+ if (this.Brightness !== this.accessory.context.Brightness) {
706
714
  // Make Push On request to the API
707
715
  const t = Date.now();
708
716
  const nonce = 'requestID';
@@ -711,13 +719,13 @@ export class ColorBulb {
711
719
  .update(Buffer.from(data, 'utf-8'))
712
720
  .digest();
713
721
  const sign = signTerm.toString('base64');
714
- this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
715
- const body = JSON.stringify({
722
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
723
+ const body = superStringify({
716
724
  'command': 'setBrightness',
717
725
  'parameter': `${this.Brightness}`,
718
726
  'commandType': 'command',
719
727
  });
720
- this.infoLog(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
728
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
721
729
  const options = {
722
730
  hostname: HostDomain,
723
731
  port: 443,
@@ -733,117 +741,25 @@ export class ColorBulb {
733
741
  },
734
742
  };
735
743
  const req = https.request(options, res => {
736
- this.debugLog(`Color Bulb: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
744
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges statusCode: ${res.statusCode}`);
737
745
  res.on('data', d => {
738
- this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
746
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
739
747
  });
740
748
  });
741
749
  req.on('error', (e: any) => {
742
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
750
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
743
751
  });
744
752
  req.write(body);
745
753
  req.end();
746
- this.debugLog(`Color Bulb: ${this.accessory.displayName} pushBrightnessChanges: ${JSON.stringify(req)}`);
747
- this.BrightnessCached = this.Brightness;
754
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges: ${superStringify(req)}`);
748
755
  } else {
749
- this.debugLog(
750
- `Color Bulb: ${this.accessory.displayName} No Changes.` + `Brightness: ${this.Brightness}, BrightnessCached: ${this.BrightnessCached}`,
751
- );
756
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushBrightnessChanges.` + `Brightness: ${this.Brightness}, `
757
+ +`BrightnessCached: ${this.accessory.context.Brightness}`);
752
758
  }
753
759
  } catch (e: any) {
754
- this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
755
- if (this.deviceLogging.includes('debug')) {
756
- this.errorLog(
757
- `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
758
- );
759
- }
760
760
  this.apiError(e);
761
- }
762
- }
763
-
764
- async updateHomeKitCharacteristics(): Promise<void> {
765
- if (this.On === undefined) {
766
- this.debugLog(`Color Bulb: ${this.accessory.displayName} On: ${this.On}`);
767
- } else {
768
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, this.On);
769
- this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
770
- }
771
- if (this.Brightness === undefined) {
772
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
773
- } else {
774
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, this.Brightness);
775
- this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
776
- }
777
- if (this.ColorTemperature === undefined) {
778
- this.debugLog(`Color Bulb: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
779
- } else {
780
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, this.ColorTemperature);
781
- this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
782
- }
783
- if (this.Hue === undefined) {
784
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Hue: ${this.Hue}`);
785
- } else {
786
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, this.Hue);
787
- this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Hue: ${this.Hue}`);
788
- }
789
- if (this.Saturation === undefined) {
790
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
791
- } else {
792
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, this.Saturation);
793
- this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Saturation: ${this.Saturation}`);
794
- }
795
- }
796
-
797
- apiError(e: any): void {
798
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, e);
799
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, e);
800
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, e);
801
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, e);
802
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, e);
803
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
804
- }
805
-
806
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
807
- switch (res.statusCode) {
808
- case 151:
809
- this.errorLog(`Color Bulb: ${this.accessory.displayName} Command not supported by this device type.`);
810
- break;
811
- case 152:
812
- this.errorLog(`Color Bulb: ${this.accessory.displayName} Device not found.`);
813
- break;
814
- case 160:
815
- this.errorLog(`Color Bulb: ${this.accessory.displayName} Command is not supported.`);
816
- break;
817
- case 161:
818
- this.errorLog(`Color Bulb: ${this.accessory.displayName} Device is offline.`);
819
- this.offlineOff();
820
- break;
821
- case 171:
822
- this.errorLog(`Color Bulb: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
823
- this.offlineOff();
824
- break;
825
- case 190:
826
- this.errorLog(
827
- `Color Bulb: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
828
- ` Or command: ${JSON.stringify(res)} format is invalid`,
829
- );
830
- break;
831
- case 100:
832
- if (this.platform.debugMode) {
833
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Command successfully sent.`);
834
- }
835
- break;
836
- default:
837
- if (this.platform.debugMode) {
838
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Unknown statusCode.`);
839
- }
840
- }
841
- }
842
-
843
- async offlineOff(): Promise<void> {
844
- if (this.device.offline) {
845
- this.On = false;
846
- this.lightBulbService.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
761
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with ${this.device.connectionType}`
762
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
847
763
  }
848
764
  }
849
765
 
@@ -851,7 +767,7 @@ export class ColorBulb {
851
767
  * Handle requests to set the value of the "On" characteristic
852
768
  */
853
769
  async OnSet(value: CharacteristicValue): Promise<void> {
854
- this.debugLog(`Color Bulb: ${this.accessory.displayName} On: ${value}`);
770
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
855
771
 
856
772
  this.On = value;
857
773
  this.doColorBulbUpdate.next();
@@ -861,7 +777,7 @@ export class ColorBulb {
861
777
  * Handle requests to set the value of the "Brightness" characteristic
862
778
  */
863
779
  async BrightnessSet(value: CharacteristicValue): Promise<void> {
864
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Brightness: ${value}`);
780
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
865
781
 
866
782
  this.Brightness = value;
867
783
  this.doColorBulbUpdate.next();
@@ -871,7 +787,7 @@ export class ColorBulb {
871
787
  * Handle requests to set the value of the "ColorTemperature" characteristic
872
788
  */
873
789
  async ColorTemperatureSet(value: CharacteristicValue): Promise<void> {
874
- this.debugLog(`Color Bulb: ${this.accessory.displayName} ColorTemperature: ${value}`);
790
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ColorTemperature: ${value}`);
875
791
 
876
792
  // Convert mired to kelvin to nearest 100 (SwitchBot seems to need this)
877
793
  const kelvin = Math.round(1000000 / Number(value) / 100) * 100;
@@ -879,7 +795,7 @@ export class ColorBulb {
879
795
  // Check and increase/decrease kelvin to range of device
880
796
  const k = Math.min(Math.max(kelvin, this.minKelvin), this.maxKelvin);
881
797
 
882
- if (!this.OnCached || this.cacheKelvin === k) {
798
+ if (!this.accessory.context.On || this.cacheKelvin === k) {
883
799
  return;
884
800
  }
885
801
 
@@ -896,7 +812,7 @@ export class ColorBulb {
896
812
  * Handle requests to set the value of the "Hue" characteristic
897
813
  */
898
814
  async HueSet(value: CharacteristicValue): Promise<void> {
899
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Hue: ${value}`);
815
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Hue: ${value}`);
900
816
 
901
817
  this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
902
818
 
@@ -908,7 +824,7 @@ export class ColorBulb {
908
824
  * Handle requests to set the value of the "Saturation" characteristic
909
825
  */
910
826
  async SaturationSet(value: CharacteristicValue): Promise<void> {
911
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Saturation: ${value}`);
827
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Saturation: ${value}`);
912
828
 
913
829
  this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
914
830
 
@@ -916,76 +832,199 @@ export class ColorBulb {
916
832
  this.doColorBulbUpdate.next();
917
833
  }
918
834
 
919
- async config(device: device & devicesConfig): Promise<void> {
920
- let config = {};
921
- if (device.colorbulb) {
922
- config = device.colorbulb;
835
+ async updateHomeKitCharacteristics(): Promise<void> {
836
+ if (this.On === undefined) {
837
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
838
+ } else {
839
+ this.accessory.context.On = this.On;
840
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, this.On);
841
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
923
842
  }
924
- if (device.ble) {
925
- config['ble'] = device.ble;
843
+ if (this.Brightness === undefined) {
844
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
845
+ } else {
846
+ this.accessory.context.Brightness = this.Brightness;
847
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, this.Brightness);
848
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
926
849
  }
927
- if (device.logging !== undefined) {
928
- config['logging'] = device.logging;
850
+ if (this.ColorTemperature === undefined) {
851
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
852
+ } else {
853
+ this.accessory.context.ColorTemperature = this.ColorTemperature;
854
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, this.ColorTemperature);
855
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
929
856
  }
930
- if (device.refreshRate !== undefined) {
931
- config['refreshRate'] = device.refreshRate;
857
+ if (this.Hue === undefined) {
858
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
859
+ } else {
860
+ this.accessory.context.Hue = this.Hue;
861
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, this.Hue);
862
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Hue: ${this.Hue}`);
932
863
  }
933
- if (device.scanDuration !== undefined) {
934
- config['scanDuration'] = device.scanDuration;
864
+ if (this.Saturation === undefined) {
865
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
866
+ } else {
867
+ this.accessory.context.Saturation = this.Saturation;
868
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, this.Saturation);
869
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Saturation: ${this.Saturation}`);
935
870
  }
936
- if (device.offline !== undefined) {
937
- config['offline'] = device.offline;
871
+ }
872
+
873
+ async adaptiveLighting(device: device & devicesConfig): Promise<void> {
874
+ if (device.colorbulb?.adaptiveLightingShift) {
875
+ this.adaptiveLightingShift = device.colorbulb.adaptiveLightingShift;
876
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
877
+ } else {
878
+ this.adaptiveLightingShift = 0;
879
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
938
880
  }
939
- if (Object.entries(config).length !== 0) {
940
- this.infoLog(`Color Bulb: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
881
+ }
882
+
883
+ async getCustomBLEAddress(switchbot: any) {
884
+ if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
885
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
886
+ (async () => {
887
+ // Start to monitor advertisement packets
888
+ await switchbot.startScan({
889
+ model: 'u',
890
+ });
891
+ // Set an event handler
892
+ switchbot.onadvertisement = (ad: any) => {
893
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
894
+ };
895
+ await switchbot.wait(10000);
896
+ // Stop to monitor
897
+ switchbot.stopScan();
898
+ })();
941
899
  }
942
900
  }
943
901
 
944
- async refreshRate(device: device & devicesConfig): Promise<void> {
945
- if (device.refreshRate) {
946
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
947
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
948
- } else if (this.platform.config.options!.refreshRate) {
949
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
950
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
902
+ async BLEconnection(switchbot: any): Promise<void> {
903
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
904
+ if (this.platform.config.credentials?.token) {
905
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
906
+ this.SwitchToOpenAPI = true;
907
+ await this.openAPIRefreshStatus();
951
908
  }
952
909
  }
953
910
 
911
+ async turnOnOff(device_list: any): Promise<any> {
912
+ return await this.retry({
913
+ max: await this.maxRetry(),
914
+ fn: () => {
915
+ if (this.On) {
916
+ return device_list[0].turnOn({ id: this.device.bleMac });
917
+ } else {
918
+ return device_list[0].turnOff({ id: this.device.bleMac });
919
+ }
920
+ },
921
+ });
922
+ }
923
+
924
+ async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
925
+ return fn().catch(async (err: any) => {
926
+ if (max === 0) {
927
+ throw err;
928
+ }
929
+ this.infoLog(err);
930
+ this.infoLog('Retrying');
931
+ await this.switchbot.wait(1000);
932
+ return this.retry({ max: max - 1, fn });
933
+ });
934
+ }
935
+
936
+ async maxRetry(): Promise<number> {
937
+ let maxRetry: number;
938
+ if (this.device.bot?.maxRetry) {
939
+ maxRetry = this.device.bot?.maxRetry;
940
+ } else {
941
+ maxRetry = 5;
942
+ }
943
+ return maxRetry;
944
+ }
945
+
946
+ minStep(device: device & devicesConfig): number {
947
+ if (device.colorbulb?.set_minStep) {
948
+ this.set_minStep = device.colorbulb?.set_minStep;
949
+ } else {
950
+ this.set_minStep = 1;
951
+ }
952
+ return this.set_minStep;
953
+ }
954
+
954
955
  async scan(device: device & devicesConfig): Promise<void> {
955
956
  if (device.scanDuration) {
956
957
  this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
957
- if (device.ble) {
958
- this.debugLog(`Bot: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
958
+ if (this.BLE) {
959
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
959
960
  }
960
961
  } else {
961
962
  this.scanDuration = this.accessory.context.scanDuration = 1;
962
- if (this.device.ble) {
963
- this.debugLog(`Bot: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
963
+ if (this.BLE) {
964
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
964
965
  }
965
966
  }
966
967
  }
967
968
 
968
- async logs(device: device & devicesConfig): Promise<void> {
969
- if (this.platform.debugMode) {
970
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
971
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
972
- } else if (device.logging) {
973
- this.deviceLogging = this.accessory.context.logging = device.logging;
974
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
975
- } else if (this.platform.config.options?.logging) {
976
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
977
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
978
- } else {
979
- this.deviceLogging = this.accessory.context.logging = 'standard';
980
- this.debugLog(`Color Bulb: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
969
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
970
+ switch (res.statusCode) {
971
+ case 151:
972
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
973
+ break;
974
+ case 152:
975
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
976
+ break;
977
+ case 160:
978
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
979
+ break;
980
+ case 161:
981
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
982
+ this.offlineOff();
983
+ break;
984
+ case 171:
985
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
986
+ this.offlineOff();
987
+ break;
988
+ case 190:
989
+ this.errorLog(
990
+ `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
991
+ ` Or command: ${superStringify(res)} format is invalid`,
992
+ );
993
+ break;
994
+ case 100:
995
+ if (this.platform.debugMode) {
996
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
997
+ }
998
+ break;
999
+ default:
1000
+ if (this.platform.debugMode) {
1001
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
1002
+ }
981
1003
  }
982
1004
  }
983
1005
 
1006
+ async offlineOff(): Promise<void> {
1007
+ if (this.device.offline) {
1008
+ this.On = false;
1009
+ this.lightBulbService.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
1010
+ await this.updateHomeKitCharacteristics();
1011
+ }
1012
+ }
1013
+
1014
+ apiError(e: any): void {
1015
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, e);
1016
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, e);
1017
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, e);
1018
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, e);
1019
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, e);
1020
+ }
1021
+
984
1022
  FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
985
1023
  let FirmwareRevision: string;
986
- this.debugLog(`Color Bulb: ${this.accessory.displayName} accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
987
- this.debugLog(`Color Bulb: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
988
- this.debugLog(`Color Bulb: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
1024
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
1025
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
1026
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
1027
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
989
1028
  if (accessory.context.FirmwareRevision) {
990
1029
  FirmwareRevision = accessory.context.FirmwareRevision;
991
1030
  } else if (device.firmware) {
@@ -996,23 +1035,85 @@ export class ColorBulb {
996
1035
  return FirmwareRevision;
997
1036
  }
998
1037
 
999
- async adaptiveLighting(device: device & devicesConfig): Promise<void> {
1000
- if (device.colorbulb?.adaptiveLightingShift) {
1001
- this.adaptiveLightingShift = device.colorbulb.adaptiveLightingShift;
1002
- this.debugLog(`Color Bulb: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
1038
+ private context() {
1039
+ if (this.On === undefined) {
1040
+ this.On = false;
1003
1041
  } else {
1004
- this.adaptiveLightingShift = 0;
1005
- this.debugLog(`Color Bulb: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
1042
+ this.On = this.accessory.context.On;
1043
+ }
1044
+ if (this.Hue === undefined) {
1045
+ this.Hue = 0;
1046
+ } else {
1047
+ this.Hue = this.accessory.context.Hue;
1048
+ }
1049
+ if (this.Brightness === undefined) {
1050
+ this.Brightness = 0;
1051
+ } else {
1052
+ this.Brightness = this.accessory.context.Brightness;
1053
+ }
1054
+ if (this.Brightness === undefined) {
1055
+ this.Saturation = 0;
1056
+ } else {
1057
+ this.Saturation = this.accessory.context.Saturation;
1058
+ }
1059
+ if (this.ColorTemperature === undefined) {
1060
+ this.ColorTemperature = 140;
1061
+ } else {
1062
+ this.ColorTemperature = this.accessory.context.ColorTemperature;
1006
1063
  }
1064
+ this.minKelvin = 2000;
1065
+ this.maxKelvin = 9000;
1007
1066
  }
1008
1067
 
1009
- minStep(device: device & devicesConfig): number {
1010
- if (device.colorbulb?.set_minStep) {
1011
- this.set_minStep = device.colorbulb?.set_minStep;
1068
+ async refreshRate(device: device & devicesConfig): Promise<void> {
1069
+ if (device.refreshRate) {
1070
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
1071
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
1072
+ } else if (this.platform.config.options!.refreshRate) {
1073
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
1074
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
1075
+ }
1076
+ }
1077
+
1078
+ async config(device: device & devicesConfig): Promise<void> {
1079
+ let config = {};
1080
+ if (device.colorbulb) {
1081
+ config = device.colorbulb;
1082
+ }
1083
+ if (device.connectionType !== undefined) {
1084
+ config['connectionType'] = device.connectionType;
1085
+ }
1086
+ if (device.logging !== undefined) {
1087
+ config['logging'] = device.logging;
1088
+ }
1089
+ if (device.refreshRate !== undefined) {
1090
+ config['refreshRate'] = device.refreshRate;
1091
+ }
1092
+ if (device.scanDuration !== undefined) {
1093
+ config['scanDuration'] = device.scanDuration;
1094
+ }
1095
+ if (device.offline !== undefined) {
1096
+ config['offline'] = device.offline;
1097
+ }
1098
+ if (Object.entries(config).length !== 0) {
1099
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
1100
+ }
1101
+ }
1102
+
1103
+ async logs(device: device & devicesConfig): Promise<void> {
1104
+ if (this.platform.debugMode) {
1105
+ this.deviceLogging = this.accessory.context.logging = 'debugMode';
1106
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
1107
+ } else if (device.logging) {
1108
+ this.deviceLogging = this.accessory.context.logging = device.logging;
1109
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
1110
+ } else if (this.platform.config.options?.logging) {
1111
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
1112
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
1012
1113
  } else {
1013
- this.set_minStep = 1;
1114
+ this.deviceLogging = this.accessory.context.logging = 'standard';
1115
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
1014
1116
  }
1015
- return this.set_minStep;
1016
1117
  }
1017
1118
 
1018
1119
  /**