@switchbot/homebridge-switchbot 2.0.0-beta.19 → 2.0.0-beta.20

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 (112) hide show
  1. package/CHANGELOG.md +6 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +51 -32
  4. package/dist/device/bot.d.ts +32 -29
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +549 -575
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +33 -15
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +426 -341
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +16 -9
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +246 -208
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +21 -18
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +449 -449
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +22 -20
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +346 -324
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +22 -10
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +257 -178
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +21 -14
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +287 -239
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +23 -10
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +308 -190
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +17 -10
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +225 -193
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +24 -17
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +270 -267
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +36 -14
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +447 -299
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +7 -14
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +177 -169
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +3 -5
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +72 -57
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +3 -4
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +47 -33
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +3 -4
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +66 -48
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +3 -4
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +48 -47
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +3 -4
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +47 -33
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +10 -11
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +64 -48
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +7 -12
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +52 -41
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +6 -11
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +52 -42
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +0 -4
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +44 -66
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +3 -3
  89. package/dist/settings.d.ts.map +1 -1
  90. package/package.json +7 -6
  91. package/src/device/bot.ts +551 -589
  92. package/src/device/colorbulb.ts +441 -375
  93. package/src/device/contact.ts +249 -213
  94. package/src/device/curtain.ts +452 -461
  95. package/src/device/humidifier.ts +358 -365
  96. package/src/device/lock.ts +263 -179
  97. package/src/device/meter.ts +302 -253
  98. package/src/device/meterplus.ts +319 -194
  99. package/src/device/motion.ts +230 -199
  100. package/src/device/plug.ts +273 -274
  101. package/src/device/striplight.ts +460 -316
  102. package/src/irdevice/airconditioner.ts +181 -183
  103. package/src/irdevice/airpurifier.ts +70 -60
  104. package/src/irdevice/camera.ts +46 -36
  105. package/src/irdevice/fan.ts +64 -49
  106. package/src/irdevice/light.ts +47 -51
  107. package/src/irdevice/other.ts +46 -36
  108. package/src/irdevice/tv.ts +64 -51
  109. package/src/irdevice/vacuumcleaner.ts +52 -45
  110. package/src/irdevice/waterheater.ts +50 -45
  111. package/src/platform.ts +44 -68
  112. package/src/settings.ts +3 -3
@@ -23,6 +23,7 @@ export class StripLight {
23
23
  Hue!: CharacteristicValue;
24
24
  Saturation!: CharacteristicValue;
25
25
  Brightness!: CharacteristicValue;
26
+ ColorTemperature?: CharacteristicValue;
26
27
 
27
28
  // OpenAPI Others
28
29
  power: deviceStatus['power'];
@@ -46,7 +47,6 @@ export class StripLight {
46
47
  deviceLogging!: string;
47
48
  deviceRefreshRate!: number;
48
49
  adaptiveLightingShift?: number;
49
- OpenAPI?: boolean;
50
50
 
51
51
  // Adaptive Lighting
52
52
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
@@ -60,23 +60,17 @@ export class StripLight {
60
60
  stripLightUpdateInProgress!: boolean;
61
61
  doStripLightUpdate!: Subject<void>;
62
62
 
63
+ // Connection
64
+ private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'Both');
65
+ private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'Both');
66
+
63
67
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
64
68
  // default placeholders
65
69
  this.logs(device);
66
- this.openAPI();
67
70
  this.scan(device);
68
71
  this.refreshRate(device);
69
72
  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.minKelvin = 2000;
79
- this.maxKelvin = 9000;
73
+ this.context();
80
74
  // this is subject we use to track when we need to POST changes to the SwitchBot API
81
75
  this.doStripLightUpdate = new Subject();
82
76
  this.stripLightUpdateInProgress = false;
@@ -97,7 +91,15 @@ export class StripLight {
97
91
  // get the Lightbulb service if it exists, otherwise create a new Lightbulb service
98
92
  // you can create multiple services for each accessory
99
93
  (this.lightBulbService = accessory.getService(this.platform.Service.Lightbulb) || accessory.addService(this.platform.Service.Lightbulb)),
100
- `${accessory.displayName} Strip Light`;
94
+ `${accessory.displayName} ${device.deviceType}`;
95
+
96
+
97
+ /*if (this.adaptiveLightingShift === -1 && this.accessory.context.adaptiveLighting) {
98
+ this.accessory.removeService(this.lightBulbService);
99
+ this.lightBulbService = this.accessory.addService(this.platform.Service.Lightbulb);
100
+ this.accessory.context.adaptiveLighting = false;
101
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting}`);
102
+ }*/
101
103
 
102
104
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
103
105
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
@@ -150,6 +152,19 @@ export class StripLight {
150
152
  })
151
153
  .onSet(this.SaturationSet.bind(this));
152
154
 
155
+ /*this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
156
+ if (this.adaptiveLightingShift !== -1) {
157
+ this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.lightBulbService, {
158
+ customTemperatureAdjustment: this.adaptiveLightingShift,
159
+ });
160
+ this.accessory.configureController(this.AdaptiveLightingController);
161
+ this.accessory.context.adaptiveLighting = true;
162
+ this.debugLog(
163
+ `${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting},` +
164
+ ` adaptiveLightingShift: ${this.adaptiveLightingShift}`,
165
+ );
166
+ }*/
167
+
153
168
  // Update Homekit
154
169
  this.updateHomeKitCharacteristics();
155
170
 
@@ -161,7 +176,7 @@ export class StripLight {
161
176
  });
162
177
 
163
178
  // Watch for Bulb change events
164
- // We put in a debounce of 100ms so we don't make duplicate calls
179
+ // We put in a debounce of 1000ms so we don't make duplicate calls
165
180
  this.doStripLightUpdate
166
181
  .pipe(
167
182
  tap(() => {
@@ -173,12 +188,9 @@ export class StripLight {
173
188
  try {
174
189
  await this.pushChanges();
175
190
  } catch (e: any) {
176
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges`);
177
- if (this.deviceLogging.includes('debug')) {
178
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges,`
179
- + ` Error Message: ${superStringify(e.message)}`);
180
- }
181
191
  this.apiError(e);
192
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
193
+ + ` Error Message: ${superStringify(e.message)}`);
182
194
  }
183
195
  this.stripLightUpdateInProgress = false;
184
196
  // Refresh the status from the API
@@ -191,16 +203,23 @@ export class StripLight {
191
203
  });
192
204
  }
193
205
 
206
+ /**
207
+ * Parse the device status from the SwitchBot api
208
+ */
194
209
  async parseStatus(): Promise<void> {
195
- if (this.SwitchToOpenAPI || !this.device.ble) {
210
+ /*if (this.BLE && !this.SwitchToOpenAPI) {
211
+ await this.BLEparseStatus();
212
+ } else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
213
+ this.SwitchToOpenAPI = false;
196
214
  await this.openAPIparseStatus();
197
215
  } else {
198
- await this.BLEparseStatus();
216
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
217
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
199
218
  }
200
219
  }
201
220
 
202
221
  async BLEparseStatus(): Promise<void> {
203
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE parseStatus`);
222
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
204
223
  // State
205
224
  switch (this.state) {
206
225
  case 'on':
@@ -213,6 +232,7 @@ export class StripLight {
213
232
  }
214
233
 
215
234
  async openAPIparseStatus(): Promise<void> {
235
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
216
236
  switch (this.power) {
217
237
  case 'on':
218
238
  this.On = true;
@@ -248,16 +268,22 @@ export class StripLight {
248
268
  }
249
269
  }
250
270
 
271
+ /**
272
+ * Asks the SwitchBot API for the latest device information
273
+ */
251
274
  async refreshStatus(): Promise<void> {
252
- if (this.device.ble) {
275
+ /*if (this.BLE) {
253
276
  await this.BLERefreshStatus();
254
- } else {
277
+ } else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
255
278
  await this.openAPIRefreshStatus();
279
+ } else {
280
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
281
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
256
282
  }
257
283
  }
258
284
 
259
285
  async BLERefreshStatus(): Promise<void> {
260
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE refreshStatus`);
286
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
261
287
  const switchbot = await this.platform.connectBLE();
262
288
  // Convert to BLE Address
263
289
  this.device.bleMac = this.device
@@ -317,214 +343,218 @@ export class StripLight {
317
343
  this.parseStatus();
318
344
  this.updateHomeKitCharacteristics();
319
345
  } else {
320
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
321
- if (this.platform.config.credentials?.token) {
322
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
323
- this.SwitchToOpenAPI = true;
324
- await this.openAPIRefreshStatus();
325
- }
346
+ await this.BLEconnection(switchbot);
326
347
  }
327
348
  })
328
349
  .catch(async (e: any) => {
329
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
330
- if (this.deviceLogging.includes('debug')) {
331
- this.errorLog(
332
- `${this.device.deviceType}: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
333
- + ` Error Message: ${superStringify(e.message)}`,
334
- );
335
- }
336
- if (this.platform.config.credentials?.token) {
337
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
338
- this.SwitchToOpenAPI = true;
339
- await this.openAPIRefreshStatus();
340
- }
341
350
  this.apiError(e);
351
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
352
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
353
+ await this.BLEconnection(switchbot);
342
354
  });
343
355
  } else {
344
356
  await this.BLEconnection(switchbot);
345
357
  }
346
358
  }
347
359
 
348
- async getCustomBLEAddress(switchbot: any) {
349
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
350
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
351
- (async () => {
352
- // Start to monitor advertisement packets
353
- await switchbot.startScan({
354
- model: 'r',
360
+ async openAPIRefreshStatus(): Promise<void> {
361
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
362
+ try {
363
+ const t = Date.now();
364
+ const nonce = 'requestID';
365
+ const data = this.platform.config.credentials?.token + t + nonce;
366
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
367
+ const sign = signTerm.toString('base64');
368
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
369
+ const options = {
370
+ hostname: HostDomain,
371
+ port: 443,
372
+ path: `${DevicePath}/${this.device.deviceId}/status`,
373
+ method: 'GET',
374
+ headers: {
375
+ Authorization: this.platform.config.credentials?.token,
376
+ sign: sign,
377
+ nonce: nonce,
378
+ t: t,
379
+ 'Content-Type': 'application/json',
380
+ },
381
+ };
382
+ const req = https.request(options, (res) => {
383
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
384
+ this.statusCode({ res });
385
+ let rawData = '';
386
+ res.on('data', (d) => {
387
+ rawData += d;
388
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
355
389
  });
356
- // Set an event handler
357
- switchbot.onadvertisement = (ad: any) => {
358
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
359
- };
360
- await switchbot.wait(10000);
361
- // Stop to monitor
362
- switchbot.stopScan();
363
- })();
390
+ res.on('end', () => {
391
+ try {
392
+ this.deviceStatus = JSON.parse(rawData);
393
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
394
+ this.power = this.deviceStatus.body.power;
395
+ this.color = this.deviceStatus.body.color;
396
+ this.brightness = this.deviceStatus.body.brightness;
397
+ this.parseStatus();
398
+ this.updateHomeKitCharacteristics();
399
+ } catch (e: any) {
400
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
401
+ }
402
+ });
403
+ });
404
+ req.on('error', (e: any) => {
405
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
406
+ });
407
+ req.end();
408
+ } catch (e: any) {
409
+ this.apiError(e);
410
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
411
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
364
412
  }
365
413
  }
366
414
 
367
- async BLEconnection(switchbot: any): Promise<void> {
368
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
369
- if (this.platform.config.credentials?.token) {
370
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
371
- this.SwitchToOpenAPI = true;
372
- await this.openAPIRefreshStatus();
415
+ /**
416
+ * Pushes the requested changes to the SwitchBot API
417
+ * deviceType commandType Command command parameter Description
418
+ * Strip Light - "command" "turnOn" "default" = set to ON state |
419
+ * Strip Light - "command" "turnOff" "default" = set to OFF state |
420
+ * Strip Light - "command" "toggle" "default" = toggle state |
421
+ * Strip Light - "command" "setBrightness" "`{1-100}`" = set brightness |
422
+ * Strip Light - "command" "setColor" "`"{0-255}:{0-255}:{0-255}"`" = set RGB color value |
423
+ *
424
+ */
425
+ async pushChanges(): Promise<void> {
426
+ /*if (this.BLE) {
427
+ await this.BLERefreshStatus();
428
+ } else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
429
+ await this.openAPIpushChanges();
430
+ } else {
431
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
432
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
373
433
  }
434
+ interval(5000)
435
+ .pipe(take(1))
436
+ .subscribe(async () => {
437
+ await this.refreshStatus();
438
+ });
374
439
  }
375
440
 
376
- async openAPIRefreshStatus(): Promise<void> {
377
- if (this.OpenAPI) {
378
- try {
441
+ async BLEpushChanges(): Promise<void> {
442
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
443
+ if (this.On !== this.accessory.context.On) {
444
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${this.On} OnCached: ${this.accessory.context.On}`);
445
+ const switchbot = await this.platform.connectBLE();
446
+ // Convert to BLE Address
447
+ this.device.bleMac = this.device
448
+ .deviceId!.match(/.{1,2}/g)!
449
+ .join(':')
450
+ .toLowerCase();
451
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
452
+ switchbot
453
+ .discover({
454
+ model: 'r',
455
+ id: this.device.bleMac,
456
+ })
457
+ .then((device_list: any) => {
458
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
459
+ return this.turnOnOff(device_list);
460
+ })
461
+ .then(() => {
462
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
463
+ this.On = false;
464
+ })
465
+ .catch(async (e: any) => {
466
+ this.apiError(e);
467
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
468
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
469
+ if (this.platform.config.credentials?.token && this.device.connectionType !== 'Both') {
470
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
471
+ await this.openAPIpushChanges();
472
+ }
473
+ });
474
+ } else {
475
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, `
476
+ +`OnCached: ${this.accessory.context.On}`);
477
+ }
478
+ }
479
+
480
+ async openAPIpushChanges() {
481
+ try {
482
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
483
+ if (this.On !== this.accessory.context.On) {
484
+ // Make Push On request to the API
379
485
  const t = Date.now();
380
486
  const nonce = 'requestID';
381
487
  const data = this.platform.config.credentials?.token + t + nonce;
382
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
488
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
489
+ .update(Buffer.from(data, 'utf-8'))
490
+ .digest();
383
491
  const sign = signTerm.toString('base64');
384
492
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
493
+
494
+ let command = '';
495
+ if (this.On) {
496
+ command = 'turnOn';
497
+ } else {
498
+ command = 'turnOff';
499
+ }
500
+ const body = superStringify({
501
+ 'command': `${command}`,
502
+ 'parameter': 'default',
503
+ 'commandType': 'command',
504
+ });
505
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
385
506
  const options = {
386
507
  hostname: HostDomain,
387
508
  port: 443,
388
- path: `${DevicePath}/${this.device.deviceId}/status`,
389
- method: 'GET',
509
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
510
+ method: 'POST',
390
511
  headers: {
391
- Authorization: this.platform.config.credentials?.token,
392
- sign: sign,
393
- nonce: nonce,
394
- t: t,
512
+ 'Authorization': this.platform.config.credentials?.token,
513
+ 'sign': sign,
514
+ 'nonce': nonce,
515
+ 't': t,
395
516
  'Content-Type': 'application/json',
517
+ 'Content-Length': body.length,
396
518
  },
397
519
  };
398
- const req = https.request(options, (res) => {
399
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
400
- let rawData = '';
401
- res.on('data', (d) => {
402
- rawData += d;
520
+ const req = https.request(options, res => {
521
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
522
+ this.statusCode({ res });
523
+ res.on('data', d => {
403
524
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
404
525
  });
405
- res.on('end', () => {
406
- try {
407
- this.deviceStatus = JSON.parse(rawData);
408
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${superStringify(this.deviceStatus)}`);
409
- this.power = this.deviceStatus.body.power;
410
- this.color = this.deviceStatus.body.color;
411
- this.brightness = this.deviceStatus.body.brightness;
412
- this.parseStatus();
413
- this.updateHomeKitCharacteristics();
414
- } catch (e: any) {
415
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
416
- }
417
- });
418
526
  });
419
527
  req.on('error', (e: any) => {
420
528
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
421
529
  });
530
+ req.write(body);
422
531
  req.end();
423
- } catch (e: any) {
424
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
425
- if (this.deviceLogging.includes('debug')) {
426
- this.errorLog(
427
- `${this.device.deviceType}: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
428
- + ` Error Message: ${superStringify(e.message)}`,
429
- );
430
- }
431
- this.apiError(e);
532
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges: ${superStringify(req)}`);
533
+ } else {
534
+ this.debugLog(
535
+ `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `On: ${this.On}, `
536
+ +`OnCached: ${this.accessory.context.On}`,
537
+ );
432
538
  }
433
- } else {
434
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI is disabled, commands will not be sent.`);
435
- }
436
- }
437
-
438
- /**
439
- * Pushes the requested changes to the SwitchBot API
440
- * deviceType commandType Command command parameter Description
441
- * Strip Light - "command" "turnOn" "default" = set to ON state |
442
- * Strip Light - "command" "turnOff" "default" = set to OFF state |
443
- * Strip Light - "command" "toggle" "default" = toggle state |
444
- * Strip Light - "command" "setBrightness" "`{1-100}`" = set brightness |
445
- * Strip Light - "command" "setColor" "`"{0-255}:{0-255}:{0-255}"`" = set RGB color value |
446
- *
447
- */
448
- async pushChanges(): Promise<void> {
449
- if (this.OpenAPI) {
450
- try {
451
- if (this.On !== this.accessory.context.On) {
452
- // Make Push On request to the API
453
- const t = Date.now();
454
- const nonce = 'requestID';
455
- const data = this.platform.config.credentials?.token + t + nonce;
456
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
457
- .update(Buffer.from(data, 'utf-8'))
458
- .digest();
459
- const sign = signTerm.toString('base64');
460
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
461
-
462
- let command = '';
463
- if (this.On) {
464
- command = 'turnOn';
465
- } else {
466
- command = 'turnOff';
467
- }
468
- const body = superStringify({
469
- 'command': `${command}`,
470
- 'parameter': 'default',
471
- 'commandType': 'command',
472
- });
473
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
474
- const options = {
475
- hostname: HostDomain,
476
- port: 443,
477
- path: `${DevicePath}/${this.device.deviceId}/commands`,
478
- method: 'POST',
479
- headers: {
480
- 'Authorization': this.platform.config.credentials?.token,
481
- 'sign': sign,
482
- 'nonce': nonce,
483
- 't': t,
484
- 'Content-Type': 'application/json',
485
- 'Content-Length': body.length,
486
- },
487
- };
488
- const req = https.request(options, res => {
489
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
490
- this.statusCode({ res });
491
- res.on('data', d => {
492
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
493
- });
494
- });
495
- req.on('error', (e: any) => {
496
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
497
- });
498
- req.write(body);
499
- req.end();
500
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
501
- }
502
- // Push Brightness Update
503
- if (this.On) {
504
- await this.pushBrightnessChanges();
505
- }
506
-
507
- // Push Hue & Saturation Update
508
- if (this.On) {
509
- await this.pushHueSaturationChanges();
510
- }
511
- } catch (e: any) {
512
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
513
- if (this.deviceLogging.includes('debug')) {
514
- this.errorLog(
515
- `${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
516
- + ` Error Message: ${superStringify(e.message)}`,
517
- );
518
- }
519
- this.apiError(e);
539
+ // Push Brightness Update
540
+ if (this.On) {
541
+ await this.pushBrightnessChanges();
520
542
  }
521
- } else {
522
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI is disabled, commands will not be sent.`);
543
+ // Push Hue & Saturation Update
544
+ if (this.On) {
545
+ await this.pushHueSaturationChanges();
546
+ }
547
+ } catch (e: any) {
548
+ this.apiError(e);
549
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
550
+ + ` Connection, Error Message: ${superStringify(e.message)}`,
551
+ );
523
552
  }
524
553
  }
525
554
 
526
555
  async pushHueSaturationChanges(): Promise<void> {
527
556
  try {
557
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges`);
528
558
  if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
529
559
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${superStringify(this.Hue)}`);
530
560
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${superStringify(this.Saturation)}`);
@@ -561,7 +591,7 @@ export class StripLight {
561
591
  },
562
592
  };
563
593
  const req = https.request(options, res => {
564
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
594
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges statusCode: ${res.statusCode}`);
565
595
  this.statusCode({ res });
566
596
  res.on('data', d => {
567
597
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
@@ -574,26 +604,19 @@ export class StripLight {
574
604
  req.end();
575
605
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges: ${superStringify(req)}`);
576
606
  } else {
577
- this.debugLog(
578
- `${this.device.deviceType}: ${this.accessory.displayName} No Changes.` +
579
- `Hue: ${this.Hue}, HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation}, `
580
- +`SaturationCached: ${this.accessory.context.Saturation}`,
581
- );
607
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushHueSaturationChanges. Hue: ${this.Hue}, `
608
+ + `HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`);
582
609
  }
583
610
  } catch (e: any) {
584
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushHueSaturationChanges with OpenAPI Connection`);
585
- if (this.deviceLogging.includes('debug')) {
586
- this.errorLog(
587
- `${this.device.deviceType}: ${this.accessory.displayName} failed pushHueSaturationChanges with OpenAPI Connection,`
588
- + ` Error Message: ${superStringify(e.message)}`,
589
- );
590
- }
591
611
  this.apiError(e);
612
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushHueSaturationChanges with ${this.device.connectionType}`
613
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
592
614
  }
593
615
  }
594
616
 
595
617
  async pushBrightnessChanges(): Promise<void> {
596
618
  try {
619
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges`);
597
620
  if (this.Brightness !== this.accessory.context.Brightness) {
598
621
  // Make Push On request to the API
599
622
  const t = Date.now();
@@ -625,7 +648,7 @@ export class StripLight {
625
648
  },
626
649
  };
627
650
  const req = https.request(options, res => {
628
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
651
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges statusCode: ${res.statusCode}`);
629
652
  this.statusCode({ res });
630
653
  res.on('data', d => {
631
654
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
@@ -638,21 +661,83 @@ export class StripLight {
638
661
  req.end();
639
662
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges: ${superStringify(req)}`);
640
663
  } else {
641
- this.debugLog(
642
- `${this.device.deviceType}: ${this.accessory.displayName} No Changes.` + `Brightness: ${this.Brightness}, `
643
- +`BrightnessCached: ${this.accessory.context.Brightness}`,
644
- );
664
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushBrightnessChanges.` + `Brightness: ${this.Brightness}, `
665
+ +`BrightnessCached: ${this.accessory.context.Brightness}`);
645
666
  }
646
667
  } catch (e: any) {
647
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with OpenAPI Connection`);
648
- if (this.deviceLogging.includes('debug')) {
649
- this.errorLog(
650
- `${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with OpenAPI Connection,`
651
- + ` Error Message: ${superStringify(e.message)}`,
652
- );
653
- }
654
668
  this.apiError(e);
669
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with ${this.device.connectionType}`
670
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
671
+ }
672
+ }
673
+
674
+ /**
675
+ * Handle requests to set the value of the "On" characteristic
676
+ */
677
+ async OnSet(value: CharacteristicValue): Promise<void> {
678
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
679
+
680
+ this.On = value;
681
+ this.doStripLightUpdate.next();
682
+ }
683
+
684
+ /**
685
+ * Handle requests to set the value of the "Brightness" characteristic
686
+ */
687
+ async BrightnessSet(value: CharacteristicValue): Promise<void> {
688
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
689
+
690
+ this.Brightness = value;
691
+ this.doStripLightUpdate.next();
692
+ }
693
+
694
+ /**
695
+ * Handle requests to set the value of the "ColorTemperature" characteristic
696
+ */
697
+ /*async ColorTemperatureSet(value: CharacteristicValue): Promise<void> {
698
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${value}`);
699
+
700
+ // Convert mired to kelvin to nearest 100 (SwitchBot seems to need this)
701
+ const kelvin = Math.round(1000000 / Number(value) / 100) * 100;
702
+
703
+ // Check and increase/decrease kelvin to range of device
704
+ const k = Math.min(Math.max(kelvin, this.minKelvin), this.maxKelvin);
705
+
706
+ if (!this.accessory.context.On || this.cacheKelvin === k) {
707
+ return;
655
708
  }
709
+
710
+ // Updating the hue/sat to the corresponding values mimics native adaptive lighting
711
+ const hs = m2hs(value);
712
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, hs[0]);
713
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, hs[1]);
714
+
715
+ this.ColorTemperature = value;
716
+ this.doColorBulbUpdate.next();
717
+ }*/
718
+
719
+ /**
720
+ * Handle requests to set the value of the "Hue" characteristic
721
+ */
722
+ async HueSet(value: CharacteristicValue): Promise<void> {
723
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Hue: ${value}`);
724
+
725
+ //this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
726
+
727
+ this.Hue = value;
728
+ this.doStripLightUpdate.next();
729
+ }
730
+
731
+ /**
732
+ * Handle requests to set the value of the "Saturation" characteristic
733
+ */
734
+ async SaturationSet(value: CharacteristicValue): Promise<void> {
735
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Saturation: ${value}`);
736
+
737
+ //this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
738
+
739
+ this.Saturation = value;
740
+ this.doStripLightUpdate.next();
656
741
  }
657
742
 
658
743
  async updateHomeKitCharacteristics(): Promise<void> {
@@ -670,6 +755,14 @@ export class StripLight {
670
755
  this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, this.Brightness);
671
756
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
672
757
  }
758
+ /*
759
+ if (this.ColorTemperature === undefined) {
760
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
761
+ } else {
762
+ this.accessory.context.ColorTemperature = this.ColorTemperature;
763
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, this.ColorTemperature);
764
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
765
+ }*/
673
766
  if (this.Hue === undefined) {
674
767
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
675
768
  } else {
@@ -686,12 +779,100 @@ export class StripLight {
686
779
  }
687
780
  }
688
781
 
689
- apiError(e: any): void {
690
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, e);
691
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, e);
692
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, e);
693
- this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, e);
694
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
782
+ async getCustomBLEAddress(switchbot: any) {
783
+ if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
784
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
785
+ (async () => {
786
+ // Start to monitor advertisement packets
787
+ await switchbot.startScan({
788
+ model: 'r',
789
+ });
790
+ // Set an event handler
791
+ switchbot.onadvertisement = (ad: any) => {
792
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
793
+ };
794
+ await switchbot.wait(10000);
795
+ // Stop to monitor
796
+ switchbot.stopScan();
797
+ })();
798
+ }
799
+ }
800
+
801
+ async BLEconnection(switchbot: any): Promise<void> {
802
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
803
+ if (this.platform.config.credentials?.token && this.device.connectionType !== 'Both') {
804
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
805
+ this.SwitchToOpenAPI = true;
806
+ await this.openAPIRefreshStatus();
807
+ }
808
+ }
809
+
810
+ async turnOnOff(device_list: any): Promise<any> {
811
+ return await this.retry({
812
+ max: await this.maxRetry(),
813
+ fn: () => {
814
+ if (this.On) {
815
+ return device_list[0].turnOn({ id: this.device.bleMac });
816
+ } else {
817
+ return device_list[0].turnOff({ id: this.device.bleMac });
818
+ }
819
+ },
820
+ });
821
+ }
822
+
823
+ async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
824
+ return fn().catch(async (err: any) => {
825
+ if (max === 0) {
826
+ throw err;
827
+ }
828
+ this.infoLog(err);
829
+ this.infoLog('Retrying');
830
+ await this.switchbot.wait(1000);
831
+ return this.retry({ max: max - 1, fn });
832
+ });
833
+ }
834
+
835
+ async maxRetry(): Promise<number> {
836
+ let maxRetry: number;
837
+ if (this.device.bot?.maxRetry) {
838
+ maxRetry = this.device.bot?.maxRetry;
839
+ } else {
840
+ maxRetry = 5;
841
+ }
842
+ return maxRetry;
843
+ }
844
+
845
+ minStep(device: device & devicesConfig): number {
846
+ if (device.colorbulb?.set_minStep) {
847
+ this.set_minStep = device.colorbulb?.set_minStep;
848
+ } else {
849
+ this.set_minStep = 1;
850
+ }
851
+ return this.set_minStep;
852
+ }
853
+
854
+ /*async adaptiveLighting(device: device & devicesConfig): Promise<void> {
855
+ if (device.colorbulb?.adaptiveLightingShift) {
856
+ this.adaptiveLightingShift = device.colorbulb.adaptiveLightingShift;
857
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
858
+ } else {
859
+ this.adaptiveLightingShift = 0;
860
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
861
+ }
862
+ }*/
863
+
864
+ async scan(device: device & devicesConfig): Promise<void> {
865
+ if (device.scanDuration) {
866
+ this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
867
+ if (this.BLE) {
868
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
869
+ }
870
+ } else {
871
+ this.scanDuration = this.accessory.context.scanDuration = 1;
872
+ if (this.BLE) {
873
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
874
+ }
875
+ }
695
876
  }
