@switchbot/homebridge-switchbot 1.15.1-beta.7 → 1.15.1-beta.8

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 (112) hide show
  1. package/.prettierrc +1 -1
  2. package/dist/device/bot.d.ts +8 -7
  3. package/dist/device/bot.d.ts.map +1 -1
  4. package/dist/device/bot.js +83 -11
  5. package/dist/device/bot.js.map +1 -1
  6. package/dist/device/colorbulb.d.ts +8 -7
  7. package/dist/device/colorbulb.d.ts.map +1 -1
  8. package/dist/device/colorbulb.js +182 -23
  9. package/dist/device/colorbulb.js.map +1 -1
  10. package/dist/device/contact.d.ts +3 -3
  11. package/dist/device/contact.d.ts.map +1 -1
  12. package/dist/device/contact.js +50 -7
  13. package/dist/device/contact.js.map +1 -1
  14. package/dist/device/curtain.d.ts +9 -8
  15. package/dist/device/curtain.d.ts.map +1 -1
  16. package/dist/device/curtain.js +86 -14
  17. package/dist/device/curtain.js.map +1 -1
  18. package/dist/device/humidifier.d.ts +8 -7
  19. package/dist/device/humidifier.d.ts.map +1 -1
  20. package/dist/device/humidifier.js +152 -27
  21. package/dist/device/humidifier.js.map +1 -1
  22. package/dist/device/lock.d.ts +8 -7
  23. package/dist/device/lock.d.ts.map +1 -1
  24. package/dist/device/lock.js +84 -12
  25. package/dist/device/lock.js.map +1 -1
  26. package/dist/device/meter.d.ts +4 -4
  27. package/dist/device/meter.d.ts.map +1 -1
  28. package/dist/device/meter.js +51 -8
  29. package/dist/device/meter.js.map +1 -1
  30. package/dist/device/meterplus.d.ts +3 -3
  31. package/dist/device/meterplus.d.ts.map +1 -1
  32. package/dist/device/meterplus.js +49 -6
  33. package/dist/device/meterplus.js.map +1 -1
  34. package/dist/device/motion.d.ts +3 -3
  35. package/dist/device/motion.d.ts.map +1 -1
  36. package/dist/device/motion.js +49 -9
  37. package/dist/device/motion.js.map +1 -1
  38. package/dist/device/plug.d.ts +8 -7
  39. package/dist/device/plug.d.ts.map +1 -1
  40. package/dist/device/plug.js +83 -11
  41. package/dist/device/plug.js.map +1 -1
  42. package/dist/device/striplight.d.ts +8 -7
  43. package/dist/device/striplight.d.ts.map +1 -1
  44. package/dist/device/striplight.js +149 -19
  45. package/dist/device/striplight.js.map +1 -1
  46. package/dist/irdevice/airconditioner.d.ts +5 -4
  47. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  48. package/dist/irdevice/airconditioner.js +40 -6
  49. package/dist/irdevice/airconditioner.js.map +1 -1
  50. package/dist/irdevice/airpurifier.d.ts +5 -4
  51. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  52. package/dist/irdevice/airpurifier.js +40 -6
  53. package/dist/irdevice/airpurifier.js.map +1 -1
  54. package/dist/irdevice/camera.d.ts +5 -4
  55. package/dist/irdevice/camera.d.ts.map +1 -1
  56. package/dist/irdevice/camera.js +40 -6
  57. package/dist/irdevice/camera.js.map +1 -1
  58. package/dist/irdevice/fan.d.ts +7 -6
  59. package/dist/irdevice/fan.d.ts.map +1 -1
  60. package/dist/irdevice/fan.js +40 -6
  61. package/dist/irdevice/fan.js.map +1 -1
  62. package/dist/irdevice/light.d.ts +5 -4
  63. package/dist/irdevice/light.d.ts.map +1 -1
  64. package/dist/irdevice/light.js +40 -6
  65. package/dist/irdevice/light.js.map +1 -1
  66. package/dist/irdevice/other.d.ts +5 -4
  67. package/dist/irdevice/other.d.ts.map +1 -1
  68. package/dist/irdevice/other.js +40 -6
  69. package/dist/irdevice/other.js.map +1 -1
  70. package/dist/irdevice/tv.d.ts +7 -6
  71. package/dist/irdevice/tv.d.ts.map +1 -1
  72. package/dist/irdevice/tv.js +40 -6
  73. package/dist/irdevice/tv.js.map +1 -1
  74. package/dist/irdevice/vacuumcleaner.d.ts +5 -4
  75. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.js +40 -6
  77. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  78. package/dist/irdevice/waterheater.d.ts +5 -4
  79. package/dist/irdevice/waterheater.d.ts.map +1 -1
  80. package/dist/irdevice/waterheater.js +40 -6
  81. package/dist/irdevice/waterheater.js.map +1 -1
  82. package/dist/platform.d.ts +3 -5
  83. package/dist/platform.d.ts.map +1 -1
  84. package/dist/platform.js +141 -95
  85. package/dist/platform.js.map +1 -1
  86. package/dist/settings.d.ts +2 -16
  87. package/dist/settings.d.ts.map +1 -1
  88. package/dist/settings.js +3 -3
  89. package/dist/settings.js.map +1 -1
  90. package/package.json +6 -7
  91. package/src/device/bot.ts +87 -15
  92. package/src/device/colorbulb.ts +186 -41
  93. package/src/device/contact.ts +49 -10
  94. package/src/device/curtain.ts +92 -19
  95. package/src/device/humidifier.ts +164 -30
  96. package/src/device/lock.ts +88 -16
  97. package/src/device/meter.ts +51 -12
  98. package/src/device/meterplus.ts +48 -9
  99. package/src/device/motion.ts +48 -12
  100. package/src/device/plug.ts +87 -15
  101. package/src/device/striplight.ts +161 -24
  102. package/src/irdevice/airconditioner.ts +43 -8
  103. package/src/irdevice/airpurifier.ts +43 -8
  104. package/src/irdevice/camera.ts +43 -8
  105. package/src/irdevice/fan.ts +44 -9
  106. package/src/irdevice/light.ts +43 -8
  107. package/src/irdevice/other.ts +43 -8
  108. package/src/irdevice/tv.ts +44 -9
  109. package/src/irdevice/vacuumcleaner.ts +43 -8
  110. package/src/irdevice/waterheater.ts +43 -8
  111. package/src/platform.ts +154 -108
  112. package/src/settings.ts +6 -10
