@switchbot/homebridge-switchbot 2.0.0-beta.4 → 2.0.0-beta.41

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