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

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 (138) hide show
  1. package/.vscode/tasks.json +13 -0
  2. package/dist/device/blindtilt.d.ts +1 -5
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +80 -140
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +1 -5
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +79 -138
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +2 -6
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +157 -304
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +2 -6
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +164 -311
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +1 -5
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +36 -72
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +1 -5
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +78 -138
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/hub.d.ts +2 -6
  27. package/dist/device/hub.d.ts.map +1 -1
  28. package/dist/device/hub.js +30 -63
  29. package/dist/device/hub.js.map +1 -1
  30. package/dist/device/humidifier.d.ts +1 -5
  31. package/dist/device/humidifier.d.ts.map +1 -1
  32. package/dist/device/humidifier.js +115 -228
  33. package/dist/device/humidifier.js.map +1 -1
  34. package/dist/device/iosensor.d.ts +1 -5
  35. package/dist/device/iosensor.d.ts.map +1 -1
  36. package/dist/device/iosensor.js +38 -74
  37. package/dist/device/iosensor.js.map +1 -1
  38. package/dist/device/lock.d.ts +1 -5
  39. package/dist/device/lock.d.ts.map +1 -1
  40. package/dist/device/lock.js +66 -126
  41. package/dist/device/lock.js.map +1 -1
  42. package/dist/device/meter.d.ts +1 -5
  43. package/dist/device/meter.d.ts.map +1 -1
  44. package/dist/device/meter.js +38 -74
  45. package/dist/device/meter.js.map +1 -1
  46. package/dist/device/meterplus.d.ts +1 -5
  47. package/dist/device/meterplus.d.ts.map +1 -1
  48. package/dist/device/meterplus.js +39 -75
  49. package/dist/device/meterplus.js.map +1 -1
  50. package/dist/device/motion.d.ts +1 -5
  51. package/dist/device/motion.d.ts.map +1 -1
  52. package/dist/device/motion.js +35 -72
  53. package/dist/device/motion.js.map +1 -1
  54. package/dist/device/plug.d.ts +1 -5
  55. package/dist/device/plug.d.ts.map +1 -1
  56. package/dist/device/plug.js +65 -126
  57. package/dist/device/plug.js.map +1 -1
  58. package/dist/device/robotvacuumcleaner.d.ts +1 -5
  59. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  60. package/dist/device/robotvacuumcleaner.js +79 -151
  61. package/dist/device/robotvacuumcleaner.js.map +1 -1
  62. package/dist/device/striplight.d.ts +1 -9
  63. package/dist/device/striplight.d.ts.map +1 -1
  64. package/dist/device/striplight.js +137 -193
  65. package/dist/device/striplight.js.map +1 -1
  66. package/dist/irdevice/airconditioner.d.ts +3 -7
  67. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  68. package/dist/irdevice/airconditioner.js +34 -62
  69. package/dist/irdevice/airconditioner.js.map +1 -1
  70. package/dist/irdevice/airpurifier.d.ts +3 -7
  71. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  72. package/dist/irdevice/airpurifier.js +31 -59
  73. package/dist/irdevice/airpurifier.js.map +1 -1
  74. package/dist/irdevice/camera.d.ts +1 -5
  75. package/dist/irdevice/camera.d.ts.map +1 -1
  76. package/dist/irdevice/camera.js +30 -57
  77. package/dist/irdevice/camera.js.map +1 -1
  78. package/dist/irdevice/fan.d.ts +2 -6
  79. package/dist/irdevice/fan.d.ts.map +1 -1
  80. package/dist/irdevice/fan.js +39 -66
  81. package/dist/irdevice/fan.js.map +1 -1
  82. package/dist/irdevice/light.d.ts +1 -5
  83. package/dist/irdevice/light.d.ts.map +1 -1
  84. package/dist/irdevice/light.js +32 -59
  85. package/dist/irdevice/light.js.map +1 -1
  86. package/dist/irdevice/other.d.ts +1 -5
  87. package/dist/irdevice/other.d.ts.map +1 -1
  88. package/dist/irdevice/other.js +30 -57
  89. package/dist/irdevice/other.js.map +1 -1
  90. package/dist/irdevice/tv.d.ts +3 -7
  91. package/dist/irdevice/tv.d.ts.map +1 -1
  92. package/dist/irdevice/tv.js +46 -76
  93. package/dist/irdevice/tv.js.map +1 -1
  94. package/dist/irdevice/vacuumcleaner.d.ts +2 -6
  95. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  96. package/dist/irdevice/vacuumcleaner.js +30 -58
  97. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  98. package/dist/irdevice/waterheater.d.ts +7 -23
  99. package/dist/irdevice/waterheater.d.ts.map +1 -1
  100. package/dist/irdevice/waterheater.js +41 -74
  101. package/dist/irdevice/waterheater.js.map +1 -1
  102. package/dist/platform.d.ts +14 -5
  103. package/dist/platform.d.ts.map +1 -1
  104. package/dist/platform.js +153 -146
  105. package/dist/platform.js.map +1 -1
  106. package/dist/settings.d.ts +4 -0
  107. package/dist/settings.d.ts.map +1 -1
  108. package/dist/settings.js +5 -1
  109. package/dist/settings.js.map +1 -1
  110. package/nodemon.json +1 -1
  111. package/package.json +10 -10
  112. package/src/device/blindtilt.ts +122 -181
  113. package/src/device/bot.ts +96 -149
  114. package/src/device/ceilinglight.ts +172 -315
  115. package/src/device/colorbulb.ts +178 -324
  116. package/src/device/contact.ts +48 -78
  117. package/src/device/curtain.ts +93 -148
  118. package/src/device/hub.ts +34 -63
  119. package/src/device/humidifier.ts +135 -243
  120. package/src/device/iosensor.ts +49 -79
  121. package/src/device/lock.ts +78 -134
  122. package/src/device/meter.ts +48 -78
  123. package/src/device/meterplus.ts +50 -80
  124. package/src/device/motion.ts +46 -77
  125. package/src/device/plug.ts +76 -134
  126. package/src/device/robotvacuumcleaner.ts +91 -159
  127. package/src/device/striplight.ts +148 -200
  128. package/src/irdevice/airconditioner.ts +56 -81
  129. package/src/irdevice/airpurifier.ts +41 -67
  130. package/src/irdevice/camera.ts +35 -60
  131. package/src/irdevice/fan.ts +46 -71
  132. package/src/irdevice/light.ts +38 -63
  133. package/src/irdevice/other.ts +35 -60
  134. package/src/irdevice/tv.ts +52 -80
  135. package/src/irdevice/vacuumcleaner.ts +36 -62
  136. package/src/irdevice/waterheater.ts +46 -76
  137. package/src/platform.ts +143 -157
  138. package/src/settings.ts +5 -0