@@ -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, payload, 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;
@@ -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')) {
@@ -394,9 +433,42 @@ export class Plug {
394
433
  );
395
434
 
396
435
  // 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);
436
+ const t = Date.now();
437
+ const nonce = 'requestID';
438
+ const data = this.platform.config.credentials?.token + t + nonce;
439
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
440
+ const sign = signTerm.toString('base64');
441
+ this.debugLog(`Plug: ${this.accessory.displayName} sign: ${sign}`);
442
+ const options = {
443
+ hostname: 'api.switch-bot.com',
444
+ port: 443,
445
+ path: `/v1.1/devices/${this.device.deviceId}/commands`,
446
+ method: 'POST',
447
+ headers: {
448
+ Authorization: this.platform.config.credentials?.token,
449
+ sign: sign,
450
+ nonce: nonce,
451
+ t: t,
452
+ 'Content-Type': 'application/json',
453
+ },
454
+ };
455
+
456
+ const req = https.request(options, (res) => {
457
+ this.debugLog(`Plug: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
458
+ this.statusCode({ res });
459
+ res.on('data', (d) => {
460
+ this.debugLog(`Plug: ${this.accessory.displayName} d: ${d}`);
461
+ });
462
+ });
463
+
464
+ req.on('error', (error) => {
465
+ this.errorLog(`Plug: ${this.accessory.displayName} error: ${error}`);
466
+ });
467
+
468
+ req.write(payload);
469
+ req.end();
470
+
471
+ this.debugLog(`Plug: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
400
472
  this.OnCached = this.On;
401
473
  this.accessory.context.On = this.OnCached;
402
474
  }
@@ -422,8 +494,8 @@ export class Plug {
422
494
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
423
495
  }
424
496
 
425
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
426
- switch (push.data.statusCode) {
497
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
498
+ switch (res.statusCode) {
427
499
  case 151:
428
500
  this.errorLog(`Plug: ${this.accessory.displayName} Command not supported by this device type.`);
429
501
  break;
@@ -444,7 +516,7 @@ export class Plug {
444
516
  case 190:
445
517
  this.errorLog(
446
518
  `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`,
519
+ ` Or command: ${JSON.stringify(res)} format is invalid`,
448
520
  );
449
521
  break;
450
522
  case 100:
@@ -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, tap } from 'rxjs/operators';
5
8
  import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
6
- import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse, payload, hs2rgb, rgb2hs, deviceStatus } from '../settings';
7
- import { Context } from 'vm';
9
+ import { device, devicesConfig, switchbot, payload, hs2rgb, rgb2hs, deviceStatus, HostDomain, DevicePath } from '../settings';
8
10
 
9
11
  /**
10
12
  * Platform Accessory
@@ -29,7 +31,7 @@ export class StripLight {
29
31
  power: deviceStatus['power'];
30
32
  color: deviceStatus['color'];
31
33
  brightness: deviceStatus['brightness'];
32
- deviceStatus!: deviceStatusResponse;
34
+ deviceStatus!: any; //deviceStatusResponse;
33
35
 
34
36
  // BLE Others
35
37
  switchbot!: switchbot;
@@ -210,14 +212,50 @@ export class StripLight {
210
212
 
211
213
  async refreshStatus(): Promise<void> {
212
214
  try {
213
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
214
- this.debugLog(`Strip Light: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
215
- this.power = this.deviceStatus.body.power;
216
- this.color = this.deviceStatus.body.color;
217
- this.brightness = this.deviceStatus.body.brightness;
218
-
219
- this.parseStatus();
220
- this.updateHomeKitCharacteristics();
215
+ const t = Date.now();
216
+ const nonce = 'requestID';
217
+ const data = this.platform.config.credentials?.token + t + nonce;
218
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
219
+ const sign = signTerm.toString('base64');
220
+ this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
221
+ const options = {
222
+ hostname: HostDomain,
223
+ port: 443,
224
+ path: `${DevicePath}/${this.device.deviceId}/status`,
225
+ method: 'GET',
226
+ headers: {
227
+ Authorization: this.platform.config.credentials?.token,
228
+ sign: sign,
229
+ nonce: nonce,
230
+ t: t,
231
+ 'Content-Type': 'application/json',
232
+ },
233
+ };
234
+ const req = https.request(options, (res) => {
235
+ this.debugLog(`Strip Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
236
+ let rawData = '';
237
+ res.on('data', (d) => {
238
+ rawData += d;
239
+ this.debugLog(`Strip Light: ${this.accessory.displayName} d: ${d}`);
240
+ });
241
+ res.on('end', () => {
242
+ try {
243
+ this.deviceStatus = JSON.parse(rawData);
244
+ this.debugLog(`Strip Light: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
245
+ this.power = this.deviceStatus.body.power;
246
+ this.color = this.deviceStatus.body.color;
247
+ this.brightness = this.deviceStatus.body.brightness;
248
+ this.parseStatus();
249
+ this.updateHomeKitCharacteristics();
250
+ } catch (e: any) {
251
+ this.errorLog(`Strip Light: ${this.accessory.displayName} error message: ${e.message}`);
252
+ }
253
+ });
254
+ });
255
+ req.on('error', (e: any) => {
256
+ this.errorLog(`Strip Light: ${this.accessory.displayName} error message: ${e.message}`);
257
+ });
258
+ req.end();
221
259
  } catch (e: any) {
222
260
  this.errorLog(`Strip Light: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
223
261
  if (this.deviceLogging.includes('debug')) {
@@ -260,9 +298,42 @@ export class StripLight {
260
298
  );
261
299
 
262
300
  // Make the API request
263
- const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
264
- this.debugLog(`Strip Light: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
265
- this.statusCode(push);
301
+ const t = Date.now();
302
+ const nonce = 'requestID';
303
+ const data = this.platform.config.credentials?.token + t + nonce;
304
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
305
+ const sign = signTerm.toString('base64');
306
+ this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
307
+ const options = {
308
+ hostname: 'api.switch-bot.com',
309
+ port: 443,
310
+ path: `/v1.1/devices/${this.device.deviceId}/commands`,
311
+ method: 'POST',
312
+ headers: {
313
+ Authorization: this.platform.config.credentials?.token,
314
+ sign: sign,
315
+ nonce: nonce,
316
+ t: t,
317
+ 'Content-Type': 'application/json',
318
+ },
319
+ };
320
+
321
+ const req = https.request(options, (res) => {
322
+ this.debugLog(`Strip Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
323
+ this.statusCode({ res });
324
+ res.on('data', (d) => {
325
+ this.debugLog(`Strip Light: ${this.accessory.displayName} d: ${d}`);
326
+ });
327
+ });
328
+
329
+ req.on('error', (error) => {
330
+ this.errorLog(`Strip Light: ${this.accessory.displayName} error: ${error}`);
331
+ });
332
+
333
+ req.write(payload);
334
+ req.end();
335
+
336
+ this.debugLog(`Strip Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
266
337
  this.OnCached = this.On;
267
338
  this.accessory.context.On = this.OnCached;
268
339
  }
@@ -307,9 +378,42 @@ export class StripLight {
307
378
  );
308
379
 
309
380
  // Make the API request
310
- const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
311
- this.debugLog(`Strip Light: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
312
- this.statusCode(push);
381
+ const t = Date.now();
382
+ const nonce = 'requestID';
383
+ const data = this.platform.config.credentials?.token + t + nonce;
384
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
385
+ const sign = signTerm.toString('base64');
386
+ this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
387
+ const options = {
388
+ hostname: 'api.switch-bot.com',
389
+ port: 443,
390
+ path: `/v1.1/devices/${this.device.deviceId}/commands`,
391
+ method: 'POST',
392
+ headers: {
393
+ Authorization: this.platform.config.credentials?.token,
394
+ sign: sign,
395
+ nonce: nonce,
396
+ t: t,
397
+ 'Content-Type': 'application/json',
398
+ },
399
+ };
400
+
401
+ const req = https.request(options, (res) => {
402
+ this.debugLog(`Strip Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
403
+ this.statusCode({ res });
404
+ res.on('data', (d) => {
405
+ this.debugLog(`Strip Light: ${this.accessory.displayName} d: ${d}`);
406
+ });
407
+ });
408
+
409
+ req.on('error', (error) => {
410
+ this.errorLog(`Strip Light: ${this.accessory.displayName} error: ${error}`);
411
+ });
412
+
413
+ req.write(payload);
414
+ req.end();
415
+
416
+ this.debugLog(`Strip Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
313
417
  this.HueCached = this.Hue;
314
418
  this.SaturationCached = this.Saturation;
315
419
  } else {
@@ -344,9 +448,42 @@ export class StripLight {
344
448
  );
345
449
 
346
450
  // Make the API request
347
- const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
348
- this.debugLog(`Strip Light: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
349
- this.statusCode(push);
451
+ const t = Date.now();
452
+ const nonce = 'requestID';
453
+ const data = this.platform.config.credentials?.token + t + nonce;
454
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
455
+ const sign = signTerm.toString('base64');
456
+ this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
457
+ const options = {
458
+ hostname: 'api.switch-bot.com',
459
+ port: 443,
460
+ path: `/v1.1/devices/${this.device.deviceId}/commands`,
461
+ method: 'POST',
462
+ headers: {
463
+ Authorization: this.platform.config.credentials?.token,
464
+ sign: sign,
465
+ nonce: nonce,
466
+ t: t,
467
+ 'Content-Type': 'application/json',
468
+ },
469
+ };
470
+
471
+ const req = https.request(options, (res) => {
472
+ this.debugLog(`Strip Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
473
+ this.statusCode({ res });
474
+ res.on('data', (d) => {
475
+ this.debugLog(`Strip Light: ${this.accessory.displayName} d: ${d}`);
476
+ });
477
+ });
478
+
479
+ req.on('error', (error) => {
480
+ this.errorLog(`Strip Light: ${this.accessory.displayName} error: ${error}`);
481
+ });
482
+
483
+ req.write(payload);
484
+ req.end();
485
+
486
+ this.debugLog(`Strip Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
350
487
  this.BrightnessCached = this.Brightness;
351
488
  } else {
352
489
  this.debugLog(
@@ -399,8 +536,8 @@ export class StripLight {
399
536
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
400
537
  }
401
538
 
402
- statusCode(push: AxiosResponse<{ statusCode: number }>): void {
403
- switch (push.data.statusCode) {
539
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
540
+ switch (res.statusCode) {
404
541
  case 151:
405
542
  this.errorLog(`Strip Light: ${this.accessory.displayName} Command not supported by this device type.`);
406
543
  break;
@@ -421,7 +558,7 @@ export class StripLight {
421
558
  case 190:
422
559
  this.errorLog(
423
560
  `Strip Light: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
424
- ` Or command: ${JSON.stringify(push.data)} format is invalid`,
561
+ ` Or command: ${JSON.stringify(res)} format is invalid`,
425
562
  );
426
563
  break;
427
564
  case 100:
@@ -1,6 +1,8 @@
1
- import { AxiosResponse } from 'axios';
1
+ import https from 'https';
2
+ import crypto from 'crypto';
3
+ import { IncomingMessage } from 'http';
2
4
  import { SwitchBotPlatform } from '../platform';
3
- import { irDevicesConfig, DeviceURL, irdevice, payload } from '../settings';
5
+ import { irDevicesConfig, irdevice, payload, HostDomain, DevicePath } from '../settings';
4
6
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
5
7
 
6
8
  /**
@@ -258,9 +260,42 @@ export class AirConditioner {
258
260
  );
259
261
 
260
262
  // Make the API request
261
- const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
262
- this.debugLog(`Air Conditioner: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
263
- this.statusCode(push);
263
+ const t = Date.now();
264
+ const nonce = 'requestID';
265
+ const data = this.platform.config.credentials?.token + t + nonce;
266
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
267
+ const sign = signTerm.toString('base64');
268
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} sign: ${sign}`);
269
+ const options = {
270
+ hostname: HostDomain,
271
+ port: 443,
272
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
273
+ method: 'POST',
274
+ headers: {
275
+ Authorization: this.platform.config.credentials?.token,
276
+ sign: sign,
277
+ nonce: nonce,
278
+ t: t,
279
+ 'Content-Type': 'application/json',
280
+ },
281
+ };
282
+
283
+ const req = https.request(options, (res) => {
284
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
285
+ this.statusCode({ res });
286
+ res.on('data', (d) => {
287
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} d: ${d}`);
288
+ });
289
+ });
290
+
291
+ req.on('error', (error) => {
292
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} error: ${error}`);
293
+ });
294
+
295
+ req.write(payload);
296
+ req.end();
297
+
298
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
264
299
  this.CurrentTemperatureCached = this.CurrentTemperature;
265
300
  this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
266
301
  this.HeatingThresholdTemperature = this.CurrentTemperatureCached;
@@ -279,8 +314,8 @@ export class AirConditioner {
279
314
  }
280
315
  }
281
316
 
282
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
283
- switch (push.data.statusCode) {
317
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
318
+ switch (res.statusCode) {
284
319
  case 151:
285
320
  this.errorLog(`Air Conditioner: ${this.accessory.displayName} Command not supported by this device type.`);
286
321
  break;
@@ -299,7 +334,7 @@ export class AirConditioner {
299
334
  case 190:
300
335
  this.errorLog(
301
336
  `Air Conditioner: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
302
- ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
337
+ ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
303
338
  );
304
339
  break;
305
340
  case 100:
@@ -1,6 +1,8 @@
1
- import { AxiosResponse } from 'axios';
1
+ import https from 'https';
2
+ import crypto from 'crypto';
3
+ import { IncomingMessage } from 'http';
2
4
  import { SwitchBotPlatform } from '../platform';
3
- import { irDevicesConfig, DeviceURL, irdevice, payload } from '../settings';
5
+ import { irDevicesConfig, irdevice, payload, HostDomain, DevicePath } from '../settings';
4
6
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
5
7
 
6
8
  /**
@@ -220,9 +222,42 @@ export class AirPurifier {
220
222
  );
221
223
 
222
224
  // Make the API request
223
- const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
224
- this.debugLog(`Air Purifier: ${this.accessory.displayName} pushChanges: ${push.data}`);
225
- this.statusCode(push);
225
+ const t = Date.now();
226
+ const nonce = 'requestID';
227
+ const data = this.platform.config.credentials?.token + t + nonce;
228
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
229
+ const sign = signTerm.toString('base64');
230
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} sign: ${sign}`);
231
+ const options = {
232
+ hostname: HostDomain,
233
+ port: 443,
234
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
235
+ method: 'POST',
236
+ headers: {
237
+ Authorization: this.platform.config.credentials?.token,
238
+ sign: sign,
239
+ nonce: nonce,
240
+ t: t,
241
+ 'Content-Type': 'application/json',
242
+ },
243
+ };
244
+
245
+ const req = https.request(options, (res) => {
246
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
247
+ this.statusCode({ res });
248
+ res.on('data', (d) => {
249
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} d: ${d}`);
250
+ });
251
+ });
252
+
253
+ req.on('error', (error) => {
254
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} error: ${error}`);
255
+ });
256
+
257
+ req.write(payload);
258
+ req.end();
259
+
260
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
226
261
  this.updateHomeKitCharacteristics();
227
262
  this.CurrentTemperatureCached = this.CurrentTemperature;
228
263
  this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
@@ -237,8 +272,8 @@ export class AirPurifier {
237
272
  }
238
273
  }
239
274
 
240
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
241
- switch (push.data.statusCode) {
275
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
276
+ switch (res.statusCode) {
242
277
  case 151:
243
278
  this.errorLog(`Air Purifier: ${this.accessory.displayName} Command not supported by this device type.`);
244
279
  break;
@@ -257,7 +292,7 @@ export class AirPurifier {
257
292
  case 190:
258
293
  this.errorLog(
259
294
  `Air Purifier: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
260
- ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
295
+ ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
261
296
  );
262
297
  break;
263
298
  case 100:
@@ -1,6 +1,8 @@
1
- import { AxiosResponse } from 'axios';
1
+ import https from 'https';
2
+ import crypto from 'crypto';
3
+ import { IncomingMessage } from 'http';
2
4
  import { SwitchBotPlatform } from '../platform';
3
- import { irDevicesConfig, DeviceURL, irdevice, payload } from '../settings';
5
+ import { irDevicesConfig, irdevice, payload, HostDomain, DevicePath } from '../settings';
4
6
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
5
7
 
6
8
  /**
@@ -112,9 +114,42 @@ export class Camera {
112
114
  );
113
115
 
114
116
  // Make the API request
115
- const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
116
- this.debugLog(`Camera: ${this.accessory.displayName} pushChanges: ${push.data}`);
117
- this.statusCode(push);
117
+ const t = Date.now();
118
+ const nonce = 'requestID';
119
+ const data = this.platform.config.credentials?.token + t + nonce;
120
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
121
+ const sign = signTerm.toString('base64');
122
+ this.debugLog(`Camera: ${this.accessory.displayName} sign: ${sign}`);
123
+ const options = {
124
+ hostname: HostDomain,
125
+ port: 443,
126
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
127
+ method: 'POST',
128
+ headers: {
129
+ Authorization: this.platform.config.credentials?.token,
130
+ sign: sign,
131
+ nonce: nonce,
132
+ t: t,
133
+ 'Content-Type': 'application/json',
134
+ },
135
+ };
136
+
137
+ const req = https.request(options, (res) => {
138
+ this.debugLog(`Camera: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
139
+ this.statusCode({ res });
140
+ res.on('data', (d) => {
141
+ this.debugLog(`Camera: ${this.accessory.displayName} d: ${d}`);
142
+ });
143
+ });
144
+
145
+ req.on('error', (error) => {
146
+ this.errorLog(`Camera: ${this.accessory.displayName} error: ${error}`);
147
+ });
148
+
149
+ req.write(payload);
150
+ req.end();
151
+
152
+ this.debugLog(`Camera: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
118
153
  this.updateHomeKitCharacteristics();
119
154
  this.OnCached = this.On;
120
155
  this.accessory.context.On = this.OnCached;
@@ -129,8 +164,8 @@ export class Camera {
129
164
  }
130
165
  }
131
166
 
132
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
133
- switch (push.data.statusCode) {
167
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
168
+ switch (res.statusCode) {
134
169
  case 151:
135
170
  this.errorLog(`Camera: ${this.accessory.displayName} Command not supported by this device type.`);
136
171
  break;
@@ -149,7 +184,7 @@ export class Camera {
149
184
  case 190:
150
185
  this.errorLog(
151
186
  `Camera: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
152
- ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
187
+ ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
153
188
  );
154
189
  break;
155
190
  case 100: