@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,17 +1,14 @@
1
- import https from 'https';
2
- import crypto from 'crypto';
3
1
  import { Context } from 'vm';
4
2
  import { hostname } from 'os';
3
+ import { request } from 'undici';
4
+ import { sleep } from '../utils';
5
5
  import { MqttClient } from 'mqtt';
6
6
  import { connectAsync } from 'async-mqtt';
7
7
  import { interval, Subject } from 'rxjs';
8
8
  import { skipWhile } from 'rxjs/operators';
9
- import superStringify from 'super-stringify';
10
9
  import { SwitchBotPlatform } from '../platform';
11
10
  import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
12
- import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, HostDomain, DevicePath } from '../settings';
13
- import { IncomingMessage } from 'http';
14
- import { sleep } from '../utils';
11
+ import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, Devices } from '../settings';
15
12
 
16
13
  /**
17
14
  * Platform Accessory
@@ -186,7 +183,7 @@ export class IOSensor {
186
183
  } else {
187
184
  await this.offlineOff();
188
185
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
189
- + ` ${this.device.connectionType}, parseStatus will not happen.`);
186
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
190
187
  }
191
188
  }
192
189
 
@@ -254,7 +251,7 @@ export class IOSensor {
254
251
  } else {
255
252
  await this.offlineOff();
256
253
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
257
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
254
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
258
255
  }
259
256
  }
260
257
 
@@ -280,7 +277,7 @@ export class IOSensor {
280
277
  switchbot.onadvertisement = async (ad: ad) => {
281
278
  this.address = ad.address;
282
279
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
283
- + ` BLE Address Found: ${this.address}`);
280
+ + ` BLE Address Found: ${this.address}`);
284
281
  if (ad.serviceData.humidity! > 0) {
285
282
  // reject unreliable data
286
283
  this.humidity = ad.serviceData.humidity;
@@ -290,11 +287,11 @@ export class IOSensor {
290
287
  this.celsius = ad.serviceData.temperature!.c;
291
288
  this.fahrenheit = ad.serviceData.temperature!.f;
292
289
  this.battery = ad.serviceData.battery;
293
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
290
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
294
291
  this.debugLog(
295
292
  `${this.device.deviceType}: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
296
- `temperature: ${superStringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
297
- `battery: ${ad.serviceData.battery}`,
293
+ `temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
294
+ `battery: ${ad.serviceData.battery}`,
298
295
  );
299
296
 
300
297
  if (this.serviceData) {
@@ -316,7 +313,7 @@ export class IOSensor {
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
  await this.BLERefreshConnection(switchbot);
321
318
  });
322
319
  } else {
@@ -327,54 +324,26 @@ export class IOSensor {
327
324
  async openAPIRefreshStatus(): Promise<void> {
328
325
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
329
326
  try {
330
- const t = Date.now();
331
- const nonce = 'requestID';
332
- const data = this.platform.config.credentials?.token + t + nonce;
333
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
334
- const sign = signTerm.toString('base64');
335
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
336
- const options = {
337
- hostname: HostDomain,
338
- port: 443,
339
- path: `${DevicePath}/${this.device.deviceId}/status`,
340
- method: 'GET',
341
- headers: {
342
- Authorization: this.platform.config.credentials?.token,
343
- sign: sign,
344
- nonce: nonce,
345
- t: t,
346
- 'Content-Type': 'application/json',
347
- },
348
- };
349
- const req = https.request(options, (res) => {
350
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
351
- let rawData = '';
352
- res.on('data', (d) => {
353
- rawData += d;
354
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
355
- });
356
- res.on('end', () => {
357
- try {
358
- this.deviceStatus = JSON.parse(rawData);
359
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
360
- this.Humidity = this.deviceStatus.body.humidity!;
361
- this.Temperature = this.deviceStatus.body.temperature!;
362
- this.Battery = this.deviceStatus.body.battery!;
363
- this.parseStatus();
364
- this.updateHomeKitCharacteristics();
365
- } catch (e: any) {
366
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
367
- }
368
- });
369
- });
370
- req.on('error', (e: any) => {
371
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
327
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
328
+ headers: this.platform.generateHeaders(),
372
329
  });
373
- req.end();
330
+ const deviceStatus = await body.json();
331
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
332
+ this.statusCode(statusCode);
333
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
334
+ this.debugLog(
335
+ `${this.device.deviceType}: ${this.accessory.displayName
336
+ } refreshStatus: ${JSON.stringify(deviceStatus)}`,
337
+ );
338
+ this.Humidity = deviceStatus.body.humidity!;
339
+ this.Temperature = deviceStatus.body.temperature!;
340
+ this.Battery = deviceStatus.body.battery!;
341
+ this.openAPIparseStatus();
342
+ this.updateHomeKitCharacteristics();
374
343
  } catch (e: any) {
375
344
  this.apiError(e);
376
345
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
377
- + ` Connection, Error Message: ${superStringify(e.message)}`);
346
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
378
347
  }
379
348
  }
380
349
 
@@ -391,7 +360,7 @@ export class IOSensor {
391
360
  this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
392
361
  this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
393
362
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
394
- + ` updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
363
+ + ` updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
395
364
  if (this.device.mqttURL) {
396
365
  mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
397
366
  }
@@ -407,7 +376,7 @@ export class IOSensor {
407
376
  if (this.device.mqttURL) {
408
377
  mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
409
378
  }
410
- if (this.device.history){
379
+ if (this.device.history) {
411
380
  entry['temp'] = this.CurrentTemperature;
412
381
  }
413
382
  this.accessory.context.CurrentTemperature = this.CurrentTemperature;
@@ -457,7 +426,7 @@ export class IOSensor {
457
426
  ?.join(':');
458
427
  const options = this.device.mqttPubOptions || {};
459
428
  this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
460
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${superStringify(options)}`);
429
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
461
430
  }
462
431
 
463
432
  /*
@@ -514,7 +483,7 @@ export class IOSensor {
514
483
  });
515
484
  // Set an event handler
516
485
  switchbot.onadvertisement = (ad: any) => {
517
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
486
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
518
487
  };
519
488
  await sleep(10000);
520
489
  // Stop to monitor
@@ -545,40 +514,41 @@ export class IOSensor {
545
514
  }
546
515
  }
547
516
 
548
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
549
- switch (res.statusCode) {
517
+ async statusCode(statusCode: number): Promise<void> {
518
+ switch (statusCode) {
550
519
  case 151:
551
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
520
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
552
521
  break;
553
522
  case 152:
554
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
523
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
555
524
  break;
556
525
  case 160:
557
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
526
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
558
527
  break;
559
528
  case 161:
560
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
561
- await this.offlineOff();
529
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
530
+ this.offlineOff();
562
531
  break;
563
532
  case 171:
564
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
565
- await this.offlineOff();
533
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
534
+ + `Hub: ${this.device.hubDeviceId}`);
535
+ this.offlineOff();
566
536
  break;
567
537
  case 190:
568
538
  this.errorLog(
569
539
  `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
570
- ` Or command: ${superStringify(res)} format is invalid`,
540
+ ` Or command format is invalid, statusCode: ${statusCode}`,
571
541
  );
572
542
  break;
573
543
  case 100:
574
- if (this.platform.debugMode) {
575
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
576
- }
544
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
545
+ break;
546
+ case 200:
547
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
577
548
  break;
578
549
  default:
579
- if (this.platform.debugMode) {
580
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
581
- }
550
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
551
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
582
552
  }
583
553
  }
584
554
 
@@ -603,7 +573,7 @@ export class IOSensor {
603
573
  FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
604
574
  let FirmwareRevision: string;
605
575
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
606
- + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
576
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
607
577
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
608
578
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
609
579
  if (accessory.context.FirmwareRevision) {
@@ -674,7 +644,7 @@ export class IOSensor {
674
644
  config['scanDuration'] = device.scanDuration;
675
645
  }
676
646
  if (Object.entries(config).length !== 0) {
677
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
647
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
678
648
  }
679
649
  }
680
650
 
@@ -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, HostDomain, DevicePath, switchbot, ad, serviceData } from '../settings';
11
- import { sleep } from '../utils';
8
+ import { device, devicesConfig, deviceStatus, switchbot, ad, serviceData, Devices } from '../settings';
12
9
 
13
10
  export class Lock {
14
11
  // Services
@@ -144,7 +141,7 @@ export class Lock {
144
141
  } catch (e: any) {
145
142
  this.apiError(e);
146
143
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
147
- + ` Error Message: ${superStringify(e.message)}`);
144
+ + ` Error Message: ${JSON.stringify(e.message)}`);
148
145
  }
149
146
  this.lockUpdateInProgress = false;
150
147
  });
@@ -163,7 +160,7 @@ export class Lock {
163
160
  } else {
164
161
  await this.offlineOff();
165
162
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
166
- + ` ${this.device.connectionType}, parseStatus will not happen.`);
163
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
167
164
  }
168
165
  }
169
166
 
@@ -222,7 +219,7 @@ export class Lock {
222
219
  } else {
223
220
  await this.offlineOff();
224
221
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
225
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
222
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
226
223
  }
227
224
  }
228
225
 
@@ -248,7 +245,7 @@ export class Lock {
248
245
  switchbot.onadvertisement = async (ad: any) => {
249
246
  this.address = ad.address;
250
247
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
251
- + ` BLE Address Found: ${this.address}`);
248
+ + ` BLE Address Found: ${this.address}`);
252
249
  this.serviceData = ad.serviceData;
253
250
  this.battery = ad.serviceData.battery;
254
251
  this.calibration = ad.serviceData.calibration;
@@ -259,11 +256,11 @@ export class Lock {
259
256
  this.unclosed_alarm = ad.serviceData.unclosed_alarm;
260
257
  this.unlocked_alarm = ad.serviceData.unlocked_alarm;
261
258
  this.auto_lock_paused = ad.serviceData.auto_lock_paused;
262
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
259
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
263
260
  this.debugLog(
264
261
  `${this.device.deviceType}: ${this.accessory.displayName} battery: ${ad.serviceData.battery}, ` +
265
- `calibration: ${ad.serviceData.calibration}, status: ${ad.serviceData.status}, battery: ${ad.serviceData.battery}, ` +
266
- `door_open: ${ad.serviceData.door_open}`);
262
+ `calibration: ${ad.serviceData.calibration}, status: ${ad.serviceData.status}, battery: ${ad.serviceData.battery}, ` +
263
+ `door_open: ${ad.serviceData.door_open}`);
267
264
 
268
265
  if (this.serviceData) {
269
266
  this.connected = true;
@@ -284,7 +281,7 @@ export class Lock {
284
281
  .catch(async (e: any) => {
285
282
  this.apiError(e);
286
283
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
287
- + ` Connection, Error Message: ${superStringify(e.message)}`);
284
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
288
285
  await this.BLERefreshConnection(switchbot);
289
286
  });
290
287
  } else {
@@ -295,53 +292,25 @@ export class Lock {
295
292
  async openAPIRefreshStatus(): Promise<void> {
296
293
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
297
294
  try {
298
- const t = Date.now();
299
- const nonce = 'requestID';
300
- const data = this.platform.config.credentials?.token + t + nonce;
301
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
302
- const sign = signTerm.toString('base64');
303
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
304
- const options = {
305
- hostname: HostDomain,
306
- port: 443,
307
- path: `${DevicePath}/${this.device.deviceId}/status`,
308
- method: 'GET',
309
- headers: {
310
- Authorization: this.platform.config.credentials?.token,
311
- sign: sign,
312
- nonce: nonce,
313
- t: t,
314
- 'Content-Type': 'application/json',
315
- },
316
- };
317
- const req = https.request(options, (res) => {
318
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
319
- let rawData = '';
320
- res.on('data', (d) => {
321
- rawData += d;
322
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
323
- });
324
- res.on('end', () => {
325
- try {
326
- this.deviceStatus = JSON.parse(rawData);
327
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
328
- this.lockState = this.deviceStatus.body.lockState;
329
- this.doorState = this.deviceStatus.body.doorState;
330
- this.openAPIparseStatus();
331
- this.updateHomeKitCharacteristics();
332
- } catch (e: any) {
333
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
334
- }
335
- });
336
- });
337
- req.on('error', (e: any) => {
338
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
295
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
296
+ headers: this.platform.generateHeaders(),
339
297
  });
340
- req.end();
298
+ const deviceStatus = await body.json();
299
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
300
+ this.statusCode(statusCode);
301
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
302
+ this.debugLog(
303
+ `${this.device.deviceType}: ${this.accessory.displayName
304
+ } refreshStatus: ${JSON.stringify(deviceStatus)}`,
305
+ );
306
+ this.lockState = deviceStatus.body.lockState;
307
+ this.doorState = deviceStatus.body.doorState;
308
+ this.openAPIparseStatus();
309
+ this.updateHomeKitCharacteristics();
341
310
  } catch (e: any) {
342
311
  this.apiError(e);
343
312
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
344
- + ` Connection, Error Message: ${superStringify(e.message)}`);
313
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
345
314
  }
346
315
  }
347
316
 
@@ -361,7 +330,7 @@ export class Lock {
361
330
  } else {
362
331
  await this.offlineOff();
363
332
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
364
- + ` ${this.device.connectionType}, pushChanges will not happen.`);
333
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
365
334
  }
366
335
  // Refresh the status from the API
367
336
  interval(15000)
@@ -376,7 +345,7 @@ export class Lock {
376
345
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
377
346
  if (this.LockTargetState !== this.accessory.context.LockTargetState) {
378
347
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges LockTargetState: ${this.LockTargetState}`
379
- + ` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
348
+ + ` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
380
349
  const switchbot = await this.platform.connectBLE();
381
350
  // Convert to BLE Address
382
351
  this.device.bleMac = this.device
@@ -396,80 +365,50 @@ export class Lock {
396
365
  .catch(async (e: any) => {
397
366
  this.apiError(e);
398
367
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
399
- + ` Connection, Error Message: ${superStringify(e.message)}`);
368
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
400
369
  await this.BLEPushConnection();
401
370
  });
402
371
  } else {
403
372
  this.debugLog(
404
373
  `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `LockTargetState: ${this.LockTargetState}, `
405
- +`LockTargetStateCached: ${this.accessory.context.LockTargetState}`,
374
+ + `LockTargetStateCached: ${this.accessory.context.LockTargetState}`,
406
375
  );
407
376
  }
408
377
  }
409
378
 
410
379
  async openAPIpushChanges(): Promise<void> {
411
- try {
412
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
413
- if (this.LockTargetState !== this.accessory.context.LockTargetState) {
414
- // Make Push On request to the API
415
- const t = Date.now();
416
- const nonce = 'requestID';
417
- const data = this.platform.config.credentials?.token + t + nonce;
418
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
419
- .update(Buffer.from(data, 'utf-8'))
420
- .digest();
421
- const sign = signTerm.toString('base64');
422
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
423
- let command = '';
424
- if (this.LockTargetState) {
425
- command = 'lock';
426
- } else {
427
- command = 'unlock';
428
- }
429
- const body = superStringify({
430
- 'command': `${command}`,
431
- 'parameter': 'default',
432
- 'commandType': 'command',
433
- });
434
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
435
- const options = {
436
- hostname: HostDomain,
437
- port: 443,
438
- path: `${DevicePath}/${this.device.deviceId}/commands`,
380
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
381
+ if (this.LockTargetState !== this.accessory.context.LockTargetState) {
382
+ let command = '';
383
+ if (this.LockTargetState) {
384
+ command = 'lock';
385
+ } else {
386
+ command = 'unlock';
387
+ }
388
+ const body = JSON.stringify({
389
+ 'command': `${command}`,
390
+ 'parameter': 'default',
391
+ 'commandType': 'command',
392
+ });
393
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
394
+ try {
395
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
439
396
  method: 'POST',
440
- headers: {
441
- 'Authorization': this.platform.config.credentials?.token,
442
- 'sign': sign,
443
- 'nonce': nonce,
444
- 't': t,
445
- 'Content-Type': 'application/json',
446
- 'Content-Length': body.length,
447
- },
448
- };
449
- const req = https.request(options, res => {
450
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
451
- this.statusCode({ res });
452
- res.on('data', d => {
453
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
454
- });
455
- });
456
- req.on('error', (e: any) => {
457
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
397
+ headers: this.platform.generateHeaders(),
458
398
  });
459
- req.write(body);
460
- req.end();
461
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges: ${superStringify(req)}`);
462
- } else {
463
- this.debugLog(
464
- `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `LockTargetState: ${this.LockTargetState}, `
465
- +`LockTargetStateCached: ${this.accessory.context.LockTargetState}`,
399
+ const deviceStatus = await body.json();
400
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
401
+ this.statusCode(statusCode);
402
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
403
+ } catch (e: any) {
404
+ this.apiError(e);
405
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
406
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`,
466
407
  );
467
408
  }
468
- } catch (e: any) {
469
- this.apiError(e);
470
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
471
- + ` Connection, Error Message: ${superStringify(e.message)}`,
472
- );
409
+ } else {
410
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `LockTargetState: ${this.LockTargetState}, `
411
+ + `LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
473
412
  }
474
413
  }
475
414
 
@@ -532,7 +471,7 @@ export class Lock {
532
471
  });
533
472
  // Set an event handler
534
473
  switchbot.onadvertisement = (ad: any) => {
535
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
474
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
536
475
  };
537
476
  await sleep(10000);
538
477
  // Stop to monitor
@@ -570,36 +509,41 @@ export class Lock {
570
509
  }
571
510
  }
572
511
 
573
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
574
- switch (res.statusCode) {
512
+ async statusCode(statusCode: number): Promise<void> {
513
+ switch (statusCode) {
575
514
  case 151:
576
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
515
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
577
516
  break;
578
517
  case 152:
579
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
518
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
580
519
  break;
581
520
  case 160:
582
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
521
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
583
522
  break;
584
523
  case 161:
585
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
586
- await this.offlineOff();
524
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
525
+ this.offlineOff();
587
526
  break;
588
527
  case 171:
589
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
590
- await this.offlineOff();
528
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
529
+ + `Hub: ${this.device.hubDeviceId}`);
530
+ this.offlineOff();
591
531
  break;
592
532
  case 190:
593
533
  this.errorLog(
594
534
  `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
595
- ` Or command: ${superStringify(res)} format is invalid`,
535
+ ` Or command format is invalid, statusCode: ${statusCode}`,
596
536
  );
597
537
  break;
598
538
  case 100:
599
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
539
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
540
+ break;
541
+ case 200:
542
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
600
543
  break;
601
544
  default:
602
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
545
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
546
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
603
547
  }
604
548
  }
605
549
 
@@ -621,7 +565,7 @@ export class Lock {
621
565
  FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
622
566
  let FirmwareRevision: string;
623
567
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
624
- + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
568
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
625
569
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
626
570
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
627
571
  if (accessory.context.FirmwareRevision) {
@@ -673,7 +617,7 @@ export class Lock {
673
617
  config['scanDuration'] = device.scanDuration;
674
618
  }
675
619
  if (Object.entries(config).length !== 0) {
676
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
620
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
677
621
  }
678
622
  }
679
623