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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/.vscode/tasks.json +13 -0
  2. package/CHANGELOG.md +4 -2
  3. package/README.md +18 -9
  4. package/dist/device/blindtilt.d.ts +1 -5
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +80 -140
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +1 -5
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +79 -138
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +2 -6
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +157 -304
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +2 -6
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +164 -311
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +1 -5
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +36 -72
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +1 -5
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +78 -138
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/hub.d.ts +2 -6
  29. package/dist/device/hub.d.ts.map +1 -1
  30. package/dist/device/hub.js +30 -63
  31. package/dist/device/hub.js.map +1 -1
  32. package/dist/device/humidifier.d.ts +1 -5
  33. package/dist/device/humidifier.d.ts.map +1 -1
  34. package/dist/device/humidifier.js +115 -228
  35. package/dist/device/humidifier.js.map +1 -1
  36. package/dist/device/iosensor.d.ts +1 -5
  37. package/dist/device/iosensor.d.ts.map +1 -1
  38. package/dist/device/iosensor.js +38 -74
  39. package/dist/device/iosensor.js.map +1 -1
  40. package/dist/device/{striplight.d.ts → lightstrip.d.ts} +2 -10
  41. package/dist/device/lightstrip.d.ts.map +1 -0
  42. package/dist/device/{striplight.js → lightstrip.js} +138 -194
  43. package/dist/device/lightstrip.js.map +1 -0
  44. package/dist/device/lock.d.ts +1 -5
  45. package/dist/device/lock.d.ts.map +1 -1
  46. package/dist/device/lock.js +66 -126
  47. package/dist/device/lock.js.map +1 -1
  48. package/dist/device/meter.d.ts +1 -5
  49. package/dist/device/meter.d.ts.map +1 -1
  50. package/dist/device/meter.js +38 -74
  51. package/dist/device/meter.js.map +1 -1
  52. package/dist/device/meterplus.d.ts +1 -5
  53. package/dist/device/meterplus.d.ts.map +1 -1
  54. package/dist/device/meterplus.js +39 -75
  55. package/dist/device/meterplus.js.map +1 -1
  56. package/dist/device/motion.d.ts +1 -5
  57. package/dist/device/motion.d.ts.map +1 -1
  58. package/dist/device/motion.js +35 -72
  59. package/dist/device/motion.js.map +1 -1
  60. package/dist/device/plug.d.ts +1 -5
  61. package/dist/device/plug.d.ts.map +1 -1
  62. package/dist/device/plug.js +65 -126
  63. package/dist/device/plug.js.map +1 -1
  64. package/dist/device/robotvacuumcleaner.d.ts +1 -5
  65. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  66. package/dist/device/robotvacuumcleaner.js +79 -151
  67. package/dist/device/robotvacuumcleaner.js.map +1 -1
  68. package/dist/irdevice/airconditioner.d.ts +3 -7
  69. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  70. package/dist/irdevice/airconditioner.js +34 -62
  71. package/dist/irdevice/airconditioner.js.map +1 -1
  72. package/dist/irdevice/airpurifier.d.ts +3 -7
  73. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  74. package/dist/irdevice/airpurifier.js +31 -59
  75. package/dist/irdevice/airpurifier.js.map +1 -1
  76. package/dist/irdevice/camera.d.ts +1 -5
  77. package/dist/irdevice/camera.d.ts.map +1 -1
  78. package/dist/irdevice/camera.js +30 -57
  79. package/dist/irdevice/camera.js.map +1 -1
  80. package/dist/irdevice/fan.d.ts +2 -6
  81. package/dist/irdevice/fan.d.ts.map +1 -1
  82. package/dist/irdevice/fan.js +39 -66
  83. package/dist/irdevice/fan.js.map +1 -1
  84. package/dist/irdevice/light.d.ts +1 -5
  85. package/dist/irdevice/light.d.ts.map +1 -1
  86. package/dist/irdevice/light.js +32 -59
  87. package/dist/irdevice/light.js.map +1 -1
  88. package/dist/irdevice/other.d.ts +1 -5
  89. package/dist/irdevice/other.d.ts.map +1 -1
  90. package/dist/irdevice/other.js +30 -57
  91. package/dist/irdevice/other.js.map +1 -1
  92. package/dist/irdevice/tv.d.ts +3 -7
  93. package/dist/irdevice/tv.d.ts.map +1 -1
  94. package/dist/irdevice/tv.js +46 -76
  95. package/dist/irdevice/tv.js.map +1 -1
  96. package/dist/irdevice/vacuumcleaner.d.ts +2 -6
  97. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  98. package/dist/irdevice/vacuumcleaner.js +30 -58
  99. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  100. package/dist/irdevice/waterheater.d.ts +7 -23
  101. package/dist/irdevice/waterheater.d.ts.map +1 -1
  102. package/dist/irdevice/waterheater.js +41 -74
  103. package/dist/irdevice/waterheater.js.map +1 -1
  104. package/dist/platform.d.ts +14 -5
  105. package/dist/platform.d.ts.map +1 -1
  106. package/dist/platform.js +156 -149
  107. package/dist/platform.js.map +1 -1
  108. package/dist/settings.d.ts +4 -0
  109. package/dist/settings.d.ts.map +1 -1
  110. package/dist/settings.js +5 -1
  111. package/dist/settings.js.map +1 -1
  112. package/nodemon.json +1 -1
  113. package/package.json +10 -10
  114. package/src/device/blindtilt.ts +122 -181
  115. package/src/device/bot.ts +96 -149
  116. package/src/device/ceilinglight.ts +172 -315
  117. package/src/device/colorbulb.ts +178 -324
  118. package/src/device/contact.ts +48 -78
  119. package/src/device/curtain.ts +93 -148
  120. package/src/device/hub.ts +34 -63
  121. package/src/device/humidifier.ts +135 -243
  122. package/src/device/iosensor.ts +49 -79
  123. package/src/device/{striplight.ts → lightstrip.ts} +148 -200
  124. package/src/device/lock.ts +78 -134
  125. package/src/device/meter.ts +48 -78
  126. package/src/device/meterplus.ts +50 -80
  127. package/src/device/motion.ts +46 -77
  128. package/src/device/plug.ts +76 -134
  129. package/src/device/robotvacuumcleaner.ts +91 -159
  130. package/src/irdevice/airconditioner.ts +56 -81
  131. package/src/irdevice/airpurifier.ts +41 -67
  132. package/src/irdevice/camera.ts +35 -60
  133. package/src/irdevice/fan.ts +46 -71
  134. package/src/irdevice/light.ts +38 -63
  135. package/src/irdevice/other.ts +35 -60
  136. package/src/irdevice/tv.ts +52 -80
  137. package/src/irdevice/vacuumcleaner.ts +36 -62
  138. package/src/irdevice/waterheater.ts +46 -76
  139. package/src/platform.ts +144 -158
  140. package/src/settings.ts +5 -0
  141. package/.github/npm-version-script.js +0 -81
  142. package/dist/device/striplight.d.ts.map +0 -1
  143. package/dist/device/striplight.js.map +0 -1
@@ -1,14 +1,11 @@
1
- import https from 'https';
2
- import crypto from 'crypto';
3
1
  import { Context } from 'vm';
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
@@ -183,7 +180,7 @@ export class Contact {
183
180
  } else {
184
181
  await this.offlineOff();
185
182
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
186
- + ` ${this.device.connectionType}, parseStatus will not happen.`);
183
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
187
184
  }
188
185
  }
189
186
 
@@ -204,7 +201,7 @@ export class Contact {
204
201
  }
205
202
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
206
203
  if ((this.ContactSensorState !== this.accessory.context.ContactSensorState)
207
- && this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED) {
204
+ && this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED) {
208
205
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Opened`);
209
206
  }
210
207
  // Movement
@@ -227,7 +224,7 @@ export class Contact {
227
224
  this.CurrentAmbientLightLevel = this.set_maxLux;
228
225
  }
229
226
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.is_light},` +
230
- ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
227
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
231
228
  if (this.CurrentAmbientLightLevel !== this.accessory.context.CurrentAmbientLightLevel) {
232
229
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
233
230
  }
@@ -243,7 +240,7 @@ export class Contact {
243
240
  this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
244
241
  }
245
242
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, `
246
- + `StatusLowBattery: ${this.StatusLowBattery}`);
243
+ + `StatusLowBattery: ${this.StatusLowBattery}`);
247
244
  }
248
245
 
249
246
  async openAPIparseStatus(): Promise<void> {
@@ -292,7 +289,7 @@ export class Contact {
292
289
  } else {
293
290
  await this.offlineOff();
294
291
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
295
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
292
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
296
293
  }
297
294
  }
298
295
 
@@ -321,7 +318,7 @@ export class Contact {
321
318
  switchbot.onadvertisement = async (ad: any) => {
322
319
  this.address = ad.address;
323
320
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
324
- + ` BLE Address Found: ${this.address}`);
321
+ + ` BLE Address Found: ${this.address}`);
325
322
  this.serviceData = ad.serviceData;
326
323
  this.movement = ad.serviceData.movement;
327
324
  this.tested = ad.serviceData.tested;
@@ -331,10 +328,10 @@ export class Contact {
331
328
  this.is_light = ad.serviceData.is_light;
332
329
  this.button_count = ad.serviceData.button_count;
333
330
  this.doorState = ad.serviceData.doorState;
334
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
331
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
335
332
  this.debugLog(
336
333
  `${this.device.deviceType}: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, doorState: ` +
337
- `${ad.serviceData.doorState}, is_light: ${ad.serviceData.is_light}, battery: ${ad.serviceData.battery}`,
334
+ `${ad.serviceData.doorState}, is_light: ${ad.serviceData.is_light}, battery: ${ad.serviceData.battery}`,
338
335
  );
339
336
 
340
337
  if (this.serviceData) {
@@ -359,7 +356,7 @@ export class Contact {
359
356
  .catch(async (e: any) => {
360
357
  this.apiError(e);
361
358
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
362
- + ` Connection, Error Message: ${superStringify(e.message)}`);
359
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
363
360
  await this.BLERefreshConnection(switchbot);
364
361
  });
365
362
  } else {
@@ -370,54 +367,26 @@ export class Contact {
370
367
  async openAPIRefreshStatus(): Promise<void> {
371
368
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
372
369
  try {
373
- const t = Date.now();
374
- const nonce = 'requestID';
375
- const data = this.platform.config.credentials?.token + t + nonce;
376
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
377
- const sign = signTerm.toString('base64');
378
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
379
- const options = {
380
- hostname: HostDomain,
381
- port: 443,
382
- path: `${DevicePath}/${this.device.deviceId}/status`,
383
- method: 'GET',
384
- headers: {
385
- Authorization: this.platform.config.credentials?.token,
386
- sign: sign,
387
- nonce: nonce,
388
- t: t,
389
- 'Content-Type': 'application/json',
390
- },
391
- };
392
- const req = https.request(options, (res) => {
393
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
394
- let rawData = '';
395
- res.on('data', (d) => {
396
- rawData += d;
397
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
398
- });
399
- res.on('end', () => {
400
- try {
401
- this.deviceStatus = JSON.parse(rawData);
402
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${superStringify(this.deviceStatus)}`);
403
- this.openState = this.deviceStatus.body.openState;
404
- this.moveDetected = this.deviceStatus.body.moveDetected;
405
- this.brightness = this.deviceStatus.body.brightness;
406
- this.openAPIparseStatus();
407
- this.updateHomeKitCharacteristics();
408
- } catch (e: any) {
409
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
410
- }
411
- });
412
- });
413
- req.on('error', (e: any) => {
414
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
370
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
371
+ headers: this.platform.generateHeaders(),
415
372
  });
416
- req.end();
373
+ const deviceStatus = await body.json();
374
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
375
+ this.statusCode(statusCode);
376
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
377
+ this.debugLog(
378
+ `${this.device.deviceType}: ${this.accessory.displayName
379
+ } refreshStatus: ${JSON.stringify(deviceStatus)}`,
380
+ );
381
+ this.openState = deviceStatus.body.openState;
382
+ this.moveDetected = deviceStatus.body.moveDetected;
383
+ this.brightness = deviceStatus.body.brightness;
384
+ this.openAPIparseStatus();
385
+ this.updateHomeKitCharacteristics();
417
386
  } catch (e: any) {
418
387
  this.apiError(e);
419
388
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
420
- + ` Connection, Error Message: ${superStringify(e.message)}`);
389
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
421
390
  }
422
391
  }
423
392
 
@@ -489,7 +458,7 @@ export class Contact {
489
458
  });
490
459
  // Set an event handler
491
460
  switchbot.onadvertisement = (ad: any) => {
492
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
461
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
493
462
  };
494
463
  await sleep(10000);
495
464
  // Stop to monitor
@@ -538,40 +507,41 @@ export class Contact {
538
507
  }
539
508
  }
540
509
 
541
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
542
- switch (res.statusCode) {
510
+ async statusCode(statusCode: number): Promise<void> {
511
+ switch (statusCode) {
543
512
  case 151:
544
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
513
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
545
514
  break;
546
515
  case 152:
547
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
516
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
548
517
  break;
549
518
  case 160:
550
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
519
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
551
520
  break;
552
521
  case 161:
553
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
554
- await this.offlineOff();
522
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
523
+ this.offlineOff();
555
524
  break;
556
525
  case 171:
557
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
558
- await this.offlineOff();
526
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
527
+ + `Hub: ${this.device.hubDeviceId}`);
528
+ this.offlineOff();
559
529
  break;
560
530
  case 190:
561
531
  this.errorLog(
562
532
  `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
563
- ` Or command: ${superStringify(res)} format is invalid`,
533
+ ` Or command format is invalid, statusCode: ${statusCode}`,
564
534
  );
565
535
  break;
566
536
  case 100:
567
- if (this.platform.debugMode) {
568
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
569
- }
537
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
538
+ break;
539
+ case 200:
540
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
570
541
  break;
571
542
  default:
572
- if (this.platform.debugMode) {
573
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
574
- }
543
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
544
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
575
545
  }
576
546
  }
577
547
 
@@ -599,7 +569,7 @@ export class Contact {
599
569
  FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
600
570
  let FirmwareRevision: string;
601
571
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
602
- + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
572
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
603
573
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
604
574
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
605
575
  if (accessory.context.FirmwareRevision) {
@@ -656,7 +626,7 @@ export class Contact {
656
626
  config['scanDuration'] = device.scanDuration;
657
627
  }
658
628
  if (Object.entries(config).length !== 0) {
659
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
629
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
660
630
  }
661
631
  }
662
632