@switchbot/homebridge-switchbot 2.0.0-beta.12 → 2.0.0-beta.14

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 (86) hide show
  1. package/dist/device/bot.d.ts.map +1 -1
  2. package/dist/device/bot.js +19 -18
  3. package/dist/device/bot.js.map +1 -1
  4. package/dist/device/colorbulb.d.ts.map +1 -1
  5. package/dist/device/colorbulb.js +32 -25
  6. package/dist/device/colorbulb.js.map +1 -1
  7. package/dist/device/contact.d.ts.map +1 -1
  8. package/dist/device/contact.js +7 -6
  9. package/dist/device/contact.js.map +1 -1
  10. package/dist/device/curtain.d.ts.map +1 -1
  11. package/dist/device/curtain.js +14 -13
  12. package/dist/device/curtain.js.map +1 -1
  13. package/dist/device/humidifier.d.ts.map +1 -1
  14. package/dist/device/humidifier.js +18 -17
  15. package/dist/device/humidifier.js.map +1 -1
  16. package/dist/device/lock.d.ts.map +1 -1
  17. package/dist/device/lock.js +8 -7
  18. package/dist/device/lock.js.map +1 -1
  19. package/dist/device/meter.d.ts.map +1 -1
  20. package/dist/device/meter.js +9 -8
  21. package/dist/device/meter.js.map +1 -1
  22. package/dist/device/meterplus.d.ts.map +1 -1
  23. package/dist/device/meterplus.js +8 -7
  24. package/dist/device/meterplus.js.map +1 -1
  25. package/dist/device/motion.d.ts.map +1 -1
  26. package/dist/device/motion.js +7 -6
  27. package/dist/device/motion.js.map +1 -1
  28. package/dist/device/plug.d.ts.map +1 -1
  29. package/dist/device/plug.js +13 -12
  30. package/dist/device/plug.js.map +1 -1
  31. package/dist/device/striplight.d.ts +2 -2
  32. package/dist/device/striplight.d.ts.map +1 -1
  33. package/dist/device/striplight.js +44 -36
  34. package/dist/device/striplight.js.map +1 -1
  35. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  36. package/dist/irdevice/airconditioner.js +10 -9
  37. package/dist/irdevice/airconditioner.js.map +1 -1
  38. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  39. package/dist/irdevice/airpurifier.js +8 -7
  40. package/dist/irdevice/airpurifier.js.map +1 -1
  41. package/dist/irdevice/camera.d.ts.map +1 -1
  42. package/dist/irdevice/camera.js +7 -6
  43. package/dist/irdevice/camera.js.map +1 -1
  44. package/dist/irdevice/fan.d.ts.map +1 -1
  45. package/dist/irdevice/fan.js +10 -9
  46. package/dist/irdevice/fan.js.map +1 -1
  47. package/dist/irdevice/light.d.ts.map +1 -1
  48. package/dist/irdevice/light.js +9 -8
  49. package/dist/irdevice/light.js.map +1 -1
  50. package/dist/irdevice/other.d.ts.map +1 -1
  51. package/dist/irdevice/other.js +7 -6
  52. package/dist/irdevice/other.js.map +1 -1
  53. package/dist/irdevice/tv.d.ts.map +1 -1
  54. package/dist/irdevice/tv.js +16 -15
  55. package/dist/irdevice/tv.js.map +1 -1
  56. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  57. package/dist/irdevice/vacuumcleaner.js +7 -6
  58. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  59. package/dist/irdevice/waterheater.d.ts.map +1 -1
  60. package/dist/irdevice/waterheater.js +7 -6
  61. package/dist/irdevice/waterheater.js.map +1 -1
  62. package/dist/platform.d.ts.map +1 -1
  63. package/dist/platform.js +24 -23
  64. package/dist/platform.js.map +1 -1
  65. package/package.json +1 -1
  66. package/src/device/bot.ts +19 -18
  67. package/src/device/colorbulb.ts +33 -26
  68. package/src/device/contact.ts +7 -6
  69. package/src/device/curtain.ts +14 -13
  70. package/src/device/humidifier.ts +18 -17
  71. package/src/device/lock.ts +8 -7
  72. package/src/device/meter.ts +9 -8
  73. package/src/device/meterplus.ts +8 -7
  74. package/src/device/motion.ts +7 -6
  75. package/src/device/plug.ts +13 -12
  76. package/src/device/striplight.ts +47 -39
  77. package/src/irdevice/airconditioner.ts +10 -9
  78. package/src/irdevice/airpurifier.ts +8 -7
  79. package/src/irdevice/camera.ts +7 -6
  80. package/src/irdevice/fan.ts +10 -9
  81. package/src/irdevice/light.ts +9 -8
  82. package/src/irdevice/other.ts +7 -6
  83. package/src/irdevice/tv.ts +16 -15
  84. package/src/irdevice/vacuumcleaner.ts +7 -6
  85. package/src/irdevice/waterheater.ts +7 -6
  86. package/src/platform.ts +24 -23