696
877
 
697
878
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
@@ -735,47 +916,71 @@ export class StripLight {
735
916
  if (this.device.offline) {
736
917
  this.On = false;
737
918
  this.lightBulbService.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
919
+ await this.updateHomeKitCharacteristics();
738
920
  }
739
921
  }
740
922
 
741
- /**
742
- * Handle requests to set the value of the "On" characteristic
743
- */
744
- async OnSet(value: CharacteristicValue): Promise<void> {
745
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${value}`);
746
-
747
- this.On = value;
748
- this.doStripLightUpdate.next();
923
+ apiError(e: any): void {
924
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, e);
925
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, e);
926
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, e);
927
+ this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, e);
749
928
  }
750
929
 
751
- /**
752
- * Handle requests to set the value of the "Brightness" characteristic
753
- */
754
- async BrightnessSet(value: CharacteristicValue): Promise<void> {
755
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${value}`);
756
-
757
- this.Brightness = value;
758
- this.doStripLightUpdate.next();
930
+ FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
931
+ let FirmwareRevision: string;
932
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
933
+ +`accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
934
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
935
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
936
+ if (accessory.context.FirmwareRevision) {
937
+ FirmwareRevision = accessory.context.FirmwareRevision;
938
+ } else if (device.firmware) {
939
+ FirmwareRevision = device.firmware;
940
+ } else {
941
+ FirmwareRevision = this.platform.version;
942
+ }
943
+ return FirmwareRevision;
759
944
  }
760
945
 
761
- /**
762
- * Handle requests to set the value of the "Hue" characteristic
763
- */
764
- async HueSet(value: CharacteristicValue): Promise<void> {
765
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${value}`);
766
-
767
- this.Hue = value;
768
- this.doStripLightUpdate.next();
946
+ async context() {
947
+ if (this.On === undefined) {
948
+ this.On = false;
949
+ } else {
950
+ this.On = this.accessory.context.On;
951
+ }
952
+ if (this.Hue === undefined) {
953
+ this.Hue = 0;
954
+ } else {
955
+ this.Hue = this.accessory.context.Hue;
956
+ }
957
+ if (this.Brightness === undefined) {
958
+ this.Brightness = 0;
959
+ } else {
960
+ this.Brightness = this.accessory.context.Brightness;
961
+ }
962
+ if (this.Brightness === undefined) {
963
+ this.Saturation = 0;
964
+ } else {
965
+ this.Saturation = this.accessory.context.Saturation;
966
+ }
967
+ /*if (this.ColorTemperature === undefined) {
968
+ this.ColorTemperature = 140;
969
+ } else {
970
+ this.ColorTemperature = this.accessory.context.ColorTemperature;
971
+ }*/
972
+ this.minKelvin = 2000;
973
+ this.maxKelvin = 9000;
769
974
  }
770
975
 
771
- /**
772
- * Handle requests to set the value of the "Saturation" characteristic
773
- */
774
- async SaturationSet(value: CharacteristicValue): Promise<void> {
775
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${value}`);
776
-
777
- this.Saturation = value;
778
- this.doStripLightUpdate.next();
976
+ async refreshRate(device: device & devicesConfig): Promise<void> {
977
+ if (device.refreshRate) {
978
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
979
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
980
+ } else if (this.platform.config.options!.refreshRate) {
981
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
982
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
983
+ }
779
984
  }
780
985
 
781
986
  async config(device: device & devicesConfig): Promise<void> {
@@ -783,11 +988,8 @@ export class StripLight {
783
988
  if (device.colorbulb) {
784
989
  config = device.colorbulb;
785
990
  }
786
- if (device.ble) {
787
- config['ble'] = device.ble;
788
- }
789
- if (device.openAPI !== undefined) {
790
- config['openAPI'] = device.openAPI;
991
+ if (device.connectionType !== undefined) {
992
+ config['connectionType'] = device.connectionType;
791
993
  }
792
994
  if (device.logging !== undefined) {
793
995
  config['logging'] = device.logging;
@@ -806,39 +1008,6 @@ export class StripLight {
806
1008
  }
807
1009
  }
808
1010
 
809
- async refreshRate(device: device & devicesConfig): Promise<void> {
810
- if (device.refreshRate) {
811
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
812
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
813
- } else if (this.platform.config.options!.refreshRate) {
814
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
815
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
816
- }
817
- }
818
-
819
- async openAPI() {
820
- if (!this.device.openAPI) {
821
- this.OpenAPI = true;
822
- } else {
823
- this.OpenAPI = this.device.openAPI;
824
- }
825
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI: ${this.OpenAPI}`);
826
- }
827
-
828
- async scan(device: device & devicesConfig): Promise<void> {
829
- if (device.scanDuration) {
830
- this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
831
- if (device.ble) {
832
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
833
- }
834
- } else {
835
- this.scanDuration = this.accessory.context.scanDuration = 1;
836
- if (this.device.ble) {
837
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
838
- }
839
- }
840
- }
841
-
842
1011
  async logs(device: device & devicesConfig): Promise<void> {
843
1012
  if (this.platform.debugMode) {
844
1013
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
@@ -855,31 +1024,6 @@ export class StripLight {
855
1024
  }
856
1025
  }
857
1026
 
858
- FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
859
- let FirmwareRevision: string;
860
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
861
- +`accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
862
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
863
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
864
- if (accessory.context.FirmwareRevision) {
865
- FirmwareRevision = accessory.context.FirmwareRevision;
866
- } else if (device.firmware) {
867
- FirmwareRevision = device.firmware;
868
- } else {
869
- FirmwareRevision = this.platform.version;
870
- }
871
- return FirmwareRevision;
872
- }
873
-
874
- minStep(device: device & devicesConfig): number {
875
- if (device.colorbulb?.set_minStep) {
876
- this.set_minStep = device.colorbulb?.set_minStep;
877
- } else {
878
- this.set_minStep = 1;
879
- }
880
- return this.set_minStep;
881
- }
882
-
883
1027
  /**
884
1028
  * Logging for Device
885
1029
  */