@switchbot/homebridge-switchbot 2.0.0-beta.9 → 2.0.0

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