@@ -3,8 +3,9 @@ import crypto from 'crypto';
3
3
  import { Context } from 'vm';
4
4
  import { IncomingMessage } from 'http';
5
5
  import { interval, Subject } from 'rxjs';
6
+ import superStringify from 'super-stringify';
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, switchbot, hs2rgb, rgb2hs, deviceStatus, HostDomain, DevicePath, ad, serviceData } from '../settings';
10
11
 
@@ -55,8 +56,8 @@ export class StripLight {
55
56
  cacheKelvin!: number;
56
57
 
57
58
  // Updates
58
- colorBulbUpdateInProgress!: boolean;
59
- doColorBulbUpdate!: Subject<void>;
59
+ stripLightUpdateInProgress!: boolean;
60
+ doStripLightUpdate!: Subject<void>;
60
61
 
61
62
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
62
63
  // default placeholders
@@ -75,8 +76,8 @@ export class StripLight {
75
76
  this.minKelvin = 2000;
76
77
  this.maxKelvin = 9000;
77
78
  // this is subject we use to track when we need to POST changes to the SwitchBot API
78
- this.doColorBulbUpdate = new Subject();
79
- this.colorBulbUpdateInProgress = false;
79
+ this.doStripLightUpdate = new Subject();
80
+ this.stripLightUpdateInProgress = false;
80
81
 
81
82
  // Retrieve initial values and updateHomekit
82
83
  this.refreshStatus();
@@ -152,17 +153,17 @@ export class StripLight {
152
153
 
153
154
  // Start an update interval
154
155
  interval(this.deviceRefreshRate * 1000)
155
- .pipe(skipWhile(() => this.colorBulbUpdateInProgress))
156
+ .pipe(skipWhile(() => this.stripLightUpdateInProgress))
156
157
  .subscribe(async () => {
157
158
  await this.refreshStatus();
158
159
  });
159
160
 
160
161
  // Watch for Bulb change events
161
162
  // We put in a debounce of 100ms so we don't make duplicate calls
162
- this.doColorBulbUpdate
163
+ this.doStripLightUpdate
163
164
  .pipe(
164
165
  tap(() => {
165
- this.colorBulbUpdateInProgress = true;
166
+ this.stripLightUpdateInProgress = true;
166
167
  }),
167
168
  debounceTime(this.platform.config.options!.pushRate! * 1000),
168
169
  )
@@ -172,11 +173,18 @@ export class StripLight {
172
173
  } catch (e: any) {
173
174
  this.errorLog(`Strip Light: ${this.accessory.displayName} failed pushChanges`);
174
175
  if (this.deviceLogging.includes('debug')) {
175
- this.errorLog(`Strip Light: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
176
+ this.errorLog(`Strip Light: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${superStringify(e.message)}`);
176
177
  }
177
178
  this.apiError(e);
178
179
  }
179
- this.colorBulbUpdateInProgress = false;
180
+ this.stripLightUpdateInProgress = false;
181
+ // Refresh the status from the API
182
+ interval(15000)
183
+ .pipe(skipWhile(() => this.stripLightUpdateInProgress))
184
+ .pipe(take(1))
185
+ .subscribe(async () => {
186
+ await this.refreshStatus();
187
+ });
180
188
  });
181
189
  }
182
190
 
@@ -217,14 +225,14 @@ export class StripLight {
217
225
 
218
226
  // Color, Hue & Brightness
219
227
  if (this.color) {
220
- this.debugLog(`Strip Light: ${this.accessory.displayName} color: ${JSON.stringify(this.color)}`);
228
+ this.debugLog(`Strip Light: ${this.accessory.displayName} color: ${superStringify(this.color)}`);
221
229
  const [red, green, blue] = this.color!.split(':');
222
- this.debugLog(`Strip Light: ${this.accessory.displayName} red: ${JSON.stringify(red)}`);
223
- this.debugLog(`Strip Light: ${this.accessory.displayName} green: ${JSON.stringify(green)}`);
224
- this.debugLog(`Strip Light: ${this.accessory.displayName} blue: ${JSON.stringify(blue)}`);
230
+ this.debugLog(`Strip Light: ${this.accessory.displayName} red: ${superStringify(red)}`);
231
+ this.debugLog(`Strip Light: ${this.accessory.displayName} green: ${superStringify(green)}`);
232
+ this.debugLog(`Strip Light: ${this.accessory.displayName} blue: ${superStringify(blue)}`);
225
233
 
226
234
  const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
227
- this.debugLog(`Strip Light: ${this.accessory.displayName} hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
235
+ this.debugLog(`Strip Light: ${this.accessory.displayName} hs: ${superStringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
228
236
 
229
237
  // Hue
230
238
  this.Hue = hue;
@@ -271,7 +279,7 @@ export class StripLight {
271
279
  this.infoLog(`Strip Light: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
272
280
  this.infoLog(`Strip Light: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
273
281
  }
274
- this.errorLog(`Strip Light: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
282
+ this.errorLog(`Strip Light: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
275
283
  this.serviceData = ad.serviceData;
276
284
  //this.state = ad.serviceData.state;
277
285
  //this.delay = ad.serviceData.delay;
@@ -280,7 +288,7 @@ export class StripLight {
280
288
  //this.wifiRssi = ad.serviceData.wifiRssi;
281
289
  //this.overload = ad.serviceData.overload;
282
290
  //this.currentPower = ad.serviceData.currentPower;
283
- this.debugLog(`Strip Light: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
291
+ this.debugLog(`Strip Light: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
284
292
  /*this.debugLog(
285
293
  `Strip Light: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
286
294
  `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
@@ -317,7 +325,7 @@ export class StripLight {
317
325
  this.errorLog(`Strip Light: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
318
326
  if (this.deviceLogging.includes('debug')) {
319
327
  this.errorLog(
320
- `Strip Light: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
328
+ `Strip Light: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${superStringify(e.message)}`,
321
329
  );
322
330
  }
323
331
  if (this.platform.config.credentials?.token) {
@@ -342,7 +350,7 @@ export class StripLight {
342
350
  });
343
351
  // Set an event handler
344
352
  switchbot.onadvertisement = (ad: any) => {
345
- this.warnLog(`Strip Light: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
353
+ this.warnLog(`Strip Light: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
346
354
  };
347
355
  await switchbot.wait(10000);
348
356
  // Stop to monitor
@@ -391,7 +399,7 @@ export class StripLight {
391
399
  res.on('end', () => {
392
400
  try {
393
401
  this.deviceStatus = JSON.parse(rawData);
394
- this.debugLog(`Strip Light: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
402
+ this.debugLog(`Strip Light: ${this.accessory.displayName} refreshStatus: ${superStringify(this.deviceStatus)}`);
395
403
  this.power = this.deviceStatus.body.power;
396
404
  this.color = this.deviceStatus.body.color;
397
405
  this.brightness = this.deviceStatus.body.brightness;
@@ -410,7 +418,7 @@ export class StripLight {
410
418
  this.errorLog(`Strip Light: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
411
419
  if (this.deviceLogging.includes('debug')) {
412
420
  this.errorLog(
413
- `Strip Light: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
421
+ `Strip Light: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
414
422
  );
415
423
  }
416
424
  this.apiError(e);
@@ -446,7 +454,7 @@ export class StripLight {
446
454
  } else {
447
455
  command = 'turnOff';
448
456
  }
449
- const body = JSON.stringify({
457
+ const body = superStringify({
450
458
  'command': `${command}`,
451
459
  'parameter': 'default',
452
460
  'commandType': 'command',
@@ -478,7 +486,7 @@ export class StripLight {
478
486
  });
479
487
  req.write(body);
480
488
  req.end();
481
- this.debugLog(`Strip Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
489
+ this.debugLog(`Strip Light: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
482
490
  }
483
491
  // Push Brightness Update
484
492
  if (this.On) {
@@ -493,7 +501,7 @@ export class StripLight {
493
501
  this.errorLog(`Strip Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
494
502
  if (this.deviceLogging.includes('debug')) {
495
503
  this.errorLog(
496
- `Strip Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
504
+ `Strip Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
497
505
  );
498
506
  }
499
507
  this.apiError(e);
@@ -503,11 +511,11 @@ export class StripLight {
503
511
  async pushHueSaturationChanges(): Promise<void> {
504
512
  try {
505
513
  if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
506
- this.debugLog(`Strip Light: ${this.accessory.displayName} Hue: ${JSON.stringify(this.Hue)}`);
507
- this.debugLog(`Strip Light: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.Saturation)}`);
514
+ this.debugLog(`Strip Light: ${this.accessory.displayName} Hue: ${superStringify(this.Hue)}`);
515
+ this.debugLog(`Strip Light: ${this.accessory.displayName} Saturation: ${superStringify(this.Saturation)}`);
508
516
 
509
517
  const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
510
- this.debugLog(`Strip Light: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
518
+ this.debugLog(`Strip Light: ${this.accessory.displayName} rgb: ${superStringify([red, green, blue])}`);
511
519
  // Make Push On request to the API
512
520
  const t = Date.now();
513
521
  const nonce = 'requestID';
@@ -517,7 +525,7 @@ export class StripLight {
517
525
  .digest();
518
526
  const sign = signTerm.toString('base64');
519
527
  this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
520
- const body = JSON.stringify({
528
+ const body = superStringify({
521
529
  'command': 'setColor',
522
530
  'parameter': `${red}:${green}:${blue}`,
523
531
  'commandType': 'command',
@@ -549,7 +557,7 @@ export class StripLight {
549
557
  });
550
558
  req.write(body);
551
559
  req.end();
552
- this.debugLog(`Strip Light: ${this.accessory.displayName} pushHueSaturationChanges: ${JSON.stringify(req)}`);
560
+ this.debugLog(`Strip Light: ${this.accessory.displayName} pushHueSaturationChanges: ${superStringify(req)}`);
553
561
  } else {
554
562
  this.debugLog(
555
563
  `Strip Light: ${this.accessory.displayName} No Changes.` +
@@ -562,7 +570,7 @@ export class StripLight {
562
570
  if (this.deviceLogging.includes('debug')) {
563
571
  this.errorLog(
564
572
  `Strip Light: ${this.accessory.displayName} failed pushHueSaturationChanges with OpenAPI Connection,`
565
- + ` Error Message: ${JSON.stringify(e.message)}`,
573
+ + ` Error Message: ${superStringify(e.message)}`,
566
574
  );
567
575
  }
568
576
  this.apiError(e);
@@ -581,7 +589,7 @@ export class StripLight {
581
589
  .digest();
582
590
  const sign = signTerm.toString('base64');
583
591
  this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
584
- const body = JSON.stringify({
592
+ const body = superStringify({
585
593
  'command': 'setBrightness',
586
594
  'parameter': `${this.Brightness}`,
587
595
  'commandType': 'command',
@@ -613,7 +621,7 @@ export class StripLight {
613
621
  });
614
622
  req.write(body);
615
623
  req.end();
616
- this.debugLog(`Strip Light: ${this.accessory.displayName} pushBrightnessChanges: ${JSON.stringify(req)}`);
624
+ this.debugLog(`Strip Light: ${this.accessory.displayName} pushBrightnessChanges: ${superStringify(req)}`);
617
625
  } else {
618
626
  this.debugLog(
619
627
  `Strip Light: ${this.accessory.displayName} No Changes.` + `Brightness: ${this.Brightness}, `
@@ -625,7 +633,7 @@ export class StripLight {
625
633
  if (this.deviceLogging.includes('debug')) {
626
634
  this.errorLog(
627
635
  `Strip Light: ${this.accessory.displayName} failed pushBrightnessChanges with OpenAPI Connection,`
628
- + ` Error Message: ${JSON.stringify(e.message)}`,
636
+ + ` Error Message: ${superStringify(e.message)}`,
629
637
  );
630
638
  }
631
639
  this.apiError(e);
@@ -693,7 +701,7 @@ export class StripLight {
693
701
  case 190:
694
702
  this.errorLog(
695
703
  `Strip Light: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
696
- ` Or command: ${JSON.stringify(res)} format is invalid`,
704
+ ` Or command: ${superStringify(res)} format is invalid`,
697
705
  );
698
706
  break;
699
707
  case 100:
@@ -722,7 +730,7 @@ export class StripLight {
722
730
  this.debugLog(`Strip Light: ${this.accessory.displayName} On: ${value}`);
723
731
 
724
732
  this.On = value;
725
- this.doColorBulbUpdate.next();
733
+ this.doStripLightUpdate.next();
726
734
  }
727
735
 
728
736
  /**
@@ -732,7 +740,7 @@ export class StripLight {
732
740
  this.debugLog(`Strip Light: ${this.accessory.displayName} Brightness: ${value}`);
733
741
 
734
742
  this.Brightness = value;
735
- this.doColorBulbUpdate.next();
743
+ this.doStripLightUpdate.next();
736
744
  }
737
745
 
738
746
  /**
@@ -742,7 +750,7 @@ export class StripLight {
742
750
  this.debugLog(`Strip Light: ${this.accessory.displayName} Hue: ${value}`);
743
751
 
744
752
  this.Hue = value;
745
- this.doColorBulbUpdate.next();
753
+ this.doStripLightUpdate.next();
746
754
  }
747
755
 
748
756
  /**
@@ -752,7 +760,7 @@ export class StripLight {
752
760
  this.debugLog(`Strip Light: ${this.accessory.displayName} Saturation: ${value}`);
753
761
 
754
762
  this.Saturation = value;
755
- this.doColorBulbUpdate.next();
763
+ this.doStripLightUpdate.next();
756
764
  }
757
765
 
758
766
  async config(device: device & devicesConfig): Promise<void> {
@@ -776,7 +784,7 @@ export class StripLight {
776
784
  config['offline'] = device.offline;
777
785
  }
778
786
  if (Object.entries(config).length !== 0) {
779
- this.infoLog(`Strip Light: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
787
+ this.infoLog(`Strip Light: ${this.accessory.displayName} Config: ${superStringify(config)}`);
780
788
  }
781
789
  }
782
790
 
@@ -1,6 +1,7 @@
1
1
  import https from 'https';
2
2
  import crypto from 'crypto';
3
3
  import { IncomingMessage } from 'http';
4
+ import superStringify from 'super-stringify';
4
5
  import { SwitchBotPlatform } from '../platform';
5
6
  import { irDevicesConfig, irdevice, HostDomain, DevicePath } from '../settings';
6
7
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
@@ -110,14 +111,14 @@ export class AirConditioner {
110
111
  this.TargetHeaterCoolerState = 1 || 2;
111
112
  this.ValidValues = [1, 2];
112
113
  this.debugLog(
113
- `Air Conditioner: ${this.accessory.displayName} ValidValues: ${JSON.stringify(this.ValidValues)},` +
114
+ `Air Conditioner: ${this.accessory.displayName} ValidValues: ${superStringify(this.ValidValues)},` +
114
115
  ` hide_automode: ${this.hide_automode}, TargetHeaterCoolerState: ${this.TargetHeaterCoolerState}`,
115
116
  );
116
117
  } else {
117
118
  this.TargetHeaterCoolerState = 0 || 1 || 2;
118
119
  this.ValidValues = [0, 1, 2];
119
120
  this.debugLog(
120
- `Air Conditioner: ${this.accessory.displayName} ValidValues: ${JSON.stringify(this.ValidValues)},` +
121
+ `Air Conditioner: ${this.accessory.displayName} ValidValues: ${superStringify(this.ValidValues)},` +
121
122
  ` hide_automode: ${this.hide_automode}, TargetHeaterCoolerState: ${this.TargetHeaterCoolerState}`,
122
123
  );
123
124
  }
@@ -183,7 +184,7 @@ export class AirConditioner {
183
184
  */
184
185
  async pushAirConditionerOnChanges(): Promise<void> {
185
186
  if (this.Active !== this.platform.Characteristic.Active.ACTIVE || this.pushOn) {
186
- const body = JSON.stringify({
187
+ const body = superStringify({
187
188
  'command': 'turnOn',
188
189
  'parameter': 'default',
189
190
  'commandType': 'command',
@@ -193,7 +194,7 @@ export class AirConditioner {
193
194
  }
194
195
 
195
196
  async pushAirConditionerOffChanges(): Promise<void> {
196
- const body = JSON.stringify({
197
+ const body = superStringify({
197
198
  'command': 'turnOff',
198
199
  'parameter': 'default',
199
200
  'commandType': 'command',
@@ -243,7 +244,7 @@ export class AirConditioner {
243
244
  } else {
244
245
  this.CurrentHeaterCoolerState = this.platform.Characteristic.CurrentHeaterCoolerState.INACTIVE;
245
246
  }
246
- const body = JSON.stringify({
247
+ const body = superStringify({
247
248
  'command': 'setAll',
248
249
  'parameter': `${parameter}`,
249
250
  'commandType': 'command',
@@ -290,7 +291,7 @@ export class AirConditioner {
290
291
  });
291
292
  req.write(body);
292
293
  req.end();
293
- this.debugLog(`Air Conditioner: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
294
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
294
295
  this.CurrentTemperatureCached = this.CurrentTemperature;
295
296
  this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
296
297
  this.HeatingThresholdTemperature = this.CurrentTemperatureCached;
@@ -303,7 +304,7 @@ export class AirConditioner {
303
304
  } catch (e: any) {
304
305
  this.errorLog(`Air Conditioner: ${this.accessory.displayName} failed pushChanges`);
305
306
  if (this.deviceLogging.includes('debug')) {
306
- this.errorLog(`Air Conditioner: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
307
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${superStringify(e.message)}`);
307
308
  }
308
309
  this.apiError(e);
309
310
  }
@@ -329,7 +330,7 @@ export class AirConditioner {
329
330
  case 190:
330
331
  this.errorLog(
331
332
  `Air Conditioner: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
332
- ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
333
+ ` with server, Or command: ${superStringify(res)} format is invalid`,
333
334
  );
334
335
  break;
335
336
  case 100:
@@ -620,7 +621,7 @@ export class AirConditioner {
620
621
  config['logging'] = device.logging;
621
622
  }
622
623
  if (Object.entries(config).length !== 0) {
623
- this.infoLog(`Air Conditioner: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
624
+ this.infoLog(`Air Conditioner: ${this.accessory.displayName} Config: ${superStringify(config)}`);
624
625
  }
625
626
  }
626
627
 
@@ -1,6 +1,7 @@
1
1
  import https from 'https';
2
2
  import crypto from 'crypto';
3
3
  import { IncomingMessage } from 'http';
4
+ import superStringify from 'super-stringify';
4
5
  import { SwitchBotPlatform } from '../platform';
5
6
  import { irDevicesConfig, irdevice, HostDomain, DevicePath } from '../settings';
6
7
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
@@ -158,7 +159,7 @@ export class AirPurifier {
158
159
  */
159
160
  async pushAirPurifierOnChanges(): Promise<void> {
160
161
  if (this.Active !== 1) {
161
- const body = JSON.stringify({
162
+ const body = superStringify({
162
163
  'command': 'turnOn',
163
164
  'parameter': 'default',
164
165
  'commandType': 'command',
@@ -169,7 +170,7 @@ export class AirPurifier {
169
170
 
170
171
  async pushAirPurifierOffChanges(): Promise<void> {
171
172
  if (this.Active !== 0) {
172
- const body = JSON.stringify({
173
+ const body = superStringify({
173
174
  'command': 'turnOff',
174
175
  'parameter': 'default',
175
176
  'commandType': 'command',
@@ -195,7 +196,7 @@ export class AirPurifier {
195
196
  this.CurrentAPFanSpeed = this.CurrentFanSpeed || 1;
196
197
  this.APActive = this.Active === 1 ? 'on' : 'off';
197
198
  const parameter = `${this.CurrentAPTemp},${this.CurrentAPMode},${this.CurrentAPFanSpeed},${this.APActive}`;
198
- const body = JSON.stringify({
199
+ const body = superStringify({
199
200
  'command': 'setAll',
200
201
  'parameter': `${parameter}`,
201
202
  'commandType': 'command',
@@ -250,7 +251,7 @@ export class AirPurifier {
250
251
  });
251
252
  req.write(body);
252
253
  req.end();
253
- this.debugLog(`Air Purifier: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
254
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
254
255
  this.updateHomeKitCharacteristics();
255
256
  this.CurrentTemperatureCached = this.CurrentTemperature;
256
257
  this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
@@ -258,7 +259,7 @@ export class AirPurifier {
258
259
  this.errorLog(`Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
259
260
  if (this.deviceLogging.includes('debug')) {
260
261
  this.errorLog(
261
- `Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
262
+ `Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
262
263
  );
263
264
  }
264
265
  this.apiError(e);
@@ -285,7 +286,7 @@ export class AirPurifier {
285
286
  case 190:
286
287
  this.errorLog(
287
288
  `Air Purifier: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
288
- ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
289
+ ` with server, Or command: ${superStringify(res)} format is invalid`,
289
290
  );
290
291
  break;
291
292
  case 100:
@@ -313,7 +314,7 @@ export class AirPurifier {
313
314
  config['logging'] = device.logging;
314
315
  }
315
316
  if (Object.entries(config).length !== 0) {
316
- this.infoLog(`Air Purifier: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
317
+ this.infoLog(`Air Purifier: ${this.accessory.displayName} Config: ${superStringify(config)}`);
317
318
  }
318
319
  }
319
320
 
@@ -1,6 +1,7 @@
1
1
  import https from 'https';
2
2
  import crypto from 'crypto';
3
3
  import { IncomingMessage } from 'http';
4
+ import superStringify from 'super-stringify';
4
5
  import { SwitchBotPlatform } from '../platform';
5
6
  import { irDevicesConfig, irdevice, HostDomain, DevicePath } from '../settings';
6
7
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
@@ -86,7 +87,7 @@ export class Camera {
86
87
  */
87
88
  async pushOnChanges(): Promise<void> {
88
89
  if (this.On) {
89
- const body = JSON.stringify({
90
+ const body = superStringify({
90
91
  'command': 'turnOn',
91
92
  'parameter': 'default',
92
93
  'commandType': 'command',
@@ -97,7 +98,7 @@ export class Camera {
97
98
 
98
99
  async pushOffChanges(): Promise<void> {
99
100
  if (!this.On) {
100
- const body = JSON.stringify({
101
+ const body = superStringify({
101
102
  'command': 'turnOff',
102
103
  'parameter': 'default',
103
104
  'commandType': 'command',
@@ -144,7 +145,7 @@ export class Camera {
144
145
  });
145
146
  req.write(body);
146
147
  req.end();
147
- this.debugLog(`Camera: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
148
+ this.debugLog(`Camera: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
148
149
  this.updateHomeKitCharacteristics();
149
150
  this.OnCached = this.On;
150
151
  this.accessory.context.On = this.OnCached;
@@ -152,7 +153,7 @@ export class Camera {
152
153
  this.errorLog(`Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
153
154
  if (this.deviceLogging.includes('debug')) {
154
155
  this.errorLog(
155
- `Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
156
+ `Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
156
157
  );
157
158
  }
158
159
  this.apiError(e);
@@ -179,7 +180,7 @@ export class Camera {
179
180
  case 190:
180
181
  this.errorLog(
181
182
  `Camera: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
182
- ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
183
+ ` with server, Or command: ${superStringify(res)} format is invalid`,
183
184
  );
184
185
  break;
185
186
  case 100:
@@ -204,7 +205,7 @@ export class Camera {
204
205
  config['logging'] = device.logging;
205
206
  }
206
207
  if (Object.entries(config).length !== 0) {
207
- this.infoLog(`Camera: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
208
+ this.infoLog(`Camera: ${this.accessory.displayName} Config: ${superStringify(config)}`);
208
209
  }
209
210
  }
210
211
 
@@ -1,6 +1,7 @@
1
1
  import https from 'https';
2
2
  import crypto from 'crypto';
3
3
  import { IncomingMessage } from 'http';
4
+ import superStringify from 'super-stringify';
4
5
  import { SwitchBotPlatform } from '../platform';
5
6
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
6
7
  import { irdevice, irDevicesConfig, HostDomain, DevicePath } from '../settings';
@@ -188,7 +189,7 @@ export class Fan {
188
189
  */
189
190
  async pushFanOnChanges(): Promise<void> {
190
191
  if (this.Active !== 1) {
191
- const body = JSON.stringify({
192
+ const body = superStringify({
192
193
  'command': 'turnOn',
193
194
  'parameter': 'default',
194
195
  'commandType': 'command',
@@ -198,7 +199,7 @@ export class Fan {
198
199
  }
199
200
 
200
201
  async pushFanOffChanges(): Promise<void> {
201
- const body = JSON.stringify({
202
+ const body = superStringify({
202
203
  'command': 'turnOff',
203
204
  'parameter': 'default',
204
205
  'commandType': 'command',
@@ -207,7 +208,7 @@ export class Fan {
207
208
  }
208
209
 
209
210
  async pushFanSpeedUpChanges(): Promise<void> {
210
- const body = JSON.stringify({
211
+ const body = superStringify({
211
212
  'command': 'highSpeed',
212
213
  'parameter': 'default',
213
214
  'commandType': 'command',
@@ -216,7 +217,7 @@ export class Fan {
216
217
  }
217
218
 
218
219
  async pushFanSpeedDownChanges(): Promise<void> {
219
- const body = JSON.stringify({
220
+ const body = superStringify({
220
221
  'command': 'lowSpeed',
221
222
  'parameter': 'default',
222
223
  'commandType': 'command',
@@ -225,7 +226,7 @@ export class Fan {
225
226
  }
226
227
 
227
228
  async pushFanSwingChanges(): Promise<void> {
228
- const body = JSON.stringify({
229
+ const body = superStringify({
229
230
  'command': 'swing',
230
231
  'parameter': 'default',
231
232
  'commandType': 'command',
@@ -271,13 +272,13 @@ export class Fan {
271
272
  });
272
273
  req.write(body);
273
274
  req.end();
274
- this.debugLog(`Fan: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
275
+ this.debugLog(`Fan: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
275
276
  this.updateHomeKitCharacteristics();
276
277
  } catch (e: any) {
277
278
  this.errorLog(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
278
279
  if (this.deviceLogging.includes('debug')) {
279
280
  this.errorLog(
280
- `Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
281
+ `Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
281
282
  );
282
283
  }
283
284
  this.apiError(e);
@@ -304,7 +305,7 @@ export class Fan {
304
305
  case 190:
305
306
  this.errorLog(
306
307
  `Fan: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
307
- ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
308
+ ` with server, Or command: ${superStringify(res)} format is invalid`,
308
309
  );
309
310
  break;
310
311
  case 100:
@@ -331,7 +332,7 @@ export class Fan {
331
332
  config['logging'] = device.logging;
332
333
  }
333
334
  if (Object.entries(config).length !== 0) {
334
- this.infoLog(`Fan: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
335
+ this.infoLog(`Fan: ${this.accessory.displayName} Config: ${superStringify(config)}`);
335
336
  }
336
337
  }
337
338
 
@@ -1,6 +1,7 @@
1
1
  import https from 'https';
2
2
  import crypto from 'crypto';
3
3
  import { IncomingMessage } from 'http';
4
+ import superStringify from 'super-stringify';
4
5
  import { SwitchBotPlatform } from '../platform';
5
6
  import { irDevicesConfig, irdevice, HostDomain, DevicePath } from '../settings';
6
7
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
@@ -101,7 +102,7 @@ export class Light {
101
102
  */
102
103
  async pushLightOnChanges(): Promise<void> {
103
104
  if (this.On) {
104
- const body = JSON.stringify({
105
+ const body = superStringify({
105
106
  'command': 'turnOn',
106
107
  'parameter': 'default',
107
108
  'commandType': 'command',
@@ -112,7 +113,7 @@ export class Light {
112
113
 
113
114
  async pushLightOffChanges(): Promise<void> {
114
115
  if (!this.On) {
115
- const body = JSON.stringify({
116
+ const body = superStringify({
116
117
  'command': 'turnOff',
117
118
  'parameter': 'default',
118
119
  'commandType': 'command',
@@ -122,7 +123,7 @@ export class Light {
122
123
  }
123
124
 
124
125
  async pushLightBrightnessUpChanges(): Promise<void> {
125
- const body = JSON.stringify({
126
+ const body = superStringify({
126
127
  'command': 'brightnessUp',
127
128
  'parameter': 'default',
128
129
  'commandType': 'command',
@@ -131,7 +132,7 @@ export class Light {
131
132
  }
132
133
 
133
134
  async pushLightBrightnessDownChanges(): Promise<void> {
134
- const body = JSON.stringify({
135
+ const body = superStringify({
135
136
  'command': 'brightnessDown',
136
137
  'parameter': 'default',
137
138
  'commandType': 'command',
@@ -177,7 +178,7 @@ export class Light {
177
178
  });
178
179
  req.write(body);
179
180
  req.end();
180
- this.debugLog(`Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
181
+ this.debugLog(`Light: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
181
182
  this.OnCached = this.On;
182
183
  this.accessory.context.On = this.OnCached;
183
184
  this.updateHomeKitCharacteristics();
@@ -185,7 +186,7 @@ export class Light {
185
186
  this.errorLog(`Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
186
187
  if (this.deviceLogging.includes('debug')) {
187
188
  this.errorLog(
188
- `Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
189
+ `Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
189
190
  );
190
191
  }
191
192
  this.apiError(e);
@@ -212,7 +213,7 @@ export class Light {
212
213
  case 190:
213
214
  this.errorLog(
214
215
  `Light: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
215
- ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
216
+ ` with server, Or command: ${superStringify(res)} format is invalid`,
216
217
  );
217
218
  break;
218
219
  case 100:
@@ -237,7 +238,7 @@ export class Light {
237
238
  config['logging'] = device.logging;
238
239
  }
239
240
  if (Object.entries(config).length !== 0) {
240
- this.infoLog(`Light: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
241
+ this.infoLog(`Light: ${this.accessory.displayName} Config: ${superStringify(config)}`);
241
242
  }
242
243
  }
243
244