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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/.vscode/tasks.json +13 -0
  2. package/CHANGELOG.md +4 -2
  3. package/README.md +18 -9
  4. package/dist/device/blindtilt.d.ts +1 -5
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +80 -140
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +1 -5
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +79 -138
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +2 -6
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +157 -304
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +2 -6
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +164 -311
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +1 -5
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +36 -72
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +1 -5
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +78 -138
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/hub.d.ts +2 -6
  29. package/dist/device/hub.d.ts.map +1 -1
  30. package/dist/device/hub.js +30 -63
  31. package/dist/device/hub.js.map +1 -1
  32. package/dist/device/humidifier.d.ts +1 -5
  33. package/dist/device/humidifier.d.ts.map +1 -1
  34. package/dist/device/humidifier.js +115 -228
  35. package/dist/device/humidifier.js.map +1 -1
  36. package/dist/device/iosensor.d.ts +1 -5
  37. package/dist/device/iosensor.d.ts.map +1 -1
  38. package/dist/device/iosensor.js +38 -74
  39. package/dist/device/iosensor.js.map +1 -1
  40. package/dist/device/{striplight.d.ts → lightstrip.d.ts} +2 -10
  41. package/dist/device/lightstrip.d.ts.map +1 -0
  42. package/dist/device/{striplight.js → lightstrip.js} +138 -194
  43. package/dist/device/lightstrip.js.map +1 -0
  44. package/dist/device/lock.d.ts +1 -5
  45. package/dist/device/lock.d.ts.map +1 -1
  46. package/dist/device/lock.js +66 -126
  47. package/dist/device/lock.js.map +1 -1
  48. package/dist/device/meter.d.ts +1 -5
  49. package/dist/device/meter.d.ts.map +1 -1
  50. package/dist/device/meter.js +38 -74
  51. package/dist/device/meter.js.map +1 -1
  52. package/dist/device/meterplus.d.ts +1 -5
  53. package/dist/device/meterplus.d.ts.map +1 -1
  54. package/dist/device/meterplus.js +39 -75
  55. package/dist/device/meterplus.js.map +1 -1
  56. package/dist/device/motion.d.ts +1 -5
  57. package/dist/device/motion.d.ts.map +1 -1
  58. package/dist/device/motion.js +35 -72
  59. package/dist/device/motion.js.map +1 -1
  60. package/dist/device/plug.d.ts +1 -5
  61. package/dist/device/plug.d.ts.map +1 -1
  62. package/dist/device/plug.js +65 -126
  63. package/dist/device/plug.js.map +1 -1
  64. package/dist/device/robotvacuumcleaner.d.ts +1 -5
  65. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  66. package/dist/device/robotvacuumcleaner.js +79 -151
  67. package/dist/device/robotvacuumcleaner.js.map +1 -1
  68. package/dist/irdevice/airconditioner.d.ts +3 -7
  69. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  70. package/dist/irdevice/airconditioner.js +34 -62
  71. package/dist/irdevice/airconditioner.js.map +1 -1
  72. package/dist/irdevice/airpurifier.d.ts +3 -7
  73. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  74. package/dist/irdevice/airpurifier.js +31 -59
  75. package/dist/irdevice/airpurifier.js.map +1 -1
  76. package/dist/irdevice/camera.d.ts +1 -5
  77. package/dist/irdevice/camera.d.ts.map +1 -1
  78. package/dist/irdevice/camera.js +30 -57
  79. package/dist/irdevice/camera.js.map +1 -1
  80. package/dist/irdevice/fan.d.ts +2 -6
  81. package/dist/irdevice/fan.d.ts.map +1 -1
  82. package/dist/irdevice/fan.js +39 -66
  83. package/dist/irdevice/fan.js.map +1 -1
  84. package/dist/irdevice/light.d.ts +1 -5
  85. package/dist/irdevice/light.d.ts.map +1 -1
  86. package/dist/irdevice/light.js +32 -59
  87. package/dist/irdevice/light.js.map +1 -1
  88. package/dist/irdevice/other.d.ts +1 -5
  89. package/dist/irdevice/other.d.ts.map +1 -1
  90. package/dist/irdevice/other.js +30 -57
  91. package/dist/irdevice/other.js.map +1 -1
  92. package/dist/irdevice/tv.d.ts +3 -7
  93. package/dist/irdevice/tv.d.ts.map +1 -1
  94. package/dist/irdevice/tv.js +46 -76
  95. package/dist/irdevice/tv.js.map +1 -1
  96. package/dist/irdevice/vacuumcleaner.d.ts +2 -6
  97. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  98. package/dist/irdevice/vacuumcleaner.js +30 -58
  99. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  100. package/dist/irdevice/waterheater.d.ts +7 -23
  101. package/dist/irdevice/waterheater.d.ts.map +1 -1
  102. package/dist/irdevice/waterheater.js +41 -74
  103. package/dist/irdevice/waterheater.js.map +1 -1
  104. package/dist/platform.d.ts +14 -5
  105. package/dist/platform.d.ts.map +1 -1
  106. package/dist/platform.js +156 -149
  107. package/dist/platform.js.map +1 -1
  108. package/dist/settings.d.ts +4 -0
  109. package/dist/settings.d.ts.map +1 -1
  110. package/dist/settings.js +5 -1
  111. package/dist/settings.js.map +1 -1
  112. package/nodemon.json +1 -1
  113. package/package.json +10 -10
  114. package/src/device/blindtilt.ts +122 -181
  115. package/src/device/bot.ts +96 -149
  116. package/src/device/ceilinglight.ts +172 -315
  117. package/src/device/colorbulb.ts +178 -324
  118. package/src/device/contact.ts +48 -78
  119. package/src/device/curtain.ts +93 -148
  120. package/src/device/hub.ts +34 -63
  121. package/src/device/humidifier.ts +135 -243
  122. package/src/device/iosensor.ts +49 -79
  123. package/src/device/{striplight.ts → lightstrip.ts} +148 -200
  124. package/src/device/lock.ts +78 -134
  125. package/src/device/meter.ts +48 -78
  126. package/src/device/meterplus.ts +50 -80
  127. package/src/device/motion.ts +46 -77
  128. package/src/device/plug.ts +76 -134
  129. package/src/device/robotvacuumcleaner.ts +91 -159
  130. package/src/irdevice/airconditioner.ts +56 -81
  131. package/src/irdevice/airpurifier.ts +41 -67
  132. package/src/irdevice/camera.ts +35 -60
  133. package/src/irdevice/fan.ts +46 -71
  134. package/src/irdevice/light.ts +38 -63
  135. package/src/irdevice/other.ts +35 -60
  136. package/src/irdevice/tv.ts +52 -80
  137. package/src/irdevice/vacuumcleaner.ts +36 -62
  138. package/src/irdevice/waterheater.ts +46 -76
  139. package/src/platform.ts +144 -158
  140. package/src/settings.ts +5 -0
  141. package/.github/npm-version-script.js +0 -81
  142. package/dist/device/striplight.d.ts.map +0 -1
  143. package/dist/device/striplight.js.map +0 -1
