@switchbot/homebridge-switchbot 1.15.1-beta.0 → 1.15.1-beta.10

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 (117) hide show
  1. package/.github/ISSUE_TEMPLATE/bug-report.yml +1 -0
  2. package/.github/ISSUE_TEMPLATE/feature-request.yml +1 -0
  3. package/.github/ISSUE_TEMPLATE/support-request.yml +1 -0
  4. package/.prettierrc +1 -1
  5. package/CHANGELOG.md +9 -0
  6. package/config.schema.json +11 -4
  7. package/dist/device/bot.d.ts +8 -7
  8. package/dist/device/bot.d.ts.map +1 -1
  9. package/dist/device/bot.js +104 -28
  10. package/dist/device/bot.js.map +1 -1
  11. package/dist/device/colorbulb.d.ts +8 -7
  12. package/dist/device/colorbulb.d.ts.map +1 -1
  13. package/dist/device/colorbulb.js +223 -58
  14. package/dist/device/colorbulb.js.map +1 -1
  15. package/dist/device/contact.d.ts +3 -3
  16. package/dist/device/contact.d.ts.map +1 -1
  17. package/dist/device/contact.js +54 -11
  18. package/dist/device/contact.js.map +1 -1
  19. package/dist/device/curtain.d.ts +9 -8
  20. package/dist/device/curtain.d.ts.map +1 -1
  21. package/dist/device/curtain.js +102 -28
  22. package/dist/device/curtain.js.map +1 -1
  23. package/dist/device/humidifier.d.ts +8 -7
  24. package/dist/device/humidifier.d.ts.map +1 -1
  25. package/dist/device/humidifier.js +187 -66
  26. package/dist/device/humidifier.js.map +1 -1
  27. package/dist/device/lock.d.ts +8 -7
  28. package/dist/device/lock.d.ts.map +1 -1
  29. package/dist/device/lock.js +98 -22
  30. package/dist/device/lock.js.map +1 -1
  31. package/dist/device/meter.d.ts +4 -4
  32. package/dist/device/meter.d.ts.map +1 -1
  33. package/dist/device/meter.js +55 -12
  34. package/dist/device/meter.js.map +1 -1
  35. package/dist/device/meterplus.d.ts +3 -3
  36. package/dist/device/meterplus.d.ts.map +1 -1
  37. package/dist/device/meterplus.js +53 -10
  38. package/dist/device/meterplus.js.map +1 -1
  39. package/dist/device/motion.d.ts +3 -3
  40. package/dist/device/motion.d.ts.map +1 -1
  41. package/dist/device/motion.js +53 -13
  42. package/dist/device/motion.js.map +1 -1
  43. package/dist/device/plug.d.ts +8 -7
  44. package/dist/device/plug.d.ts.map +1 -1
  45. package/dist/device/plug.js +100 -24
  46. package/dist/device/plug.js.map +1 -1
  47. package/dist/device/striplight.d.ts +8 -7
  48. package/dist/device/striplight.d.ts.map +1 -1
  49. package/dist/device/striplight.js +186 -47
  50. package/dist/device/striplight.js.map +1 -1
  51. package/dist/irdevice/airconditioner.d.ts +7 -6
  52. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  53. package/dist/irdevice/airconditioner.js +40 -6
  54. package/dist/irdevice/airconditioner.js.map +1 -1
  55. package/dist/irdevice/airpurifier.d.ts +7 -6
  56. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  57. package/dist/irdevice/airpurifier.js +46 -11
  58. package/dist/irdevice/airpurifier.js.map +1 -1
  59. package/dist/irdevice/camera.d.ts +7 -6
  60. package/dist/irdevice/camera.d.ts.map +1 -1
  61. package/dist/irdevice/camera.js +40 -6
  62. package/dist/irdevice/camera.js.map +1 -1
  63. package/dist/irdevice/fan.d.ts +8 -7
  64. package/dist/irdevice/fan.d.ts.map +1 -1
  65. package/dist/irdevice/fan.js +40 -6
  66. package/dist/irdevice/fan.js.map +1 -1
  67. package/dist/irdevice/light.d.ts +7 -6
  68. package/dist/irdevice/light.d.ts.map +1 -1
  69. package/dist/irdevice/light.js +40 -6
  70. package/dist/irdevice/light.js.map +1 -1
  71. package/dist/irdevice/other.d.ts +7 -6
  72. package/dist/irdevice/other.d.ts.map +1 -1
  73. package/dist/irdevice/other.js +40 -6
  74. package/dist/irdevice/other.js.map +1 -1
  75. package/dist/irdevice/tv.d.ts +8 -7
  76. package/dist/irdevice/tv.d.ts.map +1 -1
  77. package/dist/irdevice/tv.js +40 -6
  78. package/dist/irdevice/tv.js.map +1 -1
  79. package/dist/irdevice/vacuumcleaner.d.ts +7 -6
  80. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  81. package/dist/irdevice/vacuumcleaner.js +40 -6
  82. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  83. package/dist/irdevice/waterheater.d.ts +7 -6
  84. package/dist/irdevice/waterheater.d.ts.map +1 -1
  85. package/dist/irdevice/waterheater.js +40 -6
  86. package/dist/irdevice/waterheater.js.map +1 -1
  87. package/dist/platform.d.ts +10 -6
  88. package/dist/platform.d.ts.map +1 -1
  89. package/dist/platform.js +211 -93
  90. package/dist/platform.js.map +1 -1
  91. package/dist/settings.d.ts +4 -21
  92. package/dist/settings.d.ts.map +1 -1
  93. package/dist/settings.js +3 -3
  94. package/dist/settings.js.map +1 -1
  95. package/package.json +12 -12
  96. package/src/device/bot.ts +104 -37
  97. package/src/device/colorbulb.ts +227 -95
  98. package/src/device/contact.ts +53 -14
  99. package/src/device/curtain.ts +105 -38
  100. package/src/device/humidifier.ts +189 -84
  101. package/src/device/lock.ts +97 -30
  102. package/src/device/meter.ts +55 -16
  103. package/src/device/meterplus.ts +52 -13
  104. package/src/device/motion.ts +52 -16
  105. package/src/device/plug.ts +101 -33
  106. package/src/device/striplight.ts +189 -68
  107. package/src/irdevice/airconditioner.ts +44 -9
  108. package/src/irdevice/airpurifier.ts +52 -17
  109. package/src/irdevice/camera.ts +46 -11
  110. package/src/irdevice/fan.ts +50 -15
  111. package/src/irdevice/light.ts +48 -13
  112. package/src/irdevice/other.ts +46 -11
  113. package/src/irdevice/tv.ts +56 -21
  114. package/src/irdevice/vacuumcleaner.ts +46 -11
  115. package/src/irdevice/waterheater.ts +46 -11
  116. package/src/platform.ts +232 -107
  117. package/src/settings.ts +4 -25