@@ -1,14 +1,11 @@
1
- import https from 'https';
2
- import crypto from 'crypto';
3
1
  import { Context } from 'vm';
2
+ import { request } from 'undici';
3
+ import { sleep } from '../utils';
4
4
  import { interval, Subject } from 'rxjs';
5
5
  import { skipWhile } from 'rxjs/operators';
6
- import superStringify from 'super-stringify';
7
6
  import { SwitchBotPlatform } from '../platform';
8
7
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
9
- import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
10
- import { IncomingMessage } from 'http';
11
- import { sleep } from '../utils';
8
+ import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, Devices } from '../settings';
12
9
 
13
10
  /**
14
11
  * Platform Accessory
@@ -162,7 +159,7 @@ export class Motion {
162
159
  } else {
163
160
  await this.offlineOff();
164
161
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
165
- + ` ${this.device.connectionType}, parseStatus will not happen.`);
162
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
166
163
  }
167
164
  }
168
165
 
@@ -187,7 +184,7 @@ export class Motion {
187
184
  this.CurrentAmbientLightLevel = this.set_maxLux;
188
185
  }
189
186
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
190
- ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
187
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
191
188
  if (this.CurrentAmbientLightLevel !== this.accessory.context.CurrentAmbientLightLevel) {
192
189
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
193
190
  }
@@ -203,7 +200,7 @@ export class Motion {
203
200
  this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
204
201
  }
205
202
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
206
- +` StatusLowBattery: ${this.StatusLowBattery}`);
203
+ + ` StatusLowBattery: ${this.StatusLowBattery}`);
207
204
  }
208
205
 
209
206
  async openAPIparseStatus(): Promise<void> {
@@ -240,7 +237,7 @@ export class Motion {
240
237
  } else {
241
238
  await this.offlineOff();
242
239
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
243
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
240
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
244
241
  }
245
242
  }
246
243
 
@@ -272,7 +269,7 @@ export class Motion {
272
269
  switchbot.onadvertisement = async (ad: any) => {
273
270
  this.address = ad.address;
274
271
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
275
- + ` BLE Address Found: ${this.address}`);
272
+ + ` BLE Address Found: ${this.address}`);
276
273
  this.serviceData = ad.serviceData;
277
274
  this.movement = ad.serviceData.movement;
278
275
  this.tested = ad.serviceData.tested;
@@ -282,10 +279,10 @@ export class Motion {
282
279
  this.sense_distance = ad.serviceData.sense_distance;
283
280
  this.lightLevel = ad.serviceData.lightLevel;
284
281
  this.is_light = ad.serviceData.is_light;
285
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
282
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
286
283
  this.debugLog(
287
284
  `${this.device.deviceType}: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, is_light: ` +
288
- `${ad.serviceData.is_light}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`,
285
+ `${ad.serviceData.is_light}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`,
289
286
  );
290
287
 
291
288
  if (this.serviceData) {
@@ -316,7 +313,7 @@ export class Motion {
316
313
  .catch(async (e: any) => {
317
314
  this.apiError(e);
318
315
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
319
- + ` Connection, Error Message: ${superStringify(e.message)}`);
316
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
320
317
  this.debugErrorLog('3');
321
318
  await this.BLERefreshConnection(switchbot);
322
319
  });
@@ -329,54 +326,25 @@ export class Motion {
329
326
  async openAPIRefreshStatus(): Promise<void> {
330
327
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
331
328
  try {
332
- const t = Date.now();
333
- const nonce = 'requestID';
334
- const data = this.platform.config.credentials?.token + t + nonce;
335
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
336
- const sign = signTerm.toString('base64');
337
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
338
- const options = {
339
- hostname: HostDomain,
340
- port: 443,
341
- path: `${DevicePath}/${this.device.deviceId}/status`,
342
- method: 'GET',
343
- headers: {
344
- Authorization: this.platform.config.credentials?.token,
345
- sign: sign,
346
- nonce: nonce,
347
- t: t,
348
- 'Content-Type': 'application/json',
349
- },
350
- };
351
- const req = https.request(options, (res) => {
352
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
353
- this.statusCode({ res });
354
- let rawData = '';
355
- res.on('data', (d) => {
356
- rawData += d;
357
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
358
- });
359
- res.on('end', () => {
360
- try {
361
- this.deviceStatus = JSON.parse(rawData);
362
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
363
- this.moveDetected = this.deviceStatus.body.moveDetected;
364
- this.brightness = this.deviceStatus.body.brightness;
365
- this.openAPIparseStatus();
366
- this.updateHomeKitCharacteristics();
367
- } catch (e: any) {
368
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
369
- }
370
- });
371
- });
372
- req.on('error', (e: any) => {
373
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
329
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
330
+ headers: this.platform.generateHeaders(),
374
331
  });
375
- req.end();
332
+ const deviceStatus = await body.json();
333
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
334
+ this.statusCode(statusCode);
335
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
336
+ this.debugLog(
337
+ `${this.device.deviceType}: ${this.accessory.displayName
338
+ } refreshStatus: ${JSON.stringify(deviceStatus)}`,
339
+ );
340
+ this.moveDetected = deviceStatus.body.moveDetected;
341
+ this.brightness = deviceStatus.body.brightness;
342
+ this.openAPIparseStatus();
343
+ this.updateHomeKitCharacteristics();
376
344
  } catch (e: any) {
377
345
  this.apiError(e);
378
346
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
379
- + ` Connection, Error Message: ${superStringify(e.message)}`);
347
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
380
348
  }
381
349
  }
382
350
 
@@ -438,7 +406,7 @@ export class Motion {
438
406
  });
439
407
  // Set an event handler
440
408
  switchbot.onadvertisement = (ad: any) => {
441
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
409
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
442
410
  };
443
411
  await sleep(10000);
444
412
  // Stop to monitor
@@ -507,40 +475,41 @@ export class Motion {
507
475
  }
508
476
  }
509
477
 
510
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
511
- switch (res.statusCode) {
478
+ async statusCode(statusCode: number): Promise<void> {
479
+ switch (statusCode) {
512
480
  case 151:
513
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
481
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
514
482
  break;
515
483
  case 152:
516
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
484
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
517
485
  break;
518
486
  case 160:
519
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
487
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
520
488
  break;
521
489
  case 161:
522
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
523
- await this.offlineOff();
490
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
491
+ this.offlineOff();
524
492
  break;
525
493
  case 171:
526
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
527
- await this.offlineOff();
494
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
495
+ + `Hub: ${this.device.hubDeviceId}`);
496
+ this.offlineOff();
528
497
  break;
529
498
  case 190:
530
499
  this.errorLog(
531
500
  `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
532
- ` Or command: ${superStringify(res)} format is invalid`,
501
+ ` Or command format is invalid, statusCode: ${statusCode}`,
533
502
  );
534
503
  break;
535
504
  case 100:
536
- if (this.platform.debugMode) {
537
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
538
- }
505
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
506
+ break;
507
+ case 200:
508
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
539
509
  break;
540
510
  default:
541
- if (this.platform.debugMode) {
542
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
543
- }
511
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
512
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
544
513
  }
545
514
  }
546
515
 
@@ -563,7 +532,7 @@ export class Motion {
563
532
  FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
564
533
  let FirmwareRevision: string;
565
534
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
566
- + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
535
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
567
536
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
568
537
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
569
538
  if (accessory.context.FirmwareRevision) {
@@ -618,7 +587,7 @@ export class Motion {
618
587
  config['offline'] = device.offline;
619
588
  }
620
589
  if (Object.entries(config).length !== 0) {
621
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
590
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
622
591
  }
623
592
  }
624
593
 
@@ -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 } from 'homebridge';
10
- import { device, devicesConfig, deviceStatus, ad, serviceData, switchbot, HostDomain, DevicePath } from '../settings';
11
- import { sleep } from '../utils';
8
+ import { device, devicesConfig, deviceStatus, ad, serviceData, switchbot, Devices } from '../settings';
12
9
 
13
10
  export class Plug {
14
11
  // Services
@@ -118,7 +115,7 @@ export class Plug {
118
115
  } catch (e: any) {
119
116
  this.apiError(e);
120
117
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
121
- + ` Error Message: ${superStringify(e.message)}`);
118
+ + ` Error Message: ${JSON.stringify(e.message)}`);
122
119
  }
123
120
  this.plugUpdateInProgress = false;
124
121
  });
@@ -137,7 +134,7 @@ export class Plug {
137
134
  } else {
138
135
  await this.offlineOff();
139
136
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
140
- + ` ${this.device.connectionType}, parseStatus will not happen.`);
137
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
141
138
  }
142
139
  }
143
140
 
@@ -179,7 +176,7 @@ export class Plug {
179
176
  } else {
180
177
  await this.offlineOff();
181
178
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
182
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
179
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
183
180
  }
184
181
  }
185
182
 
@@ -205,7 +202,7 @@ export class Plug {
205
202
  switchbot.onadvertisement = async (ad: any) => {
206
203
  this.address = ad.address;
207
204
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
208
- + ` BLE Address Found: ${this.address}`);
205
+ + ` BLE Address Found: ${this.address}`);
209
206
  this.serviceData = ad.serviceData;
210
207
  this.state = ad.serviceData.state;
211
208
  this.delay = ad.serviceData.delay;
@@ -214,11 +211,11 @@ export class Plug {
214
211
  this.wifiRssi = ad.serviceData.wifiRssi;
215
212
  this.overload = ad.serviceData.overload;
216
213
  this.currentPower = ad.serviceData.currentPower;
217
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
214
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
218
215
  this.debugLog(
219
216
  `${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
220
- `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
221
- `wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
217
+ `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
218
+ `wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
222
219
  );
223
220
 
224
221
  if (this.serviceData) {
@@ -240,7 +237,7 @@ export class Plug {
240
237
  .catch(async (e: any) => {
241
238
  this.apiError(e);
242
239
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
243
- + ` Connection, Error Message: ${superStringify(e.message)}`);
240
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
244
241
  await this.BLERefreshConnection(switchbot);
245
242
  });
246
243
  } else {
@@ -251,53 +248,24 @@ export class Plug {
251
248
  async openAPIRefreshStatus() {
252
249
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
253
250
  try {
254
- const t = Date.now();
255
- const nonce = 'requestID';
256
- const data = this.platform.config.credentials?.token + t + nonce;
257
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
258
- const sign = signTerm.toString('base64');
259
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
260
- const options = {
261
- hostname: HostDomain,
262
- port: 443,
263
- path: `${DevicePath}/${this.device.deviceId}/status`,
264
- method: 'GET',
265
- headers: {
266
- Authorization: this.platform.config.credentials?.token,
267
- sign: sign,
268
- nonce: nonce,
269
- t: t,
270
- 'Content-Type': 'application/json',
271
- },
272
- };
273
- const req = https.request(options, (res) => {
274
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
275
- this.statusCode({ res });
276
- let rawData = '';
277
- res.on('data', (d) => {
278
- rawData += d;
279
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
280
- });
281
- res.on('end', () => {
282
- try {
283
- this.deviceStatus = JSON.parse(rawData);
284
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
285
- this.power = this.deviceStatus.body.power;
286
- this.openAPIparseStatus();
287
- this.updateHomeKitCharacteristics();
288
- } catch (e: any) {
289
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
290
- }
291
- });
292
- });
293
- req.on('error', (e: any) => {
294
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
251
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
252
+ headers: this.platform.generateHeaders(),
295
253
  });
296
- req.end();
254
+ const deviceStatus = await body.json();
255
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
256
+ this.statusCode(statusCode);
257
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
258
+ this.debugLog(
259
+ `${this.device.deviceType}: ${this.accessory.displayName
260
+ } refreshStatus: ${JSON.stringify(deviceStatus)}`,
261
+ );
262
+ this.power = deviceStatus.body.power;
263
+ this.openAPIparseStatus();
264
+ this.updateHomeKitCharacteristics();
297
265
  } catch (e: any) {
298
266
  this.apiError(e);
299
267
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
300
- + ` Connection, Error Message: ${superStringify(e.message)}`);
268
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
301
269
  }
302
270
  }
303
271
 
@@ -321,7 +289,7 @@ export class Plug {
321
289
  } else {
322
290
  await this.offlineOff();
323
291
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
324
- + ` ${this.device.connectionType}, pushChanges will not happen.`);
292
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
325
293
  }
326
294
  // Refresh the status from the API
327
295
  interval(15000)
@@ -368,81 +336,50 @@ export class Plug {
368
336
  .catch(async (e: any) => {
369
337
  this.apiError(e);
370
338
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
371
- + ` Connection, Error Message: ${superStringify(e.message)}`);
339
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
372
340
  await this.BLEPushConnection();
373
341
  });
374
342
  } else {
375
343
  this.debugLog(
376
344
  `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, `
377
- +`OnCached: ${this.accessory.context.On}`,
345
+ + `OnCached: ${this.accessory.context.On}`,
378
346
  );
379
347
  }
380
348
  }
381
349
 
382
350
  async openAPIpushChanges() {
383
- try {
384
- if (this.On !== this.accessory.context.On) {
385
- // Make Push On request to the API
386
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
387
- const t = Date.now();
388
- const nonce = 'requestID';
389
- const data = this.platform.config.credentials?.token + t + nonce;
390
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
391
- .update(Buffer.from(data, 'utf-8'))
392
- .digest();
393
- const sign = signTerm.toString('base64');
394
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
395
-
396
- let command = '';
397
- if (this.On) {
398
- command = 'turnOn';
399
- } else {
400
- command = 'turnOff';
401
- }
402
- const body = superStringify({
403
- 'command': `${command}`,
404
- 'parameter': 'default',
405
- 'commandType': 'command',
406
- });
407
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
408
- const options = {
409
- hostname: HostDomain,
410
- port: 443,
411
- path: `${DevicePath}/${this.device.deviceId}/commands`,
351
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
352
+ if (this.On !== this.accessory.context.On) {
353
+ let command = '';
354
+ if (this.On) {
355
+ command = 'turnOn';
356
+ } else {
357
+ command = 'turnOff';
358
+ }
359
+ const body = JSON.stringify({
360
+ 'command': `${command}`,
361
+ 'parameter': 'default',
362
+ 'commandType': 'command',
363
+ });
364
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
365
+ try {
366
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
412
367
  method: 'POST',
413
- headers: {
414
- 'Authorization': this.platform.config.credentials?.token,
415
- 'sign': sign,
416
- 'nonce': nonce,
417
- 't': t,
418
- 'Content-Type': 'application/json',
419
- 'Content-Length': body.length,
420
- },
421
- };
422
- const req = https.request(options, res => {
423
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
424
- this.statusCode({ res });
425
- res.on('data', d => {
426
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
427
- });
428
- });
429
- req.on('error', (e: any) => {
430
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
368
+ headers: this.platform.generateHeaders(),
431
369
  });
432
- req.write(body);
433
- req.end();
434
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges: ${superStringify(req)}`);
435
- } else {
436
- this.debugLog(
437
- `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `On: ${this.On}, `
438
- +`OnCached: ${this.accessory.context.On}`,
370
+ const deviceStatus = await body.json();
371
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
372
+ this.statusCode(statusCode);
373
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
374
+ } catch (e: any) {
375
+ this.apiError(e);
376
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
377
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`,
439
378
  );
440
379
  }
441
- } catch (e: any) {
442
- this.apiError(e);
443
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
444
- + ` Connection, Error Message: ${superStringify(e.message)}`,
445
- );
380
+ } else {
381
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `On: ${this.On}, `
382
+ + `OnCached: ${this.accessory.context.On}`);
446
383
  }
447
384
  }
448
385
 
@@ -497,7 +434,7 @@ export class Plug {
497
434
  });
498
435
  // Set an event handler
499
436
  switchbot.onadvertisement = (ad: any) => {
500
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
437
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
501
438
  };
502
439
  await sleep(10000);
503
440
  // Stop to monitor
@@ -567,36 +504,41 @@ export class Plug {
567
504
  }
568
505
  }
569
506
 
570
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
571
- switch (res.statusCode) {
507
+ async statusCode(statusCode: number): Promise<void> {
508
+ switch (statusCode) {
572
509
  case 151:
573
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
510
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
574
511
  break;
575
512
  case 152:
576
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
513
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
577
514
  break;
578
515
  case 160:
579
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
516
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
580
517
  break;
581
518
  case 161:
582
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
583
- await this.offlineOff();
519
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
520
+ this.offlineOff();
584
521
  break;
585
522
  case 171:
586
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
587
- await this.offlineOff();
523
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
524
+ + `Hub: ${this.device.hubDeviceId}`);
525
+ this.offlineOff();
588
526
  break;
589
527
  case 190:
590
528
  this.errorLog(
591
529
  `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
592
- ` Or command: ${superStringify(res)} format is invalid`,
530
+ ` Or command format is invalid, statusCode: ${statusCode}`,
593
531
  );
594
532
  break;
595
533
  case 100:
596
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
534
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
535
+ break;
536
+ case 200:
537
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
597
538
  break;
598
539
  default:
599
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
540
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
541
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
600
542
  }
601
543
  }
602
544
 
@@ -614,7 +556,7 @@ export class Plug {
614
556
  FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
615
557
  let FirmwareRevision: string;
616
558
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
617
- +` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
559
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
618
560
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
619
561
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
620
562
  if (accessory.context.FirmwareRevision) {
@@ -672,7 +614,7 @@ export class Plug {
672
614
  config['maxRetry'] = device.maxRetry;
673
615
  }
674
616
  if (Object.entries(config).length !== 0) {
675
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
617
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
676
618
  }
677
619
  }
678
620