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

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 +97 -21
  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 +221 -56
  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 +95 -21
  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 +180 -59
  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 +98 -22
  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 +96 -20
  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 +186 -47
  45. package/dist/device/striplight.js.map +1 -1
  46. package/dist/irdevice/airconditioner.d.ts +7 -6
  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 +7 -6
  51. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  52. package/dist/irdevice/airpurifier.js +46 -11
  53. package/dist/irdevice/airpurifier.js.map +1 -1
  54. package/dist/irdevice/camera.d.ts +7 -6
  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 +8 -7
  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 +7 -6
  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 +7 -6
  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 +8 -7
  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 +7 -6
  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 +7 -6
  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 -21
  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 +97 -30
  92. package/src/device/colorbulb.ts +225 -93
  93. package/src/device/contact.ts +49 -10
  94. package/src/device/curtain.ts +98 -31
  95. package/src/device/humidifier.ts +182 -77
  96. package/src/device/lock.ts +97 -30
  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 +97 -29
  101. package/src/device/striplight.ts +189 -68
  102. package/src/irdevice/airconditioner.ts +44 -9
  103. package/src/irdevice/airpurifier.ts +52 -17
  104. package/src/irdevice/camera.ts +46 -11
  105. package/src/irdevice/fan.ts +50 -15
  106. package/src/irdevice/light.ts +48 -13
  107. package/src/irdevice/other.ts +46 -11
  108. package/src/irdevice/tv.ts +56 -21
  109. package/src/irdevice/vacuumcleaner.ts +46 -11
  110. package/src/irdevice/waterheater.ts +46 -11
  111. package/src/platform.ts +154 -108
  112. package/src/settings.ts +2 -25
@@ -1,7 +1,9 @@
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
5
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
4
- import { DeviceURL, irdevice, deviceStatusResponse, irDevicesConfig, payload } from '../settings';
6
+ import { irdevice, irDevicesConfig, HostDomain, DevicePath } from '../settings';
5
7
 
6
8
  /**
7
9
  * Platform Accessory
@@ -21,7 +23,7 @@ export class Fan {
21
23
  RotationDirection!: CharacteristicValue;
22
24
 
23
25
  // Others
24
- deviceStatus!: deviceStatusResponse;
26
+ deviceStatus!: any;
25
27
 
26
28
  // Config
27
29
  minStep?: number;
@@ -190,7 +192,7 @@ export class Fan {
190
192
  commandType: 'command',
191
193
  parameter: 'default',
192
194
  command: 'turnOn',
193
- } as payload;
195
+ };
194
196
  await this.pushTVChanges(payload);
195
197
  }
196
198
  }
@@ -200,7 +202,7 @@ export class Fan {
200
202
  commandType: 'command',
201
203
  parameter: 'default',
202
204
  command: 'turnOff',
203
- } as payload;
205
+ };
204
206
  await this.pushTVChanges(payload);
205
207
  }
206
208
 
@@ -209,7 +211,7 @@ export class Fan {
209
211
  commandType: 'command',
210
212
  parameter: 'default',
211
213
  command: 'highSpeed',
212
- } as payload;
214
+ };
213
215
  await this.pushTVChanges(payload);
214
216
  }
215
217
 
@@ -218,7 +220,7 @@ export class Fan {
218
220
  commandType: 'command',
219
221
  parameter: 'default',
220
222
  command: 'lowSpeed',
221
- } as payload;
223
+ };
222
224
  await this.pushTVChanges(payload);
223
225
  }
224
226
 
@@ -227,11 +229,11 @@ export class Fan {
227
229
  commandType: 'command',
228
230
  parameter: 'default',
229
231
  command: 'swing',
230
- } as payload;
232
+ };
231
233
  await this.pushTVChanges(payload);
232
234
  }
233
235
 
234
- async pushTVChanges(payload: payload): Promise<void> {
236
+ async pushTVChanges(payload): Promise<void> {
235
237
  try {
236
238
  this.infoLog(
237
239
  `Fan: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
@@ -239,9 +241,42 @@ export class Fan {
239
241
  );
240
242
 
241
243
  // Make the API request
242
- const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
243
- this.debugLog(`Fan: ${this.accessory.displayName} pushTVChanges: ${push.data}`);
244
- this.statusCode(push);
244
+ const t = Date.now();
245
+ const nonce = 'requestID';
246
+ const data = this.platform.config.credentials?.token + t + nonce;
247
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
248
+ const sign = signTerm.toString('base64');
249
+ this.debugLog(`Fan: ${this.accessory.displayName} sign: ${sign}`);
250
+ const options = {
251
+ hostname: HostDomain,
252
+ port: 443,
253
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
254
+ method: 'POST',
255
+ headers: {
256
+ Authorization: this.platform.config.credentials?.token,
257
+ sign: sign,
258
+ nonce: nonce,
259
+ t: t,
260
+ 'Content-Type': 'application/json',
261
+ },
262
+ };
263
+
264
+ const req = https.request(options, (res) => {
265
+ this.debugLog(`Fan: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
266
+ this.statusCode({ res });
267
+ res.on('data', (d) => {
268
+ this.debugLog(`an: ${this.accessory.displayName} d: ${d}`);
269
+ });
270
+ });
271
+
272
+ req.on('error', (error) => {
273
+ this.errorLog(`Fan: ${this.accessory.displayName} error: ${error}`);
274
+ });
275
+
276
+ req.write(payload);
277
+ req.end();
278
+
279
+ this.debugLog(`Fan: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
245
280
  this.updateHomeKitCharacteristics();
246
281
  } catch (e: any) {
247
282
  this.errorLog(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
@@ -254,8 +289,8 @@ export class Fan {
254
289
  }
255
290
  }
256
291
 
257
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
258
- switch (push.data.statusCode) {
292
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
293
+ switch (res.statusCode) {
259
294
  case 151:
260
295
  this.errorLog(`Fan: ${this.accessory.displayName} Command not supported by this device type.`);
261
296
  break;
@@ -274,7 +309,7 @@ export class Fan {
274
309
  case 190:
275
310
  this.errorLog(
276
311
  `Fan: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
277
- ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
312
+ ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
278
313
  );
279
314
  break;
280
315
  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, HostDomain, DevicePath } from '../settings';
4
6
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
5
7
 
6
8
  /**
@@ -103,7 +105,7 @@ export class Light {
103
105
  commandType: 'command',
104
106
  parameter: 'default',
105
107
  command: 'turnOn',
106
- } as payload;
108
+ };
107
109
  await this.pushChanges(payload);
108
110
  }
109
111
  }
@@ -114,7 +116,7 @@ export class Light {
114
116
  commandType: 'command',
115
117
  parameter: 'default',
116
118
  command: 'turnOff',
117
- } as payload;
119
+ };
118
120
  await this.pushChanges(payload);
119
121
  }
120
122
  }
@@ -124,7 +126,7 @@ export class Light {
124
126
  commandType: 'command',
125
127
  parameter: 'default',
126
128
  command: 'brightnessUp',
127
- } as payload;
129
+ };
128
130
  await this.pushChanges(payload);
129
131
  }
130
132
 
@@ -133,11 +135,11 @@ export class Light {
133
135
  commandType: 'command',
134
136
  parameter: 'default',
135
137
  command: 'brightnessDown',
136
- } as payload;
138
+ };
137
139
  await this.pushChanges(payload);
138
140
  }
139
141
 
140
- async pushChanges(payload: payload): Promise<void> {
142
+ async pushChanges(payload): Promise<void> {
141
143
  try {
142
144
  this.infoLog(
143
145
  `Light: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
@@ -145,9 +147,42 @@ export class Light {
145
147
  );
146
148
 
147
149
  // Make the API request
148
- const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
149
- this.debugLog(`Light: ${this.accessory.displayName} pushChanges: ${push.data}`);
150
- this.statusCode(push);
150
+ const t = Date.now();
151
+ const nonce = 'requestID';
152
+ const data = this.platform.config.credentials?.token + t + nonce;
153
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
154
+ const sign = signTerm.toString('base64');
155
+ this.debugLog(`Light: ${this.accessory.displayName} sign: ${sign}`);
156
+ const options = {
157
+ hostname: HostDomain,
158
+ port: 443,
159
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
160
+ method: 'POST',
161
+ headers: {
162
+ Authorization: this.platform.config.credentials?.token,
163
+ sign: sign,
164
+ nonce: nonce,
165
+ t: t,
166
+ 'Content-Type': 'application/json',
167
+ },
168
+ };
169
+
170
+ const req = https.request(options, (res) => {
171
+ this.debugLog(`Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
172
+ this.statusCode({ res });
173
+ res.on('data', (d) => {
174
+ this.debugLog(`Light: ${this.accessory.displayName} d: ${d}`);
175
+ });
176
+ });
177
+
178
+ req.on('error', (error) => {
179
+ this.errorLog(`Light: ${this.accessory.displayName} error: ${error}`);
180
+ });
181
+
182
+ req.write(payload);
183
+ req.end();
184
+
185
+ this.debugLog(`Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
151
186
  this.OnCached = this.On;
152
187
  this.accessory.context.On = this.OnCached;
153
188
  this.updateHomeKitCharacteristics();
@@ -162,8 +197,8 @@ export class Light {
162
197
  }
163
198
  }
164
199
 
165
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void>{
166
- switch (push.data.statusCode) {
200
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
201
+ switch (res.statusCode) {
167
202
  case 151:
168
203
  this.errorLog(`Light: ${this.accessory.displayName} Command not supported by this device type.`);
169
204
  break;
@@ -182,7 +217,7 @@ export class Light {
182
217
  case 190:
183
218
  this.errorLog(
184
219
  `Light: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
185
- ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
220
+ ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
186
221
  );
187
222
  break;
188
223
  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, HostDomain, DevicePath } from '../settings';
4
6
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
5
7
 
6
8
  /**
@@ -101,7 +103,7 @@ export class Others {
101
103
  commandType: 'customize',
102
104
  parameter: 'default',
103
105
  command: `${this.device.other.commandOn}`,
104
- } as payload;
106
+ };
105
107
  await this.pushChanges(payload);
106
108
  }
107
109
  } else {
@@ -124,7 +126,7 @@ export class Others {
124
126
  commandType: 'customize',
125
127
  parameter: 'default',
126
128
  command: `${this.device.other.commandOff}`,
127
- } as payload;
129
+ };
128
130
  await this.pushChanges(payload);
129
131
  }
130
132
  } else {
@@ -138,7 +140,7 @@ export class Others {
138
140
  }
139
141
  }
140
142
 
141
- async pushChanges(payload: payload): Promise<void> {
143
+ async pushChanges(payload): Promise<void> {
142
144
  try {
143
145
  this.infoLog(
144
146
  `Other: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
@@ -146,9 +148,42 @@ export class Others {
146
148
  );
147
149
 
148
150
  // Make the API request
149
- const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
150
- this.debugLog(`Other: ${this.accessory.displayName} pushChanges: ${push.data}`);
151
- this.statusCode(push);
151
+ const t = Date.now();
152
+ const nonce = 'requestID';
153
+ const data = this.platform.config.credentials?.token + t + nonce;
154
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
155
+ const sign = signTerm.toString('base64');
156
+ this.debugLog(`Other: ${this.accessory.displayName} sign: ${sign}`);
157
+ const options = {
158
+ hostname: HostDomain,
159
+ port: 443,
160
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
161
+ method: 'POST',
162
+ headers: {
163
+ Authorization: this.platform.config.credentials?.token,
164
+ sign: sign,
165
+ nonce: nonce,
166
+ t: t,
167
+ 'Content-Type': 'application/json',
168
+ },
169
+ };
170
+
171
+ const req = https.request(options, (res) => {
172
+ this.debugLog(`Other: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
173
+ this.statusCode({ res });
174
+ res.on('data', (d) => {
175
+ this.debugLog(`Other: ${this.accessory.displayName} d: ${d}`);
176
+ });
177
+ });
178
+
179
+ req.on('error', (error) => {
180
+ this.errorLog(`Other: ${this.accessory.displayName} error: ${error}`);
181
+ });
182
+
183
+ req.write(payload);
184
+ req.end();
185
+
186
+ this.debugLog(`Other: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
152
187
  this.updateHomeKitCharacteristics();
153
188
  } catch (e: any) {
154
189
  this.errorLog(`Other: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
@@ -161,8 +196,8 @@ export class Others {
161
196
  }
162
197
  }
163
198
 
164
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void>{
165
- switch (push.data.statusCode) {
199
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
200
+ switch (res.statusCode) {
166
201
  case 151:
167
202
  this.errorLog(`Other: ${this.accessory.displayName} Command not supported by this device type.`);
168
203
  break;
@@ -181,7 +216,7 @@ export class Others {
181
216
  case 190:
182
217
  this.errorLog(
183
218
  `Other: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
184
- ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
219
+ ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
185
220
  );
186
221
  break;
187
222
  case 100:
@@ -1,7 +1,9 @@
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
5
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
4
- import { DeviceURL, irdevice, deviceStatusResponse, irDevicesConfig, payload } from '../settings';
6
+ import { irdevice, irDevicesConfig, HostDomain, DevicePath } from '../settings';
5
7
 
6
8
  /**
7
9
  * Platform Accessory
@@ -19,7 +21,7 @@ export class TV {
19
21
  ActiveIdentifier!: CharacteristicValue;
20
22
 
21
23
  // Others
22
- deviceStatus!: deviceStatusResponse;
24
+ deviceStatus!: any;
23
25
 
24
26
  // Config
25
27
  deviceLogging!: string;
@@ -239,7 +241,7 @@ export class TV {
239
241
  commandType: 'command',
240
242
  parameter: 'default',
241
243
  command: 'turnOn',
242
- } as payload;
244
+ };
243
245
  await this.pushTVChanges(payload);
244
246
  }
245
247
  }
@@ -249,7 +251,7 @@ export class TV {
249
251
  commandType: 'command',
250
252
  parameter: 'default',
251
253
  command: 'turnOff',
252
- } as payload;
254
+ };
253
255
  await this.pushTVChanges(payload);
254
256
  }
255
257
 
@@ -258,7 +260,7 @@ export class TV {
258
260
  commandType: 'command',
259
261
  parameter: 'default',
260
262
  command: 'Ok',
261
- } as payload;
263
+ };
262
264
  await this.pushTVChanges(payload);
263
265
  }
264
266
 
@@ -267,7 +269,7 @@ export class TV {
267
269
  commandType: 'command',
268
270
  parameter: 'default',
269
271
  command: 'Back',
270
- } as payload;
272
+ };
271
273
  await this.pushTVChanges(payload);
272
274
  }
273
275
 
@@ -276,7 +278,7 @@ export class TV {
276
278
  commandType: 'command',
277
279
  parameter: 'default',
278
280
  command: 'Menu',
279
- } as payload;
281
+ };
280
282
  await this.pushTVChanges(payload);
281
283
  }
282
284
 
@@ -285,7 +287,7 @@ export class TV {
285
287
  commandType: 'command',
286
288
  parameter: 'default',
287
289
  command: 'Up',
288
- } as payload;
290
+ };
289
291
  await this.pushTVChanges(payload);
290
292
  }
291
293
 
@@ -294,7 +296,7 @@ export class TV {
294
296
  commandType: 'command',
295
297
  parameter: 'default',
296
298
  command: 'Down',
297
- } as payload;
299
+ };
298
300
  await this.pushTVChanges(payload);
299
301
  }
300
302
 
@@ -303,7 +305,7 @@ export class TV {
303
305
  commandType: 'command',
304
306
  parameter: 'default',
305
307
  command: 'Right',
306
- } as payload;
308
+ };
307
309
  await this.pushTVChanges(payload);
308
310
  }
309
311
 
@@ -312,7 +314,7 @@ export class TV {
312
314
  commandType: 'command',
313
315
  parameter: 'default',
314
316
  command: 'Left',
315
- } as payload;
317
+ };
316
318
  await this.pushTVChanges(payload);
317
319
  }
318
320
 
@@ -321,7 +323,7 @@ export class TV {
321
323
  commandType: 'command',
322
324
  parameter: 'default',
323
325
  command: 'volumeAdd',
324
- } as payload;
326
+ };
325
327
  await this.pushTVChanges(payload);
326
328
  }
327
329
 
@@ -330,11 +332,11 @@ export class TV {
330
332
  commandType: 'command',
331
333
  parameter: 'default',
332
334
  command: 'volumeSub',
333
- } as payload;
335
+ };
334
336
  await this.pushTVChanges(payload);
335
337
  }
336
338
 
337
- async pushTVChanges(payload: payload): Promise<void> {
339
+ async pushTVChanges(payload): Promise<void> {
338
340
  try {
339
341
  this.infoLog(
340
342
  `${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
@@ -342,9 +344,42 @@ export class TV {
342
344
  );
343
345
 
344
346
  // Make the API request
345
- const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
346
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushChanges: ${push.data}`);
347
- this.statusCode(push);
347
+ const t = Date.now();
348
+ const nonce = 'requestID';
349
+ const data = this.platform.config.credentials?.token + t + nonce;
350
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
351
+ const sign = signTerm.toString('base64');
352
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
353
+ const options = {
354
+ hostname: HostDomain,
355
+ port: 443,
356
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
357
+ method: 'POST',
358
+ headers: {
359
+ Authorization: this.platform.config.credentials?.token,
360
+ sign: sign,
361
+ nonce: nonce,
362
+ t: t,
363
+ 'Content-Type': 'application/json',
364
+ },
365
+ };
366
+
367
+ const req = https.request(options, (res) => {
368
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
369
+ this.statusCode({ res });
370
+ res.on('data', (d) => {
371
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
372
+ });
373
+ });
374
+
375
+ req.on('error', (error) => {
376
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error: ${error}`);
377
+ });
378
+
379
+ req.write(payload);
380
+ req.end();
381
+
382
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
348
383
  this.updateHomeKitCharacteristics();
349
384
  } catch (e: any) {
350
385
  this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
@@ -358,8 +393,8 @@ export class TV {
358
393
  }
359
394
  }
360
395
 
361
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void>{
362
- switch (push.data.statusCode) {
396
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
397
+ switch (res.statusCode) {
363
398
  case 151:
364
399
  this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
365
400
  break;
@@ -379,7 +414,7 @@ export class TV {
379
414
  this.errorLog(
380
415
  `${this.device.remoteType}: ` +
381
416
  `${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
382
- ` Or command: ${JSON.stringify(push.data)} format is invalid`,
417
+ ` Or command: ${JSON.stringify(res)} format is invalid`,
383
418
  );
384
419
  break;
385
420
  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, HostDomain, DevicePath } from '../settings';
4
6
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
5
7
 
6
8
  /**
@@ -88,7 +90,7 @@ export class VacuumCleaner {
88
90
  commandType: 'command',
89
91
  parameter: 'default',
90
92
  command: 'turnOn',
91
- } as payload;
93
+ };
92
94
  await this.pushChanges(payload);
93
95
  }
94
96
  }
@@ -99,12 +101,12 @@ export class VacuumCleaner {
99
101
  commandType: 'command',
100
102
  parameter: 'default',
101
103
  command: 'turnOff',
102
- } as payload;
104
+ };
103
105
  await this.pushChanges(payload);
104
106
  }
105
107
  }
106
108
 
107
- async pushChanges(payload: payload): Promise<void> {
109
+ async pushChanges(payload): Promise<void> {
108
110
  try {
109
111
  this.infoLog(
110
112
  `Vacuum Cleaner: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
@@ -112,9 +114,42 @@ export class VacuumCleaner {
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(`Vacuum Cleaner: ${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(`Vacuum Cleaner: ${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(`Vacuum Cleaner: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
139
+ this.statusCode({ res });
140
+ res.on('data', (d) => {
141
+ this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} d: ${d}`);
142
+ });
143
+ });
144
+
145
+ req.on('error', (error) => {
146
+ this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} error: ${error}`);
147
+ });
148
+
149
+ req.write(payload);
150
+ req.end();
151
+
152
+ this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
118
153
  this.OnCached = this.On;
119
154
  this.accessory.context.On = this.OnCached;
120
155
  this.updateHomeKitCharacteristics();
@@ -130,8 +165,8 @@ export class VacuumCleaner {
130
165
  }
131
166
  }
132
167
 
133
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void>{
134
- switch (push.data.statusCode) {
168
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
169
+ switch (res.statusCode) {
135
170
  case 151:
136
171
  this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} Command not supported by this device type.`);
137
172
  break;
@@ -150,7 +185,7 @@ export class VacuumCleaner {
150
185
  case 190:
151
186
  this.errorLog(
152
187
  `Vacuum Cleaner: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
153
- ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
188
+ ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
154
189
  );
155
190
  break;
156
191
  case 100: