@switchbot/homebridge-switchbot 2.6.0-beta.4 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/.vscode/tasks.json +13 -0
  2. package/CHANGELOG.md +4 -2
  3. package/README.md +18 -9
  4. package/dist/device/blindtilt.d.ts +1 -5
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +80 -140
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +1 -5
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +79 -138
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +2 -6
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +157 -304
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +2 -6
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +164 -311
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +1 -5
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +36 -72
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +1 -5
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +78 -138
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/hub.d.ts +2 -6
  29. package/dist/device/hub.d.ts.map +1 -1
  30. package/dist/device/hub.js +30 -63
  31. package/dist/device/hub.js.map +1 -1
  32. package/dist/device/humidifier.d.ts +1 -5
  33. package/dist/device/humidifier.d.ts.map +1 -1
  34. package/dist/device/humidifier.js +115 -228
  35. package/dist/device/humidifier.js.map +1 -1
  36. package/dist/device/iosensor.d.ts +1 -5
  37. package/dist/device/iosensor.d.ts.map +1 -1
  38. package/dist/device/iosensor.js +38 -74
  39. package/dist/device/iosensor.js.map +1 -1
  40. package/dist/device/{striplight.d.ts → lightstrip.d.ts} +2 -10
  41. package/dist/device/lightstrip.d.ts.map +1 -0
  42. package/dist/device/{striplight.js → lightstrip.js} +138 -194
  43. package/dist/device/lightstrip.js.map +1 -0
  44. package/dist/device/lock.d.ts +1 -5
  45. package/dist/device/lock.d.ts.map +1 -1
  46. package/dist/device/lock.js +66 -126
  47. package/dist/device/lock.js.map +1 -1
  48. package/dist/device/meter.d.ts +1 -5
  49. package/dist/device/meter.d.ts.map +1 -1
  50. package/dist/device/meter.js +38 -74
  51. package/dist/device/meter.js.map +1 -1
  52. package/dist/device/meterplus.d.ts +1 -5
  53. package/dist/device/meterplus.d.ts.map +1 -1
  54. package/dist/device/meterplus.js +39 -75
  55. package/dist/device/meterplus.js.map +1 -1
  56. package/dist/device/motion.d.ts +1 -5
  57. package/dist/device/motion.d.ts.map +1 -1
  58. package/dist/device/motion.js +35 -72
  59. package/dist/device/motion.js.map +1 -1
  60. package/dist/device/plug.d.ts +1 -5
  61. package/dist/device/plug.d.ts.map +1 -1
  62. package/dist/device/plug.js +65 -126
  63. package/dist/device/plug.js.map +1 -1
  64. package/dist/device/robotvacuumcleaner.d.ts +1 -5
  65. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  66. package/dist/device/robotvacuumcleaner.js +79 -151
  67. package/dist/device/robotvacuumcleaner.js.map +1 -1
  68. package/dist/irdevice/airconditioner.d.ts +3 -7
  69. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  70. package/dist/irdevice/airconditioner.js +34 -62
  71. package/dist/irdevice/airconditioner.js.map +1 -1
  72. package/dist/irdevice/airpurifier.d.ts +3 -7
  73. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  74. package/dist/irdevice/airpurifier.js +31 -59
  75. package/dist/irdevice/airpurifier.js.map +1 -1
  76. package/dist/irdevice/camera.d.ts +1 -5
  77. package/dist/irdevice/camera.d.ts.map +1 -1
  78. package/dist/irdevice/camera.js +30 -57
  79. package/dist/irdevice/camera.js.map +1 -1
  80. package/dist/irdevice/fan.d.ts +2 -6
  81. package/dist/irdevice/fan.d.ts.map +1 -1
  82. package/dist/irdevice/fan.js +39 -66
  83. package/dist/irdevice/fan.js.map +1 -1
  84. package/dist/irdevice/light.d.ts +1 -5
  85. package/dist/irdevice/light.d.ts.map +1 -1
  86. package/dist/irdevice/light.js +32 -59
  87. package/dist/irdevice/light.js.map +1 -1
  88. package/dist/irdevice/other.d.ts +1 -5
  89. package/dist/irdevice/other.d.ts.map +1 -1
  90. package/dist/irdevice/other.js +30 -57
  91. package/dist/irdevice/other.js.map +1 -1
  92. package/dist/irdevice/tv.d.ts +3 -7
  93. package/dist/irdevice/tv.d.ts.map +1 -1
  94. package/dist/irdevice/tv.js +46 -76
  95. package/dist/irdevice/tv.js.map +1 -1
  96. package/dist/irdevice/vacuumcleaner.d.ts +2 -6
  97. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  98. package/dist/irdevice/vacuumcleaner.js +30 -58
  99. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  100. package/dist/irdevice/waterheater.d.ts +7 -23
  101. package/dist/irdevice/waterheater.d.ts.map +1 -1
  102. package/dist/irdevice/waterheater.js +41 -74
  103. package/dist/irdevice/waterheater.js.map +1 -1
  104. package/dist/platform.d.ts +14 -5
  105. package/dist/platform.d.ts.map +1 -1
  106. package/dist/platform.js +156 -149
  107. package/dist/platform.js.map +1 -1
  108. package/dist/settings.d.ts +4 -0
  109. package/dist/settings.d.ts.map +1 -1
  110. package/dist/settings.js +5 -1
  111. package/dist/settings.js.map +1 -1
  112. package/nodemon.json +1 -1
  113. package/package.json +10 -10
  114. package/src/device/blindtilt.ts +122 -181
  115. package/src/device/bot.ts +96 -149
  116. package/src/device/ceilinglight.ts +172 -315
  117. package/src/device/colorbulb.ts +178 -324
  118. package/src/device/contact.ts +48 -78
  119. package/src/device/curtain.ts +93 -148
  120. package/src/device/hub.ts +34 -63
  121. package/src/device/humidifier.ts +135 -243
  122. package/src/device/iosensor.ts +49 -79
  123. package/src/device/{striplight.ts → lightstrip.ts} +148 -200
  124. package/src/device/lock.ts +78 -134
  125. package/src/device/meter.ts +48 -78
  126. package/src/device/meterplus.ts +50 -80
  127. package/src/device/motion.ts +46 -77
  128. package/src/device/plug.ts +76 -134
  129. package/src/device/robotvacuumcleaner.ts +91 -159
  130. package/src/irdevice/airconditioner.ts +56 -81
  131. package/src/irdevice/airpurifier.ts +41 -67
  132. package/src/irdevice/camera.ts +35 -60
  133. package/src/irdevice/fan.ts +46 -71
  134. package/src/irdevice/light.ts +38 -63
  135. package/src/irdevice/other.ts +35 -60
  136. package/src/irdevice/tv.ts +52 -80
  137. package/src/irdevice/vacuumcleaner.ts +36 -62
  138. package/src/irdevice/waterheater.ts +46 -76
  139. package/src/platform.ts +144 -158
  140. package/src/settings.ts +5 -0
  141. package/.github/npm-version-script.js +0 -81
  142. package/dist/device/striplight.d.ts.map +0 -1
  143. package/dist/device/striplight.js.map +0 -1
@@ -1,14 +1,11 @@
1
- import https from 'https';
2
- import crypto from 'crypto';
3
1
  import { Context } from 'vm';
4
- import { IncomingMessage } from 'http';
2
+ import { request } from 'undici';
3
+ import { sleep } from '../utils';
5
4
  import { interval, Subject } from 'rxjs';
6
- import superStringify from 'super-stringify';
7
5
  import { SwitchBotPlatform } from '../platform';
8
6
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
9
7
  import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
10
- import { device, devicesConfig, switchbot, hs2rgb, rgb2hs, deviceStatus, HostDomain, DevicePath, ad, serviceData, m2hs } from '../settings';
11
- import { sleep } from '../utils';
8
+ import { device, devicesConfig, switchbot, hs2rgb, rgb2hs, deviceStatus, ad, serviceData, m2hs, Devices } from '../settings';
12
9
 
13
10
  /**
14
11
  * Platform Accessory
@@ -177,7 +174,7 @@ export class StripLight {
177
174
  this.accessory.context.adaptiveLighting = true;
178
175
  this.debugLog(
179
176
  `${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting},` +
180
- ` adaptiveLightingShift: ${this.adaptiveLightingShift}`,
177
+ ` adaptiveLightingShift: ${this.adaptiveLightingShift}`,
181
178
  );
182
179
  }
183
180
 
@@ -206,7 +203,7 @@ export class StripLight {
206
203
  } catch (e: any) {
207
204
  this.apiError(e);
208
205
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
209
- + ` Error Message: ${superStringify(e.message)}`);
206
+ + ` Error Message: ${JSON.stringify(e.message)}`);
210
207
  }
211
208
  this.stripLightUpdateInProgress = false;
212
209
  });
@@ -225,7 +222,7 @@ export class StripLight {
225
222
  } else {
226
223
  await this.offlineOff();
227
224
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
228
- + ` ${this.device.connectionType}, parseStatus will not happen.`);
225
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
229
226
  }
230
227
  }
231
228
 
@@ -259,15 +256,15 @@ export class StripLight {
259
256
 
260
257
  // Color, Hue & Brightness
261
258
  if (this.color) {
262
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} color: ${superStringify(this.color)}`);
259
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} color: ${JSON.stringify(this.color)}`);
263
260
  const [red, green, blue] = this.color!.split(':');
264
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} red: ${superStringify(red)}`);
265
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} green: ${superStringify(green)}`);
266
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} blue: ${superStringify(blue)}`);
261
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} red: ${JSON.stringify(red)}`);
262
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} green: ${JSON.stringify(green)}`);
263
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} blue: ${JSON.stringify(blue)}`);
267
264
 
268
265
  const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
269
266
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
270
- +` hs: ${superStringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
267
+ + ` hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
271
268
 
272
269
  // Hue
273
270
  this.Hue = hue;
@@ -292,7 +289,7 @@ export class StripLight {
292
289
  } else {
293
290
  await this.offlineOff();
294
291
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
295
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
292
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
296
293
  }
297
294
  }
298
295
 
@@ -318,8 +315,8 @@ export class StripLight {
318
315
  switchbot.onadvertisement = async (ad: any) => {
319
316
  this.address = ad.address;
320
317
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
321
- + ` BLE Address Found: ${this.address}`);
322
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
318
+ + ` BLE Address Found: ${this.address}`);
319
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
323
320
  this.serviceData = ad.serviceData;
324
321
  //this.state = ad.serviceData.state;
325
322
  //this.delay = ad.serviceData.delay;
@@ -328,7 +325,7 @@ export class StripLight {
328
325
  //this.wifiRssi = ad.serviceData.wifiRssi;
329
326
  //this.overload = ad.serviceData.overload;
330
327
  //this.currentPower = ad.serviceData.currentPower;
331
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
328
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
332
329
  /*this.debugLog(
333
330
  `${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
334
331
  `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
@@ -348,13 +345,13 @@ export class StripLight {
348
345
  return await sleep(this.scanDuration * 1000);
349
346
  })
350
347
  .then(async () => {
351
- // Stop to monitor
348
+ // Stop to monitor
352
349
  await this.stopScanning(switchbot);
353
350
  })
354
351
  .catch(async (e: any) => {
355
352
  this.apiError(e);
356
353
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
357
- + ` Connection, Error Message: ${superStringify(e.message)}`);
354
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
358
355
  await this.BLERefreshConnection(switchbot);
359
356
  });
360
357
  } else {
@@ -365,55 +362,26 @@ export class StripLight {
365
362
  async openAPIRefreshStatus(): Promise<void> {
366
363
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
367
364
  try {
368
- const t = Date.now();
369
- const nonce = 'requestID';
370
- const data = this.platform.config.credentials?.token + t + nonce;
371
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
372
- const sign = signTerm.toString('base64');
373
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
374
- const options = {
375
- hostname: HostDomain,
376
- port: 443,
377
- path: `${DevicePath}/${this.device.deviceId}/status`,
378
- method: 'GET',
379
- headers: {
380
- Authorization: this.platform.config.credentials?.token,
381
- sign: sign,
382
- nonce: nonce,
383
- t: t,
384
- 'Content-Type': 'application/json',
385
- },
386
- };
387
- const req = https.request(options, (res) => {
388
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
389
- this.statusCode({ res });
390
- let rawData = '';
391
- res.on('data', (d) => {
392
- rawData += d;
393
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
394
- });
395
- res.on('end', () => {
396
- try {
397
- this.deviceStatus = JSON.parse(rawData);
398
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
399
- this.power = this.deviceStatus.body.power;
400
- this.color = this.deviceStatus.body.color;
401
- this.brightness = this.deviceStatus.body.brightness;
402
- this.openAPIparseStatus();
403
- this.updateHomeKitCharacteristics();
404
- } catch (e: any) {
405
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
406
- }
407
- });
408
- });
409
- req.on('error', (e: any) => {
410
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
365
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
366
+ headers: this.platform.generateHeaders(),
411
367
  });
412
- req.end();
368
+ const deviceStatus = await body.json();
369
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
370
+ this.statusCode(statusCode);
371
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
372
+ this.debugLog(
373
+ `${this.device.deviceType}: ${this.accessory.displayName
374
+ } refreshStatus: ${JSON.stringify(deviceStatus)}`,
375
+ );
376
+ this.power = deviceStatus.body.power;
377
+ this.color = deviceStatus.body.color;
378
+ this.brightness = deviceStatus.body.brightness;
379
+ this.openAPIparseStatus();
380
+ this.updateHomeKitCharacteristics();
413
381
  } catch (e: any) {
414
382
  this.apiError(e);
415
383
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
416
- + ` Connection, Error Message: ${superStringify(e.message)}`);
384
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
417
385
  }
418
386
  }
419
387
 
@@ -437,7 +405,7 @@ export class StripLight {
437
405
  } else {
438
406
  await this.offlineOff();
439
407
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
440
- + ` ${this.device.connectionType}, pushChanges will not happen.`);
408
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
441
409
  }
442
410
  // Refresh the status from the API
443
411
  interval(15000)
@@ -484,7 +452,7 @@ export class StripLight {
484
452
  .catch(async (e: any) => {
485
453
  this.apiError(e);
486
454
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
487
- + ` Connection, Error Message: ${superStringify(e.message)}`);
455
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
488
456
  await this.BLEPushConnection();
489
457
  });
490
458
  // Push Brightness Update
@@ -497,7 +465,7 @@ export class StripLight {
497
465
  }
498
466
  } else {
499
467
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, `
500
- +`OnCached: ${this.accessory.context.On}`);
468
+ + `OnCached: ${this.accessory.context.On}`);
501
469
  }
502
470
  }
503
471
 
@@ -527,23 +495,23 @@ export class StripLight {
527
495
  .catch(async (e: any) => {
528
496
  this.apiError(e);
529
497
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushBrightnessChanges with ${this.device.connectionType}`
530
- + ` Connection, Error Message: ${superStringify(e.message)}`);
498
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
531
499
  await this.BLEPushConnection();
532
500
  });
533
501
  } else {
534
502
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushBrightnessChanges.` + `Brightness: ${this.Brightness}, `
535
- +`BrightnessCached: ${this.accessory.context.Brightness}`);
503
+ + `BrightnessCached: ${this.accessory.context.Brightness}`);
536
504
  }
537
505
  }
538
506
 
539
507
  async BLEpushRGBChanges(): Promise<void> {
540
508
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushRGBChanges`);
541
509
  if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
542
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${superStringify(this.Hue)}`);
543
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${superStringify(this.Saturation)}`);
510
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${JSON.stringify(this.Hue)}`);
511
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.Saturation)}`);
544
512
 
545
513
  const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
546
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${superStringify([red, green, blue])}`);
514
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
547
515
 
548
516
  const switchbot = await this.platform.connectBLE();
549
517
  // Convert to BLE Address
@@ -568,7 +536,7 @@ export class StripLight {
568
536
  .catch(async (e: any) => {
569
537
  this.apiError(e);
570
538
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushRGBChanges with ${this.device.connectionType}`
571
- + ` Connection, Error Message: ${superStringify(e.message)}`);
539
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
572
540
  await this.BLEPushConnection();
573
541
  });
574
542
  } else {
@@ -578,135 +546,114 @@ export class StripLight {
578
546
  }
579
547
 
580
548
  async openAPIpushChanges() {
581
- const change = 'openAPIpushChanges';
582
- try {
583
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${change}`);
584
- if (this.On !== this.accessory.context.On) {
585
- // Make Push On request to the API
586
- const command = this.On ? 'turnOn' : 'turnOff';
587
- /*if (this.On) {
549
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
550
+ if (this.On !== this.accessory.context.On) {
551
+ const command = this.On ? 'turnOn' : 'turnOff';
552
+ /*if (this.On) {
588
553
  command = 'turnOn';
589
554
  } else {
590
555
  command = 'turnOff';
591
556
  }*/
592
- const body = superStringify({
593
- 'command': `${command}`,
594
- 'parameter': 'default',
595
- 'commandType': 'command',
557
+ const body = JSON.stringify({
558
+ 'command': `${command}`,
559
+ 'parameter': 'default',
560
+ 'commandType': 'command',
561
+ });
562
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
563
+ try {
564
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
565
+ method: 'POST',
566
+ headers: this.platform.generateHeaders(),
596
567
  });
597
- await this.request({ body, change });
598
- } else {
599
- this.debugLog(
600
- `${this.device.deviceType}: ${this.accessory.displayName} No ${change}.` + `On: ${this.On}, `
601
- +`OnCached: ${this.accessory.context.On}`,
568
+ const deviceStatus = await body.json();
569
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
570
+ this.statusCode(statusCode);
571
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
572
+ } catch (e: any) {
573
+ this.apiError(e);
574
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
575
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`,
602
576
  );
603
577
  }
604
- // Push Brightness Update
605
- if (this.On) {
606
- await this.pushBrightnessChanges();
607
- }
608
- // Push Hue & Saturation Update
609
- if (this.On) {
610
- await this.pushHueSaturationChanges();
611
- }
612
- } catch (e: any) {
613
- this.apiError(e);
614
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed ${change} with ${this.device.connectionType}`
615
- + ` Connection, Error Message: ${superStringify(e.message)}`,
616
- );
578
+ } else {
579
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `On: ${this.On}, `
580
+ + `OnCached: ${this.accessory.context.On}`);
581
+ }
582
+ // Push Hue & Saturation Update
583
+ if (this.On) {
584
+ await this.pushHueSaturationChanges();
585
+ }
586
+ // Push Brightness Update
587
+ if (this.On) {
588
+ await this.pushBrightnessChanges();
617
589
  }
618
590
  }
619
591
 
620
592
  async pushHueSaturationChanges(): Promise<void> {
621
- const change = 'pushHueSaturationChanges';
622
- try {
623
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${change}`);
624
- if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
625
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${superStringify(this.Hue)}`);
626
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${superStringify(this.Saturation)}`);
627
-
628
- const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
629
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${superStringify([red, green, blue])}`);
630
- // Make Push On request to the API
631
- const body = superStringify({
632
- 'command': 'setColor',
633
- 'parameter': `${red}:${green}:${blue}`,
634
- 'commandType': 'command',
593
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges`);
594
+ if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
595
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${JSON.stringify(this.Hue)}`);
596
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.Saturation)}`);
597
+ const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
598
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
599
+ // Make Push On request to the API
600
+ const body = JSON.stringify({
601
+ 'command': 'setColor',
602
+ 'parameter': `${red}:${green}:${blue}`,
603
+ 'commandType': 'command',
604
+ });
605
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
606
+ try {
607
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
608
+ method: 'POST',
609
+ headers: this.platform.generateHeaders(),
635
610
  });
636
- await this.request({ body, change });
637
- } else {
638
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No ${change}. Hue: ${this.Hue}, `
639
- + `HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`);
611
+ const deviceStatus = await body.json();
612
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
613
+ this.statusCode(statusCode);
614
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
615
+ } catch (e: any) {
616
+ this.apiError(e);
617
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushHueSaturationChanges with ${this.device.connectionType}`
618
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`,
619
+ );
640
620
  }
641
- } catch (e: any) {
642
- this.apiError(e);
643
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed ${change} with ${this.device.connectionType}`
644
- + ` Connection, Error Message: ${superStringify(e.message)}`);
621
+ } else {
622
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushHueSaturationChanges. Hue: ${this.Hue}, `
623
+ + `HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`);
645
624
  }
646
625
  }
647
626
 
648
627
  async pushBrightnessChanges(): Promise<void> {
649
- const change = 'pushBrightnessChanges';
650
- try {
651
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${change}`);
652
- if (this.Brightness !== this.accessory.context.Brightness) {
653
- // Make Push On request to the API
654
- const body = superStringify({
655
- 'command': 'setBrightness',
656
- 'parameter': `${this.Brightness}`,
657
- 'commandType': 'command',
628
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges`);
629
+ if (this.Brightness !== this.accessory.context.Brightness) {
630
+ const body = JSON.stringify({
631
+ 'command': 'setBrightness',
632
+ 'parameter': `${this.Brightness}`,
633
+ 'commandType': 'command',
634
+ });
635
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
636
+ try {
637
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
638
+ method: 'POST',
639
+ headers: this.platform.generateHeaders(),
658
640
  });
659
- await this.request({ body, change });
660
- } else {
661
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No ${change},` + `Brightness: ${this.Brightness}, `
662
- +`BrightnessCached: ${this.accessory.context.Brightness}`);
641
+ const deviceStatus = await body.json();
642
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
643
+ this.statusCode(statusCode);
644
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
645
+ } catch (e: any) {
646
+ this.apiError(e);
647
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with ${this.device.connectionType}`
648
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`,
649
+ );
663
650
  }
664
- } catch (e: any) {
665
- this.apiError(e);
666
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed ${change} with ${this.device.connectionType}`
667
- + ` Connection, Error Message: ${superStringify(e.message)}`);
651
+ } else {
652
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushBrightnessChanges,` + `Brightness: ${this.Brightness}, `
653
+ + `BrightnessCached: ${this.accessory.context.Brightness}`);
668
654
  }
669
655
  }
670
656
 
671
- async request({ body, change }: { body: any; change: string; }): Promise<void> {
672
- const t = Date.now();
673
- const nonce = 'requestID';
674
- const data = this.platform.config.credentials?.token + t + nonce;
675
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
676
- .update(Buffer.from(data, 'utf-8'))
677
- .digest();
678
- const sign = signTerm.toString('base64');
679
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
680
- const options = {
681
- hostname: HostDomain,
682
- port: 443,
683
- path: `${DevicePath}/${this.device.deviceId}/commands`,
684
- method: 'POST',
685
- headers: {
686
- 'Authorization': this.platform.config.credentials?.token,
687
- 'sign': sign,
688
- 'nonce': nonce,
689
- 't': t,
690
- 'Content-Type': 'application/json',
691
- 'Content-Length': body.length,
692
- },
693
- };
694
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
695
- const req = https.request(options, res => {
696
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${change} statusCode: ${res.statusCode}`);
697
- this.statusCode({ res });
698
- res.on('data', d => {
699
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
700
- });
701
- });
702
- req.on('error', (e: any) => {
703
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
704
- });
705
- req.write(body);
706
- req.end();
707
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${change} req: ${superStringify(req)}`);
708
- }
709
-
710
657
  /**
711
658
  * Handle requests to set the value of the "On" characteristic
712
659
  */
@@ -862,7 +809,7 @@ export class StripLight {
862
809
  });
863
810
  // Set an event handler
864
811
  switchbot.onadvertisement = (ad: any) => {
865
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
812
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
866
813
  };
867
814
  await sleep(10000);
868
815
  // Stop to monitor
@@ -939,40 +886,41 @@ export class StripLight {
939
886
  }
940
887
  }
941
888
 
942
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
943
- switch (res.statusCode) {
889
+ async statusCode(statusCode: number): Promise<void> {
890
+ switch (statusCode) {
944
891
  case 151:
945
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
892
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
946
893
  break;
947
894
  case 152:
948
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
895
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
949
896
  break;
950
897
  case 160:
951
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
898
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
952
899
  break;
953
900
  case 161:
954
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
955
- await this.offlineOff();
901
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
902
+ this.offlineOff();
956
903
  break;
957
904
  case 171:
958
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
959
- await this.offlineOff();
905
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
906
+ + `Hub: ${this.device.hubDeviceId}`);
907
+ this.offlineOff();
960
908
  break;
961
909
  case 190:
962
910
  this.errorLog(
963
911
  `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
964
- ` Or command: ${superStringify(res)} format is invalid`,
912
+ ` Or command format is invalid, statusCode: ${statusCode}`,
965
913
  );
966
914
  break;
967
915
  case 100:
968
- if (this.platform.debugMode) {
969
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
970
- }
916
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
917
+ break;
918
+ case 200:
919
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
971
920
  break;
972
921
  default:
973
- if (this.platform.debugMode) {
974
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
975
- }
922
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
923
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
976
924
  }
977
925
  }
978
926
 
@@ -993,7 +941,7 @@ export class StripLight {
993
941
  FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
994
942
  let FirmwareRevision: string;
995
943
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
996
- +`accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
944
+ + `accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
997
945
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
998
946
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
999
947
  if (accessory.context.FirmwareRevision) {
@@ -1073,7 +1021,7 @@ export class StripLight {
1073
1021
  config['maxRetry'] = device.maxRetry;
1074
1022
  }
1075
1023
  if (Object.entries(config).length !== 0) {
1076
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
1024
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
1077
1025
  }
1078
1026
  }
1079
1027