@@ -1,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
- import { connectAsync } from 'async-mqtt';
7
6
  import { interval, Subject } from 'rxjs';
7
+ import { connectAsync } from 'async-mqtt';
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
@@ -195,7 +192,7 @@ export class MeterPlus {
195
192
  } else {
196
193
  await this.offlineOff();
197
194
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
198
- + ` ${this.device.connectionType}, parseStatus will not happen.`);
195
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
199
196
  }
200
197
  }
201
198
 
@@ -254,7 +251,7 @@ export class MeterPlus {
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 MeterPlus {
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 MeterPlus {
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 MeterPlus {
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 MeterPlus {
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
- });
327
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
328
+ headers: this.platform.generateHeaders(),
369
329
  });
370
- req.on('error', (e: any) => {
371
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
372
- });
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 MeterPlus {
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 MeterPlus {
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;
@@ -459,7 +428,7 @@ export class MeterPlus {
459
428
  ?.join(':');
460
429
  const options = this.device.mqttPubOptions || {};
461
430
  this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
462
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${superStringify(options)}`);
431
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
463
432
  }
464
433
 
465
434
  /*
@@ -516,7 +485,7 @@ export class MeterPlus {
516
485
  });
517
486
  // Set an event handler
518
487
  switchbot.onadvertisement = (ad: any) => {
519
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
488
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
520
489
  };
521
490
  await sleep(10000);
522
491
  // Stop to monitor
@@ -557,40 +526,41 @@ export class MeterPlus {
557
526
  }
558
527
  }
559
528
 
560
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
561
- switch (res.statusCode) {
529
+ async statusCode(statusCode: number): Promise<void> {
530
+ switch (statusCode) {
562
531
  case 151:
563
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
532
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
564
533
  break;
565
534
  case 152:
566
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
535
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
567
536
  break;
568
537
  case 160:
569
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
538
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
570
539
  break;
571
540
  case 161:
572
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
573
- await this.offlineOff();
541
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
542
+ this.offlineOff();
574
543
  break;
575
544
  case 171:
576
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
577
- await this.offlineOff();
545
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
546
+ + `Hub: ${this.device.hubDeviceId}`);
547
+ this.offlineOff();
578
548
  break;
579
549
  case 190:
580
550
  this.errorLog(
581
551
  `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
582
- ` Or command: ${superStringify(res)} format is invalid`,
552
+ ` Or command format is invalid, statusCode: ${statusCode}`,
583
553
  );
584
554
  break;
585
555
  case 100:
586
- if (this.platform.debugMode) {
587
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
588
- }
556
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
557
+ break;
558
+ case 200:
559
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
589
560
  break;
590
561
  default:
591
- if (this.platform.debugMode) {
592
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
593
- }
562
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
563
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
594
564
  }
595
565
  }
596
566
 
@@ -617,7 +587,7 @@ export class MeterPlus {
617
587
  FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
618
588
  let FirmwareRevision: string;
619
589
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
620
- + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
590
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
621
591
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
622
592
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
623
593
  if (accessory.context.FirmwareRevision) {
@@ -690,7 +660,7 @@ export class MeterPlus {
690
660
  config['scanDuration'] = device.scanDuration;
691
661
  }
692
662
  if (Object.entries(config).length !== 0) {
693
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
663
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
694
664
  }
695
665
  }
696
666
 
@@ -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