@@ -1,9 +1,11 @@
1
+ import https from 'https';
2
+ import crypto from 'crypto';
3
+ import { Context } from 'vm';
1
4
  import { interval, Subject } from 'rxjs';
2
5
  import { skipWhile } from 'rxjs/operators';
3
6
  import { SwitchBotPlatform } from '../platform';
4
7
  import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
5
- import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature, deviceStatus } from '../settings';
6
- import { Context } from 'vm';
8
+ import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, HostDomain, DevicePath } from '../settings';
7
9
 
8
10
  /**
9
11
  * Platform Accessory
@@ -30,7 +32,7 @@ export class MeterPlus {
30
32
  // OpenAPI Others
31
33
  Temperature: deviceStatus['temperature'];
32
34
  Humidity: deviceStatus['humidity'];
33
- deviceStatus!: deviceStatusResponse;
35
+ deviceStatus!: any; //deviceStatusResponse;
34
36
 
35
37
  // BLE Others
36
38
  connected?: boolean;
@@ -208,7 +210,7 @@ export class MeterPlus {
208
210
  if (this.device.ble) {
209
211
  this.SwitchToOpenAPI = false;
210
212
  }
211
- if (this.platform.config.credentials?.openToken) {
213
+ if (this.platform.config.credentials?.token) {
212
214
  this.debugLog(`Meter Plus: ${this.accessory.displayName} OpenAPI parseStatus`);
213
215
  // Current Relative Humidity
214
216
  if (!this.device.meter?.hide_humidity) {
@@ -301,7 +303,7 @@ export class MeterPlus {
301
303
  `Meter Plus: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
302
304
  );
303
305
  }
304
- if (this.platform.config.credentials?.openToken) {
306
+ if (this.platform.config.credentials?.token) {
305
307
  this.warnLog(`Meter Plus: ${this.accessory.displayName} Using OpenAPI Connection`);
306
308
  this.SwitchToOpenAPI = true;
307
309
  this.openAPIRefreshStatus();
@@ -333,7 +335,7 @@ export class MeterPlus {
333
335
 
334
336
  async BLEconnection(switchbot: any): Promise<void> {
335
337
  this.errorLog(`Meter Plus: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
336
- if (this.platform.config.credentials?.openToken) {
338
+ if (this.platform.config.credentials?.token) {
337
339
  this.warnLog(`Meter Plus: ${this.accessory.displayName} Using OpenAPI Connection`);
338
340
  this.SwitchToOpenAPI = true;
339
341
  await this.openAPIRefreshStatus();
@@ -341,15 +343,52 @@ export class MeterPlus {
341
343
  }
342
344
 
343
345
  async openAPIRefreshStatus(): Promise<void> {
344
- if (this.platform.config.credentials?.openToken) {
346
+ if (this.platform.config.credentials?.token) {
345
347
  this.debugLog(`Meter Plus: ${this.accessory.displayName} OpenAPI RefreshStatus`);
346
348
  try {
347
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
348
- this.debugLog(`Meter Plus: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
349
- this.Humidity = this.deviceStatus.body.humidity!;
350
- this.Temperature = this.deviceStatus.body.temperature!;
351
- this.parseStatus();
352
- this.updateHomeKitCharacteristics();
349
+ const t = Date.now();
350
+ const nonce = 'requestID';
351
+ const data = this.platform.config.credentials?.token + t + nonce;
352
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
353
+ const sign = signTerm.toString('base64');
354
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} sign: ${sign}`);
355
+ const options = {
356
+ hostname: HostDomain,
357
+ port: 443,
358
+ path: `${DevicePath}/${this.device.deviceId}/status`,
359
+ method: 'GET',
360
+ headers: {
361
+ Authorization: this.platform.config.credentials?.token,
362
+ sign: sign,
363
+ nonce: nonce,
364
+ t: t,
365
+ 'Content-Type': 'application/json',
366
+ },
367
+ };
368
+ const req = https.request(options, (res) => {
369
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
370
+ let rawData = '';
371
+ res.on('data', (d) => {
372
+ rawData += d;
373
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} d: ${d}`);
374
+ });
375
+ res.on('end', () => {
376
+ try {
377
+ this.deviceStatus = JSON.parse(rawData);
378
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
379
+ this.Humidity = this.deviceStatus.body.humidity!;
380
+ this.Temperature = this.deviceStatus.body.temperature!;
381
+ this.parseStatus();
382
+ this.updateHomeKitCharacteristics();
383
+ } catch (e: any) {
384
+ this.errorLog(`Meter Plus: ${this.accessory.displayName} error message: ${e.message}`);
385
+ }
386
+ });
387
+ });
388
+ req.on('error', (e: any) => {
389
+ this.errorLog(`Meter Plus: ${this.accessory.displayName} error message: ${e.message}`);
390
+ });
391
+ req.end();
353
392
  } catch (e: any) {
354
393
  this.errorLog(`Meter Plus: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
355
394
  if (this.deviceLogging.includes('debug')) {
@@ -1,9 +1,11 @@
1
+ import https from 'https';
2
+ import crypto from 'crypto';
3
+ import { Context } from 'vm';
1
4
  import { interval, Subject } from 'rxjs';
2
5
  import { skipWhile } from 'rxjs/operators';
3
6
  import { SwitchBotPlatform } from '../platform';
4
7
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
5
- import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, deviceStatus, ad } from '../settings';
6
- import { Context } from 'vm';
8
+ import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
7
9
 
8
10
  /**
9
11
  * Platform Accessory
@@ -23,7 +25,7 @@ export class Motion {
23
25
  StatusLowBattery?: CharacteristicValue;
24
26
 
25
27
  // OpenAPI Others
26
- deviceStatus!: deviceStatusResponse;
28
+ deviceStatus!: any; //deviceStatusResponse;
27
29
  moveDetected: deviceStatus['moveDetected'];
28
30
  brightness: deviceStatus['brightness'];
29
31
 
@@ -181,7 +183,7 @@ export class Motion {
181
183
  if (this.device.ble) {
182
184
  this.SwitchToOpenAPI = false;
183
185
  }
184
- if (this.platform.config.credentials?.openToken) {
186
+ if (this.platform.config.credentials?.token) {
185
187
  this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
186
188
  // Motion State
187
189
  this.MotionDetected = this.moveDetected!;
@@ -283,7 +285,7 @@ export class Motion {
283
285
  ` Error Message: ${JSON.stringify(e.message)}`,
284
286
  );
285
287
  }
286
- if (this.platform.config.credentials?.openToken) {
288
+ if (this.platform.config.credentials?.token) {
287
289
  this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
288
290
  this.SwitchToOpenAPI = true;
289
291
  await this.openAPIRefreshStatus();
@@ -315,7 +317,7 @@ export class Motion {
315
317
 
316
318
  async BLEconnection(switchbot: any): Promise<void> {
317
319
  this.errorLog(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
318
- if (this.platform.config.credentials?.openToken) {
320
+ if (this.platform.config.credentials?.token) {
319
321
  this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
320
322
  this.SwitchToOpenAPI = true;
321
323
  await this.openAPIRefreshStatus();
@@ -323,18 +325,52 @@ export class Motion {
323
325
  }
324
326
 
325
327
  async openAPIRefreshStatus(): Promise<void> {
326
- if (this.platform.config.credentials?.openToken) {
328
+ if (this.platform.config.credentials?.token) {
327
329
  this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI RefreshStatus`);
328
330
  try {
329
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
330
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
331
- if (this.deviceStatus.body.moveDetected === undefined) {
332
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
333
- }
334
- this.moveDetected = this.deviceStatus.body.moveDetected;
335
- this.brightness = this.deviceStatus.body.brightness;
336
- this.parseStatus();
337
- this.updateHomeKitCharacteristics();
331
+ const t = Date.now();
332
+ const nonce = 'requestID';
333
+ const data = this.platform.config.credentials?.token + t + nonce;
334
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
335
+ const sign = signTerm.toString('base64');
336
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} sign: ${sign}`);
337
+ const options = {
338
+ hostname: HostDomain,
339
+ port: 443,
340
+ path: `${DevicePath}/${this.device.deviceId}/status`,
341
+ method: 'GET',
342
+ headers: {
343
+ Authorization: this.platform.config.credentials?.token,
344
+ sign: sign,
345
+ nonce: nonce,
346
+ t: t,
347
+ 'Content-Type': 'application/json',
348
+ },
349
+ };
350
+ const req = https.request(options, (res) => {
351
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
352
+ let rawData = '';
353
+ res.on('data', (d) => {
354
+ rawData += d;
355
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} d: ${d}`);
356
+ });
357
+ res.on('end', () => {
358
+ try {
359
+ this.deviceStatus = JSON.parse(rawData);
360
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
361
+ this.moveDetected = this.deviceStatus.body.moveDetected;
362
+ this.brightness = this.deviceStatus.body.brightness;
363
+ this.parseStatus();
364
+ this.updateHomeKitCharacteristics();
365
+ } catch (e: any) {
366
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
367
+ }
368
+ });
369
+ });
370
+ req.on('error', (e: any) => {
371
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
372
+ });
373
+ req.end();
338
374
  } catch (e: any) {
339
375
  this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
340
376
  if (this.deviceLogging.includes('debug')) {
@@ -1,10 +1,12 @@
1
- import { AxiosResponse } from 'axios';
1
+ import https from 'https';
2
+ import crypto from 'crypto';
3
+ import { Context } from 'vm';
4
+ import { IncomingMessage } from 'http';
2
5
  import { interval, Subject } from 'rxjs';
3
6
  import { SwitchBotPlatform } from '../platform';
4
7
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
5
8
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
6
- import { DeviceURL, device, devicesConfig, deviceStatusResponse, payload, deviceStatus, ad, serviceData, switchbot } from '../settings';
7
- import { Context } from 'vm';
9
+ import { device, devicesConfig, deviceStatus, ad, serviceData, switchbot, HostDomain, DevicePath } from '../settings';
8
10
 
9
11
  export class Plug {
10
12
  // Services
@@ -16,7 +18,7 @@ export class Plug {
16
18
 
17
19
  // OpenAPI Others
18
20
  power: deviceStatus['power'];
19
- deviceStatus!: deviceStatusResponse;
21
+ deviceStatus!: any; //deviceStatusResponse;
20
22
 
21
23
  // BLE Others
22
24
  connected?: boolean;
@@ -232,7 +234,7 @@ export class Plug {
232
234
  `Plug: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
233
235
  );
234
236
  }
235
- if (this.platform.config.credentials?.openToken) {
237
+ if (this.platform.config.credentials?.token) {
236
238
  this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
237
239
  this.SwitchToOpenAPI = true;
238
240
  await this.openAPIRefreshStatus();
@@ -272,7 +274,7 @@ export class Plug {
272
274
 
273
275
  async BLEconnection(switchbot: any): Promise<void> {
274
276
  this.errorLog(`Plug: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
275
- if (this.platform.config.credentials?.openToken) {
277
+ if (this.platform.config.credentials?.token) {
276
278
  this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
277
279
  this.SwitchToOpenAPI = true;
278
280
  await this.openAPIRefreshStatus();
@@ -281,11 +283,48 @@ export class Plug {
281
283
 
282
284
  async openAPIRefreshStatus() {
283
285
  try {
284
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
285
- this.debugLog(`Plug: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
286
- this.power = this.deviceStatus.body.power;
287
- this.parseStatus();
288
- this.updateHomeKitCharacteristics();
286
+ const t = Date.now();
287
+ const nonce = 'requestID';
288
+ const data = this.platform.config.credentials?.token + t + nonce;
289
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
290
+ const sign = signTerm.toString('base64');
291
+ this.debugLog(`Plug: ${this.accessory.displayName} sign: ${sign}`);
292
+ const options = {
293
+ hostname: HostDomain,
294
+ port: 443,
295
+ path: `${DevicePath}/${this.device.deviceId}/status`,
296
+ method: 'GET',
297
+ headers: {
298
+ Authorization: this.platform.config.credentials?.token,
299
+ sign: sign,
300
+ nonce: nonce,
301
+ t: t,
302
+ 'Content-Type': 'application/json',
303
+ },
304
+ };
305
+ const req = https.request(options, (res) => {
306
+ this.debugLog(`Plug: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
307
+ let rawData = '';
308
+ res.on('data', (d) => {
309
+ rawData += d;
310
+ this.debugLog(`Plug: ${this.accessory.displayName} d: ${d}`);
311
+ });
312
+ res.on('end', () => {
313
+ try {
314
+ this.deviceStatus = JSON.parse(rawData);
315
+ this.debugLog(`Plug: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
316
+ this.power = this.deviceStatus.body.power;
317
+ this.parseStatus();
318
+ this.updateHomeKitCharacteristics();
319
+ } catch (e: any) {
320
+ this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
321
+ }
322
+ });
323
+ });
324
+ req.on('error', (e: any) => {
325
+ this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
326
+ });
327
+ req.end();
289
328
  } catch (e: any) {
290
329
  this.errorLog(`Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
291
330
  if (this.deviceLogging.includes('debug')) {
@@ -350,7 +389,7 @@ export class Plug {
350
389
  if (this.platform.debugMode) {
351
390
  this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error: ${JSON.stringify(e)}`);
352
391
  }
353
- if (this.platform.config.credentials?.openToken) {
392
+ if (this.platform.config.credentials?.token) {
354
393
  this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
355
394
  await this.openAPIpushChanges();
356
395
  }
@@ -374,29 +413,58 @@ export class Plug {
374
413
  }
375
414
 
376
415
  async openAPIpushChanges() {
377
- if (this.platform.config.credentials?.openToken) {
416
+ if (this.platform.config.credentials?.token) {
378
417
  if (this.On !== this.OnCached) {
418
+ // Make Push On request to the API
379
419
  this.debugLog(`Plug: ${this.accessory.displayName} OpenAPI pushChanges`);
380
- const payload = {
381
- commandType: 'command',
382
- parameter: 'default',
383
- } as payload;
384
-
420
+ const t = Date.now();
421
+ const nonce = 'requestID';
422
+ const data = this.platform.config.credentials?.token + t + nonce;
423
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
424
+ .update(Buffer.from(data, 'utf-8'))
425
+ .digest();
426
+ const sign = signTerm.toString('base64');
427
+ this.debugLog(`Plug: ${this.accessory.displayName} sign: ${sign}`);
428
+
429
+ let command = '';
385
430
  if (this.On) {
386
- payload.command = 'turnOn';
431
+ command = 'turnOn';
387
432
  } else {
388
- payload.command = 'turnOff';
433
+ command = 'turnOff';
389
434
  }
390
-
391
- this.infoLog(
392
- `Plug: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
393
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
394
- );
395
-
396
- // Make the API request
397
- const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
398
- this.debugLog(`Plug: ${this.accessory.displayName} pushchanges: ${JSON.stringify(push.data)}`);
399
- this.statusCode(push);
435
+ const body = JSON.stringify({
436
+ 'command': `${command}`,
437
+ 'parameter': 'default',
438
+ 'commandType': 'command',
439
+ });
440
+ this.infoLog(`Plug: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
441
+ const options = {
442
+ hostname: HostDomain,
443
+ port: 443,
444
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
445
+ method: 'POST',
446
+ headers: {
447
+ 'Authorization': this.platform.config.credentials?.token,
448
+ 'sign': sign,
449
+ 'nonce': nonce,
450
+ 't': t,
451
+ 'Content-Type': 'application/json',
452
+ 'Content-Length': body.length,
453
+ },
454
+ };
455
+ const req = https.request(options, res => {
456
+ this.debugLog(`Plug: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
457
+ this.statusCode({ res });
458
+ res.on('data', d => {
459
+ this.debugLog(`Plug: ${this.accessory.displayName} d: ${d}`);
460
+ });
461
+ });
462
+ req.on('error', (e: any) => {
463
+ this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
464
+ });
465
+ req.write(body);
466
+ req.end();
467
+ this.debugLog(`Plug: ${this.accessory.displayName} openAPIpushChanges: ${JSON.stringify(req)}`);
400
468
  this.OnCached = this.On;
401
469
  this.accessory.context.On = this.OnCached;
402
470
  }
@@ -422,8 +490,8 @@ export class Plug {
422
490
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
423
491
  }
424
492
 
425
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
426
- switch (push.data.statusCode) {
493
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
494
+ switch (res.statusCode) {
427
495
  case 151:
428
496
  this.errorLog(`Plug: ${this.accessory.displayName} Command not supported by this device type.`);
429
497
  break;
@@ -444,7 +512,7 @@ export class Plug {
444
512
  case 190:
445
513
  this.errorLog(
446
514
  `Plug: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
447
- ` Or command: ${JSON.stringify(push.data)} format is invalid`,
515
+ ` Or command: ${JSON.stringify(res)} format is invalid`,
448
516
  );
449
517
  break;
450
518
  case 100: