@switchbot/homebridge-switchbot 2.6.0-beta.3 → 2.6.0-beta.5

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 (139) hide show
  1. package/.github/workflows/dependabot.yml +2 -0
  2. package/.vscode/tasks.json +13 -0
  3. package/dist/device/blindtilt.d.ts +1 -5
  4. package/dist/device/blindtilt.d.ts.map +1 -1
  5. package/dist/device/blindtilt.js +80 -140
  6. package/dist/device/blindtilt.js.map +1 -1
  7. package/dist/device/bot.d.ts +1 -5
  8. package/dist/device/bot.d.ts.map +1 -1
  9. package/dist/device/bot.js +79 -138
  10. package/dist/device/bot.js.map +1 -1
  11. package/dist/device/ceilinglight.d.ts +2 -6
  12. package/dist/device/ceilinglight.d.ts.map +1 -1
  13. package/dist/device/ceilinglight.js +157 -304
  14. package/dist/device/ceilinglight.js.map +1 -1
  15. package/dist/device/colorbulb.d.ts +2 -6
  16. package/dist/device/colorbulb.d.ts.map +1 -1
  17. package/dist/device/colorbulb.js +164 -311
  18. package/dist/device/colorbulb.js.map +1 -1
  19. package/dist/device/contact.d.ts +1 -5
  20. package/dist/device/contact.d.ts.map +1 -1
  21. package/dist/device/contact.js +36 -72
  22. package/dist/device/contact.js.map +1 -1
  23. package/dist/device/curtain.d.ts +1 -5
  24. package/dist/device/curtain.d.ts.map +1 -1
  25. package/dist/device/curtain.js +78 -138
  26. package/dist/device/curtain.js.map +1 -1
  27. package/dist/device/hub.d.ts +2 -6
  28. package/dist/device/hub.d.ts.map +1 -1
  29. package/dist/device/hub.js +30 -63
  30. package/dist/device/hub.js.map +1 -1
  31. package/dist/device/humidifier.d.ts +1 -5
  32. package/dist/device/humidifier.d.ts.map +1 -1
  33. package/dist/device/humidifier.js +115 -228
  34. package/dist/device/humidifier.js.map +1 -1
  35. package/dist/device/iosensor.d.ts +1 -5
  36. package/dist/device/iosensor.d.ts.map +1 -1
  37. package/dist/device/iosensor.js +38 -74
  38. package/dist/device/iosensor.js.map +1 -1
  39. package/dist/device/lock.d.ts +1 -5
  40. package/dist/device/lock.d.ts.map +1 -1
  41. package/dist/device/lock.js +66 -126
  42. package/dist/device/lock.js.map +1 -1
  43. package/dist/device/meter.d.ts +1 -5
  44. package/dist/device/meter.d.ts.map +1 -1
  45. package/dist/device/meter.js +38 -74
  46. package/dist/device/meter.js.map +1 -1
  47. package/dist/device/meterplus.d.ts +1 -5
  48. package/dist/device/meterplus.d.ts.map +1 -1
  49. package/dist/device/meterplus.js +39 -75
  50. package/dist/device/meterplus.js.map +1 -1
  51. package/dist/device/motion.d.ts +1 -5
  52. package/dist/device/motion.d.ts.map +1 -1
  53. package/dist/device/motion.js +35 -72
  54. package/dist/device/motion.js.map +1 -1
  55. package/dist/device/plug.d.ts +1 -5
  56. package/dist/device/plug.d.ts.map +1 -1
  57. package/dist/device/plug.js +65 -126
  58. package/dist/device/plug.js.map +1 -1
  59. package/dist/device/robotvacuumcleaner.d.ts +1 -5
  60. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  61. package/dist/device/robotvacuumcleaner.js +79 -151
  62. package/dist/device/robotvacuumcleaner.js.map +1 -1
  63. package/dist/device/striplight.d.ts +1 -9
  64. package/dist/device/striplight.d.ts.map +1 -1
  65. package/dist/device/striplight.js +137 -193
  66. package/dist/device/striplight.js.map +1 -1
  67. package/dist/irdevice/airconditioner.d.ts +3 -7
  68. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  69. package/dist/irdevice/airconditioner.js +34 -62
  70. package/dist/irdevice/airconditioner.js.map +1 -1
  71. package/dist/irdevice/airpurifier.d.ts +3 -7
  72. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  73. package/dist/irdevice/airpurifier.js +31 -59
  74. package/dist/irdevice/airpurifier.js.map +1 -1
  75. package/dist/irdevice/camera.d.ts +1 -5
  76. package/dist/irdevice/camera.d.ts.map +1 -1
  77. package/dist/irdevice/camera.js +30 -57
  78. package/dist/irdevice/camera.js.map +1 -1
  79. package/dist/irdevice/fan.d.ts +2 -6
  80. package/dist/irdevice/fan.d.ts.map +1 -1
  81. package/dist/irdevice/fan.js +39 -66
  82. package/dist/irdevice/fan.js.map +1 -1
  83. package/dist/irdevice/light.d.ts +1 -5
  84. package/dist/irdevice/light.d.ts.map +1 -1
  85. package/dist/irdevice/light.js +32 -59
  86. package/dist/irdevice/light.js.map +1 -1
  87. package/dist/irdevice/other.d.ts +1 -5
  88. package/dist/irdevice/other.d.ts.map +1 -1
  89. package/dist/irdevice/other.js +30 -57
  90. package/dist/irdevice/other.js.map +1 -1
  91. package/dist/irdevice/tv.d.ts +3 -7
  92. package/dist/irdevice/tv.d.ts.map +1 -1
  93. package/dist/irdevice/tv.js +46 -76
  94. package/dist/irdevice/tv.js.map +1 -1
  95. package/dist/irdevice/vacuumcleaner.d.ts +2 -6
  96. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  97. package/dist/irdevice/vacuumcleaner.js +30 -58
  98. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  99. package/dist/irdevice/waterheater.d.ts +7 -23
  100. package/dist/irdevice/waterheater.d.ts.map +1 -1
  101. package/dist/irdevice/waterheater.js +41 -74
  102. package/dist/irdevice/waterheater.js.map +1 -1
  103. package/dist/platform.d.ts +14 -5
  104. package/dist/platform.d.ts.map +1 -1
  105. package/dist/platform.js +153 -146
  106. package/dist/platform.js.map +1 -1
  107. package/dist/settings.d.ts +4 -0
  108. package/dist/settings.d.ts.map +1 -1
  109. package/dist/settings.js +5 -1
  110. package/dist/settings.js.map +1 -1
  111. package/nodemon.json +1 -1
  112. package/package.json +10 -10
  113. package/src/device/blindtilt.ts +122 -181
  114. package/src/device/bot.ts +96 -149
  115. package/src/device/ceilinglight.ts +172 -315
  116. package/src/device/colorbulb.ts +178 -324
  117. package/src/device/contact.ts +48 -78
  118. package/src/device/curtain.ts +93 -148
  119. package/src/device/hub.ts +34 -63
  120. package/src/device/humidifier.ts +135 -243
  121. package/src/device/iosensor.ts +49 -79
  122. package/src/device/lock.ts +78 -134
  123. package/src/device/meter.ts +48 -78
  124. package/src/device/meterplus.ts +50 -80
  125. package/src/device/motion.ts +46 -77
  126. package/src/device/plug.ts +76 -134
  127. package/src/device/robotvacuumcleaner.ts +91 -159
  128. package/src/device/striplight.ts +148 -200
  129. package/src/irdevice/airconditioner.ts +56 -81
  130. package/src/irdevice/airpurifier.ts +41 -67
  131. package/src/irdevice/camera.ts +35 -60
  132. package/src/irdevice/fan.ts +46 -71
  133. package/src/irdevice/light.ts +38 -63
  134. package/src/irdevice/other.ts +35 -60
  135. package/src/irdevice/tv.ts +52 -80
  136. package/src/irdevice/vacuumcleaner.ts +36 -62
  137. package/src/irdevice/waterheater.ts +46 -76
  138. package/src/platform.ts +143 -157
  139. package/src/settings.ts +5 -0
@@ -1,9 +1,6 @@
1
- import https from 'https';
2
- import crypto from 'crypto';
3
- import { IncomingMessage } from 'http';
4
- import superStringify from 'super-stringify';
1
+ import { request } from 'undici';
5
2
  import { SwitchBotPlatform } from '../platform';
6
- import { irDevicesConfig, irdevice, HostDomain, DevicePath } from '../settings';
3
+ import { irDevicesConfig, irdevice, Devices } from '../settings';
7
4
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
8
5
 
9
6
  /**
@@ -91,12 +88,12 @@ export class Others {
91
88
  */
92
89
  async pushOnChanges(): Promise<void> {
93
90
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushOnChanges Active: ${this.Active},`
94
- + ` disablePushOn: ${this.disablePushOn}, customize: ${this.device.customize}, customOn: ${this.device.customOn}`);
91
+ + ` disablePushOn: ${this.disablePushOn}, customize: ${this.device.customize}, customOn: ${this.device.customOn}`);
95
92
  if (this.device.customize) {
96
93
  if (this.Active === this.platform.Characteristic.Active.ACTIVE && !this.disablePushOn) {
97
94
  const commandType: string = await this.commandType();
98
95
  const command: string = await this.commandOn();
99
- const body = superStringify({
96
+ const body = JSON.stringify({
100
97
  'command': command,
101
98
  'parameter': 'default',
102
99
  'commandType': commandType,
@@ -110,12 +107,12 @@ export class Others {
110
107
 
111
108
  async pushOffChanges(): Promise<void> {
112
109
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushOffChanges Active: ${this.Active},`
113
- + ` disablePushOff: ${this.disablePushOff}, customize: ${this.device.customize}, customOff: ${this.device.customOff}`);
110
+ + ` disablePushOff: ${this.disablePushOff}, customize: ${this.device.customize}, customOff: ${this.device.customOff}`);
114
111
  if (this.device.customize) {
115
112
  if (this.Active === this.platform.Characteristic.Active.INACTIVE && !this.disablePushOff) {
116
113
  const commandType: string = await this.commandType();
117
114
  const command: string = await this.commandOff();
118
- const body = superStringify({
115
+ const body = JSON.stringify({
119
116
  'command': command,
120
117
  'parameter': 'default',
121
118
  'commandType': commandType,
@@ -128,55 +125,28 @@ export class Others {
128
125
  }
129
126
 
130
127
  async pushChanges(body: any): Promise<void> {
128
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushChanges`);
131
129
  if (this.device.connectionType === 'OpenAPI') {
130
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
132
131
  try {
133
- // Make Push On request to the API
134
- const t = Date.now();
135
- const nonce = 'requestID';
136
- const data = this.platform.config.credentials?.token + t + nonce;
137
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
138
- .update(Buffer.from(data, 'utf-8'))
139
- .digest();
140
- const sign = signTerm.toString('base64');
141
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
142
- this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
143
- const options = {
144
- hostname: HostDomain,
145
- port: 443,
146
- path: `${DevicePath}/${this.device.deviceId}/commands`,
132
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
147
133
  method: 'POST',
148
- headers: {
149
- 'Authorization': this.platform.config.credentials?.token,
150
- 'sign': sign,
151
- 'nonce': nonce,
152
- 't': t,
153
- 'Content-Type': 'application/json',
154
- 'Content-Length': body.length,
155
- },
156
- };
157
- const req = https.request(options, res => {
158
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges statusCode: ${res.statusCode}`);
159
- this.statusCode({ res });
160
- res.on('data', d => {
161
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
162
- });
134
+ headers: this.platform.generateHeaders(),
163
135
  });
164
- req.on('error', (e: any) => {
165
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`);
166
- });
167
- req.write(body);
168
- req.end();
169
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
136
+ const deviceStatus = await body.json();
137
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
138
+ this.statusCode(statusCode);
139
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
170
140
  this.updateHomeKitCharacteristics();
171
141
  } catch (e: any) {
172
142
  this.apiError(e);
173
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
174
- + ` Error Message: ${superStringify(e.message)}`,
143
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
144
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`,
175
145
  );
176
146
  }
177
147
  } else {
178
148
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
179
- + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
149
+ + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
180
150
  }
181
151
  }
182
152
 
@@ -236,34 +206,39 @@ export class Others {
236
206
  return command;
237
207
  }
238
208
 
239
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
240
- switch (res.statusCode) {
209
+ async statusCode(statusCode: number): Promise<void> {
210
+ switch (statusCode) {
241
211
  case 151:
242
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
212
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
243
213
  break;
244
214
  case 152:
245
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
215
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
246
216
  break;
247
217
  case 160:
248
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
218
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
249
219
  break;
250
220
  case 161:
251
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
221
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
252
222
  break;
253
223
  case 171:
254
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
224
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
225
+ + `Hub: ${this.device.hubDeviceId}`);
255
226
  break;
256
227
  case 190:
257
228
  this.errorLog(
258
- `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
259
- ` with server, Or command: ${superStringify(res)} format is invalid`,
229
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
230
+ ` Or command format is invalid, statusCode: ${statusCode}`,
260
231
  );
261
232
  break;
262
233
  case 100:
263
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
234
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
235
+ break;
236
+ case 200:
237
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
264
238
  break;
265
239
  default:
266
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
240
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode: `
241
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
267
242
  }
268
243
  }
269
244
 
@@ -286,7 +261,7 @@ export class Others {
286
261
  FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string {
287
262
  let FirmwareRevision: string;
288
263
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
289
- + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
264
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
290
265
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
291
266
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
292
267
  if (accessory.context.FirmwareRevision) {
@@ -337,7 +312,7 @@ export class Others {
337
312
  config['disablePushOff'] = device.disablePushOff;
338
313
  }
339
314
  if (Object.entries(config).length !== 0) {
340
- this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
315
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
341
316
  }
342
317
  }
343
318
 
@@ -1,10 +1,7 @@
1
- import https from 'https';
2
- import crypto from 'crypto';
3
- import { IncomingMessage } from 'http';
4
- import superStringify from 'super-stringify';
1
+ import { request } from 'undici';
5
2
  import { SwitchBotPlatform } from '../platform';
6
3
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
7
- import { irdevice, irDevicesConfig, HostDomain, DevicePath, body } from '../settings';
4
+ import { irdevice, irDevicesConfig, Devices } from '../settings';
8
5
 
9
6
  /**
10
7
  * Platform Accessory
@@ -226,11 +223,11 @@ export class TV {
226
223
  */
227
224
  async pushTvOnChanges(): Promise<void> {
228
225
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushTvOnChanges Active: ${this.Active},`
229
- + ` disablePushOn: ${this.disablePushOn}`);
226
+ + ` disablePushOn: ${this.disablePushOn}`);
230
227
  if (this.Active === this.platform.Characteristic.Active.ACTIVE && !this.disablePushOn) {
231
228
  const commandType: string = await this.commandType();
232
229
  const command: string = await this.commandOn();
233
- const body = superStringify({
230
+ const body = JSON.stringify({
234
231
  'command': command,
235
232
  'parameter': 'default',
236
233
  'commandType': commandType,
@@ -241,11 +238,11 @@ export class TV {
241
238
 
242
239
  async pushTvOffChanges(): Promise<void> {
243
240
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushTvOffChanges Active: ${this.Active},`
244
- + ` disablePushOff: ${this.disablePushOff}`);
241
+ + ` disablePushOff: ${this.disablePushOff}`);
245
242
  if (this.Active === this.platform.Characteristic.Active.INACTIVE && !this.disablePushOff) {
246
243
  const commandType: string = await this.commandType();
247
244
  const command: string = await this.commandOff();
248
- const body = superStringify({
245
+ const body = JSON.stringify({
249
246
  'command': command,
250
247
  'parameter': 'default',
251
248
  'commandType': commandType,
@@ -257,7 +254,7 @@ export class TV {
257
254
  async pushOkChanges(): Promise<void> {
258
255
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushOkChanges disablePushDetail: ${this.disablePushDetail}`);
259
256
  if (!this.disablePushDetail) {
260
- const body = superStringify({
257
+ const body = JSON.stringify({
261
258
  'command': 'Ok',
262
259
  'parameter': 'default',
263
260
  'commandType': 'command',
@@ -269,7 +266,7 @@ export class TV {
269
266
  async pushBackChanges(): Promise<void> {
270
267
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushBackChanges disablePushDetail: ${this.disablePushDetail}`);
271
268
  if (!this.disablePushDetail) {
272
- const body = superStringify({
269
+ const body = JSON.stringify({
273
270
  'command': 'Back',
274
271
  'parameter': 'default',
275
272
  'commandType': 'command',
@@ -281,7 +278,7 @@ export class TV {
281
278
  async pushMenuChanges(): Promise<void> {
282
279
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushMenuChanges disablePushDetail: ${this.disablePushDetail}`);
283
280
  if (!this.disablePushDetail) {
284
- const body = superStringify({
281
+ const body = JSON.stringify({
285
282
  'command': 'Menu',
286
283
  'parameter': 'default',
287
284
  'commandType': 'command',
@@ -293,7 +290,7 @@ export class TV {
293
290
  async pushUpChanges(): Promise<void> {
294
291
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushUpChanges disablePushDetail: ${this.disablePushDetail}`);
295
292
  if (!this.disablePushDetail) {
296
- const body = superStringify({
293
+ const body = JSON.stringify({
297
294
  'command': 'Up',
298
295
  'parameter': 'default',
299
296
  'commandType': 'command',
@@ -305,7 +302,7 @@ export class TV {
305
302
  async pushDownChanges(): Promise<void> {
306
303
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushDownChanges disablePushDetail: ${this.disablePushDetail}`);
307
304
  if (!this.disablePushDetail) {
308
- const body = superStringify({
305
+ const body = JSON.stringify({
309
306
  'command': 'Down',
310
307
  'parameter': 'default',
311
308
  'commandType': 'command',
@@ -317,7 +314,7 @@ export class TV {
317
314
  async pushRightChanges(): Promise<void> {
318
315
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushRightChanges disablePushDetail: ${this.disablePushDetail}`);
319
316
  if (!this.disablePushDetail) {
320
- const body = superStringify({
317
+ const body = JSON.stringify({
321
318
  'command': 'Right',
322
319
  'parameter': 'default',
323
320
  'commandType': 'command',
@@ -329,7 +326,7 @@ export class TV {
329
326
  async pushLeftChanges(): Promise<void> {
330
327
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushLeftChanges disablePushDetail: ${this.disablePushDetail}`);
331
328
  if (!this.disablePushDetail) {
332
- const body = superStringify({
329
+ const body = JSON.stringify({
333
330
  'command': 'Left',
334
331
  'parameter': 'default',
335
332
  'commandType': 'command',
@@ -341,7 +338,7 @@ export class TV {
341
338
  async pushVolumeUpChanges(): Promise<void> {
342
339
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushVolumeUpChanges disablePushDetail: ${this.disablePushDetail}`);
343
340
  if (!this.disablePushDetail) {
344
- const body = superStringify({
341
+ const body = JSON.stringify({
345
342
  'command': 'volumeAdd',
346
343
  'parameter': 'default',
347
344
  'commandType': 'command',
@@ -353,7 +350,7 @@ export class TV {
353
350
  async pushVolumeDownChanges(): Promise<void> {
354
351
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushVolumeDownChanges disablePushDetail: ${this.disablePushDetail}`);
355
352
  if (!this.disablePushDetail) {
356
- const body = superStringify({
353
+ const body = JSON.stringify({
357
354
  'command': 'volumeSub',
358
355
  'parameter': 'default',
359
356
  'commandType': 'command',
@@ -362,58 +359,29 @@ export class TV {
362
359
  }
363
360
  }
364
361
 
365
- async pushTVChanges(body: Array<body>): Promise<void> {
362
+ async pushTVChanges(body: any): Promise<void> {
363
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushTVChanges`);
366
364
  if (this.device.connectionType === 'OpenAPI') {
367
- {
368
- try {
369
- // Make Push On request to the API
370
- const t = Date.now();
371
- const nonce = 'requestID';
372
- const data = this.platform.config.credentials?.token + t + nonce;
373
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
374
- .update(Buffer.from(data, 'utf-8'))
375
- .digest();
376
- const sign = signTerm.toString('base64');
377
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
378
- this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
379
- const options = {
380
- hostname: HostDomain,
381
- port: 443,
382
- path: `${DevicePath}/${this.device.deviceId}/commands`,
383
- method: 'POST',
384
- headers: {
385
- 'Authorization': this.platform.config.credentials?.token,
386
- 'sign': sign,
387
- 'nonce': nonce,
388
- 't': t,
389
- 'Content-Type': 'application/json',
390
- 'Content-Length': body.length,
391
- },
392
- };
393
- const req = https.request(options, res => {
394
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges statusCode: ${res.statusCode}`);
395
- this.statusCode({ res });
396
- res.on('data', d => {
397
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
398
- });
399
- });
400
- req.on('error', (e: any) => {
401
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`);
402
- });
403
- req.write(body);
404
- req.end();
405
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
406
- this.updateHomeKitCharacteristics();
407
- } catch (e: any) {
408
- this.apiError(e);
409
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
410
- + ` Error Message: ${superStringify(e.message)}`,
411
- );
412
- }
365
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
366
+ try {
367
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
368
+ method: 'POST',
369
+ headers: this.platform.generateHeaders(),
370
+ });
371
+ const deviceStatus = await body.json();
372
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
373
+ this.statusCode(statusCode);
374
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
375
+ this.updateHomeKitCharacteristics();
376
+ } catch (e: any) {
377
+ this.apiError(e);
378
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushTVChanges with ${this.device.connectionType}`
379
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`,
380
+ );
413
381
  }
414
382
  } else {
415
383
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
416
- + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
384
+ + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
417
385
  }
418
386
  }
419
387
 
@@ -488,35 +456,39 @@ export class TV {
488
456
  return command;
489
457
  }
490
458
 
491
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
492
- switch (res.statusCode) {
459
+ async statusCode(statusCode: number): Promise<void> {
460
+ switch (statusCode) {
493
461
  case 151:
494
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
462
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
495
463
  break;
496
464
  case 152:
497
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
465
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
498
466
  break;
499
467
  case 160:
500
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
468
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
501
469
  break;
502
470
  case 161:
503
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
471
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
504
472
  break;
505
473
  case 171:
506
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
474
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
475
+ + `Hub: ${this.device.hubDeviceId}`);
507
476
  break;
508
477
  case 190:
509
478
  this.errorLog(
510
- `${this.device.remoteType}: ` +
511
- `${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
512
- ` Or command: ${superStringify(res)} format is invalid`,
479
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
480
+ ` Or command format is invalid, statusCode: ${statusCode}`,
513
481
  );
514
482
  break;
515
483
  case 100:
516
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
484
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
485
+ break;
486
+ case 200:
487
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
517
488
  break;
518
489
  default:
519
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
490
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode: `
491
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
520
492
  }
521
493
  }
522
494
 
@@ -528,7 +500,7 @@ export class TV {
528
500
  FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string {
529
501
  let FirmwareRevision: string;
530
502
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
531
- + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
503
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
532
504
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
533
505
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
534
506
  if (accessory.context.FirmwareRevision) {
@@ -587,7 +559,7 @@ export class TV {
587
559
  config['disablePushDetail'] = device.disablePushDetail;
588
560
  }
589
561
  if (Object.entries(config).length !== 0) {
590
- this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
562
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
591
563
  }
592
564
  }
593
565
 
@@ -1,9 +1,6 @@
1
- import https from 'https';
2
- import crypto from 'crypto';
3
- import { IncomingMessage } from 'http';
4
- import superStringify from 'super-stringify';
1
+ import { request } from 'undici';
5
2
  import { SwitchBotPlatform } from '../platform';
6
- import { irDevicesConfig, irdevice, HostDomain, DevicePath } from '../settings';
3
+ import { irDevicesConfig, irdevice, Devices } from '../settings';
7
4
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
8
5
 
9
6
  /**
@@ -80,11 +77,11 @@ export class VacuumCleaner {
80
77
  */
81
78
  async pushOnChanges(): Promise<void> {
82
79
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushOnChanges On: ${this.On},`
83
- + ` disablePushOn: ${this.disablePushOn}`);
80
+ + ` disablePushOn: ${this.disablePushOn}`);
84
81
  if (this.On && !this.disablePushOn) {
85
82
  const commandType: string = await this.commandType();
86
83
  const command: string = await this.commandOn();
87
- const body = superStringify({
84
+ const body = JSON.stringify({
88
85
  'command': command,
89
86
  'parameter': 'default',
90
87
  'commandType': commandType,
@@ -95,11 +92,11 @@ export class VacuumCleaner {
95
92
 
96
93
  async pushOffChanges(): Promise<void> {
97
94
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushOffChanges On: ${this.On},`
98
- + ` disablePushOff: ${this.disablePushOff}`);
95
+ + ` disablePushOff: ${this.disablePushOff}`);
99
96
  if (!this.On && !this.disablePushOff) {
100
97
  const commandType: string = await this.commandType();
101
98
  const command: string = await this.commandOff();
102
- const body = superStringify({
99
+ const body = JSON.stringify({
103
100
  'command': command,
104
101
  'parameter': 'default',
105
102
  'commandType': commandType,
@@ -108,57 +105,29 @@ export class VacuumCleaner {
108
105
  }
109
106
  }
110
107
 
111
- async pushChanges(body: any[]): Promise<void> {
108
+ async pushChanges(body: any): Promise<void> {
109
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushChanges`);
112
110
  if (this.device.connectionType === 'OpenAPI') {
111
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
113
112
  try {
114
- // Make Push On request to the API
115
- const t = Date.now();
116
- const nonce = 'requestID';
117
- const data = this.platform.config.credentials?.token + t + nonce;
118
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
119
- .update(Buffer.from(data, 'utf-8'))
120
- .digest();
121
- const sign = signTerm.toString('base64');
122
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
123
- this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
124
- const options = {
125
- hostname: HostDomain,
126
- port: 443,
127
- path: `${DevicePath}/${this.device.deviceId}/commands`,
113
+ const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
128
114
  method: 'POST',
129
- headers: {
130
- 'Authorization': this.platform.config.credentials?.token,
131
- 'sign': sign,
132
- 'nonce': nonce,
133
- 't': t,
134
- 'Content-Type': 'application/json',
135
- 'Content-Length': body.length,
136
- },
137
- };
138
- const req = https.request(options, res => {
139
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges statusCode: ${res.statusCode}`);
140
- this.statusCode({ res });
141
- res.on('data', d => {
142
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
143
- });
115
+ headers: this.platform.generateHeaders(),
144
116
  });
145
- req.on('error', (e: any) => {
146
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`);
147
- });
148
- req.write(body);
149
- req.end();
150
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
151
- this.accessory.context.On = this.On;
117
+ const deviceStatus = await body.json();
118
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
119
+ this.statusCode(statusCode);
120
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
152
121
  this.updateHomeKitCharacteristics();
153
122
  } catch (e: any) {
154
123
  this.apiError(e);
155
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
156
- + ` Error Message: ${superStringify(e.message)}`,
124
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
125
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`,
157
126
  );
158
127
  }
159
128
  } else {
160
129
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
161
- + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
130
+ + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
162
131
  }
163
132
  }
164
133
 
@@ -218,34 +187,39 @@ export class VacuumCleaner {
218
187
  return command;
219
188
  }
220
189
 
221
- async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
222
- switch (res.statusCode) {
190
+ async statusCode(statusCode: number): Promise<void> {
191
+ switch (statusCode) {
223
192
  case 151:
224
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
193
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
225
194
  break;
226
195
  case 152:
227
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
196
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
228
197
  break;
229
198
  case 160:
230
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
199
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
231
200
  break;
232
201
  case 161:
233
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
202
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
234
203
  break;
235
204
  case 171:
236
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
205
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
206
+ + `Hub: ${this.device.hubDeviceId}`);
237
207
  break;
238
208
  case 190:
239
209
  this.errorLog(
240
- `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
241
- ` with server, Or command: ${superStringify(res)} format is invalid`,
210
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
211
+ ` Or command format is invalid, statusCode: ${statusCode}`,
242
212
  );
243
213
  break;
244
214
  case 100:
245
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
215
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
216
+ break;
217
+ case 200:
218
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
246
219
  break;
247
220
  default:
248
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
221
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode: `
222
+ + `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
249
223
  }
250
224
  }
251
225
 
@@ -256,7 +230,7 @@ export class VacuumCleaner {
256
230
  FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string {
257
231
  let FirmwareRevision: string;
258
232
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
259
- + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
233
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
260
234
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
261
235
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
262
236
  if (accessory.context.FirmwareRevision) {
@@ -307,7 +281,7 @@ export class VacuumCleaner {
307
281
  config['disablePushOff'] = device.disablePushOff;
308
282
  }
309
283
  if (Object.entries(config).length !== 0) {
310
- this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
284
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
311
285
  }
312
286
  }
313
287