@switchbot/homebridge-switchbot 2.0.0-beta.17 → 2.0.0-beta.19

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 (106) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/config.schema.json +14 -4
  3. package/dist/device/bot.d.ts +2 -0
  4. package/dist/device/bot.d.ts.map +1 -1
  5. package/dist/device/bot.js +201 -163
  6. package/dist/device/bot.js.map +1 -1
  7. package/dist/device/colorbulb.d.ts +2 -0
  8. package/dist/device/colorbulb.d.ts.map +1 -1
  9. package/dist/device/colorbulb.js +250 -218
  10. package/dist/device/colorbulb.js.map +1 -1
  11. package/dist/device/contact.d.ts +2 -0
  12. package/dist/device/contact.d.ts.map +1 -1
  13. package/dist/device/contact.js +85 -66
  14. package/dist/device/contact.js.map +1 -1
  15. package/dist/device/curtain.d.ts +2 -0
  16. package/dist/device/curtain.d.ts.map +1 -1
  17. package/dist/device/curtain.js +166 -136
  18. package/dist/device/curtain.js.map +1 -1
  19. package/dist/device/humidifier.d.ts.map +1 -1
  20. package/dist/device/humidifier.js +126 -115
  21. package/dist/device/humidifier.js.map +1 -1
  22. package/dist/device/lock.d.ts +2 -0
  23. package/dist/device/lock.d.ts.map +1 -1
  24. package/dist/device/lock.js +156 -130
  25. package/dist/device/lock.js.map +1 -1
  26. package/dist/device/meter.d.ts +2 -0
  27. package/dist/device/meter.d.ts.map +1 -1
  28. package/dist/device/meter.js +85 -64
  29. package/dist/device/meter.js.map +1 -1
  30. package/dist/device/meterplus.d.ts +2 -0
  31. package/dist/device/meterplus.d.ts.map +1 -1
  32. package/dist/device/meterplus.js +78 -59
  33. package/dist/device/meterplus.js.map +1 -1
  34. package/dist/device/motion.d.ts +2 -0
  35. package/dist/device/motion.d.ts.map +1 -1
  36. package/dist/device/motion.js +76 -57
  37. package/dist/device/motion.js.map +1 -1
  38. package/dist/device/plug.d.ts +2 -0
  39. package/dist/device/plug.d.ts.map +1 -1
  40. package/dist/device/plug.js +133 -107
  41. package/dist/device/plug.js.map +1 -1
  42. package/dist/device/striplight.d.ts +2 -0
  43. package/dist/device/striplight.d.ts.map +1 -1
  44. package/dist/device/striplight.js +224 -195
  45. package/dist/device/striplight.js.map +1 -1
  46. package/dist/irdevice/airconditioner.d.ts +2 -0
  47. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  48. package/dist/irdevice/airconditioner.js +127 -105
  49. package/dist/irdevice/airconditioner.js.map +1 -1
  50. package/dist/irdevice/airpurifier.d.ts +2 -0
  51. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  52. package/dist/irdevice/airpurifier.js +83 -66
  53. package/dist/irdevice/airpurifier.js.map +1 -1
  54. package/dist/irdevice/camera.d.ts +8 -6
  55. package/dist/irdevice/camera.d.ts.map +1 -1
  56. package/dist/irdevice/camera.js +83 -68
  57. package/dist/irdevice/camera.js.map +1 -1
  58. package/dist/irdevice/fan.d.ts +7 -5
  59. package/dist/irdevice/fan.d.ts.map +1 -1
  60. package/dist/irdevice/fan.js +90 -75
  61. package/dist/irdevice/fan.js.map +1 -1
  62. package/dist/irdevice/light.d.ts +8 -6
  63. package/dist/irdevice/light.d.ts.map +1 -1
  64. package/dist/irdevice/light.js +83 -68
  65. package/dist/irdevice/light.js.map +1 -1
  66. package/dist/irdevice/other.d.ts +8 -6
  67. package/dist/irdevice/other.d.ts.map +1 -1
  68. package/dist/irdevice/other.js +93 -78
  69. package/dist/irdevice/other.js.map +1 -1
  70. package/dist/irdevice/tv.d.ts +8 -6
  71. package/dist/irdevice/tv.d.ts.map +1 -1
  72. package/dist/irdevice/tv.js +68 -52
  73. package/dist/irdevice/tv.js.map +1 -1
  74. package/dist/irdevice/vacuumcleaner.d.ts +8 -6
  75. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.js +83 -69
  77. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  78. package/dist/irdevice/waterheater.d.ts +2 -0
  79. package/dist/irdevice/waterheater.d.ts.map +1 -1
  80. package/dist/irdevice/waterheater.js +75 -60
  81. package/dist/irdevice/waterheater.js.map +1 -1
  82. package/dist/settings.d.ts +12 -11
  83. package/dist/settings.d.ts.map +1 -1
  84. package/dist/settings.js.map +1 -1
  85. package/package.json +1 -1
  86. package/src/device/bot.ts +200 -163
  87. package/src/device/colorbulb.ts +252 -221
  88. package/src/device/contact.ts +85 -66
  89. package/src/device/curtain.ts +165 -136
  90. package/src/device/humidifier.ts +126 -115
  91. package/src/device/lock.ts +156 -131
  92. package/src/device/meter.ts +85 -64
  93. package/src/device/meterplus.ts +78 -59
  94. package/src/device/motion.ts +76 -57
  95. package/src/device/plug.ts +132 -107
  96. package/src/device/striplight.ts +226 -198
  97. package/src/irdevice/airconditioner.ts +126 -103
  98. package/src/irdevice/airpurifier.ts +84 -66
  99. package/src/irdevice/camera.ts +84 -68
  100. package/src/irdevice/fan.ts +91 -75
  101. package/src/irdevice/light.ts +84 -68
  102. package/src/irdevice/other.ts +94 -78
  103. package/src/irdevice/tv.ts +69 -53
  104. package/src/irdevice/vacuumcleaner.ts +83 -68
  105. package/src/irdevice/waterheater.ts +76 -60
  106. package/src/settings.ts +12 -11
@@ -40,6 +40,7 @@ export class AirPurifier {
40
40
 
41
41
  // Config
42
42
  deviceLogging!: string;
43
+ OpenAPI?: boolean;
43
44
 
44
45
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) {
45
46
  // default placeholders
@@ -87,7 +88,7 @@ export class AirPurifier {
87
88
  }
88
89
 
89
90
  async ActiveSet(value: CharacteristicValue): Promise<void> {
90
- this.debugLog(`Air Purifier: ${this.accessory.displayName} Set Active: ${value}`);
91
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Set Active: ${value}`);
91
92
  if (value === this.platform.Characteristic.Active.INACTIVE) {
92
93
  this.pushAirPurifierOffChanges();
93
94
  } else {
@@ -100,23 +101,25 @@ export class AirPurifier {
100
101
 
101
102
  async updateHomeKitCharacteristics(): Promise<void> {
102
103
  if (this.Active === undefined) {
103
- this.debugLog(`Air Purifier: ${this.accessory.displayName} Active: ${this.Active}`);
104
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Active: ${this.Active}`);
104
105
  } else {
105
106
  this.airPurifierService?.updateCharacteristic(this.platform.Characteristic.Active, this.Active);
106
- this.debugLog(`Air Purifier: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
107
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
107
108
  }
108
109
  if (this.CurrentAirPurifierState === undefined) {
109
- this.debugLog(`Air Purifier: ${this.accessory.displayName} CurrentAirPurifierState: ${this.CurrentAirPurifierState}`);
110
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} CurrentAirPurifierState: ${this.CurrentAirPurifierState}`);
110
111
  } else {
111
112
  this.airPurifierService?.updateCharacteristic(this.platform.Characteristic.CurrentAirPurifierState, this.CurrentAirPurifierState);
112
- this.debugLog(`Air Purifier: ${this.accessory.displayName}` + ` updateCharacteristic CurrentAirPurifierState: ${this.CurrentAirPurifierState}`);
113
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
114
+ + ` updateCharacteristic CurrentAirPurifierState: ${this.CurrentAirPurifierState}`);
113
115
  }
114
116
  if (this.CurrentHeaterCoolerState === undefined) {
115
- this.debugLog(`Air Purifier: ${this.accessory.displayName} CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
117
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
116
118
  } else {
117
119
  this.airPurifierService?.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.CurrentHeaterCoolerState);
118
120
  this.debugLog(
119
- `Air Purifier: ${this.accessory.displayName}` + ` updateCharacteristic CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`,
121
+ `${this.device.remoteType}: ${this.accessory.displayName}`
122
+ + ` updateCharacteristic CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`,
120
123
  );
121
124
  }
122
125
  }
@@ -214,86 +217,89 @@ export class AirPurifier {
214
217
  }
215
218
 
216
219
  async pushChanges(body): Promise<void> {
217
- try {
220
+ if (this.OpenAPI) {
221
+ try {
218
222
  // Make Push On request to the API
219
- const t = Date.now();
220
- const nonce = 'requestID';
221
- const data = this.platform.config.credentials?.token + t + nonce;
222
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
223
- .update(Buffer.from(data, 'utf-8'))
224
- .digest();
225
- const sign = signTerm.toString('base64');
226
- this.debugLog(`Air Purifier: ${this.accessory.displayName} sign: ${sign}`);
227
- this.infoLog(`Air Purifier: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
228
- const options = {
229
- hostname: HostDomain,
230
- port: 443,
231
- path: `${DevicePath}/${this.device.deviceId}/commands`,
232
- method: 'POST',
233
- headers: {
234
- 'Authorization': this.platform.config.credentials?.token,
235
- 'sign': sign,
236
- 'nonce': nonce,
237
- 't': t,
238
- 'Content-Type': 'application/json',
239
- 'Content-Length': body.length,
240
- },
241
- };
242
- const req = https.request(options, res => {
243
- this.debugLog(`Air Purifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
244
- this.statusCode({ res });
245
- res.on('data', d => {
246
- this.debugLog(`Air Purifier: ${this.accessory.displayName} d: ${d}`);
223
+ const t = Date.now();
224
+ const nonce = 'requestID';
225
+ const data = this.platform.config.credentials?.token + t + nonce;
226
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
227
+ .update(Buffer.from(data, 'utf-8'))
228
+ .digest();
229
+ const sign = signTerm.toString('base64');
230
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
231
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
232
+ const options = {
233
+ hostname: HostDomain,
234
+ port: 443,
235
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
236
+ method: 'POST',
237
+ headers: {
238
+ 'Authorization': this.platform.config.credentials?.token,
239
+ 'sign': sign,
240
+ 'nonce': nonce,
241
+ 't': t,
242
+ 'Content-Type': 'application/json',
243
+ 'Content-Length': body.length,
244
+ },
245
+ };
246
+ const req = https.request(options, res => {
247
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
248
+ this.statusCode({ res });
249
+ res.on('data', d => {
250
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
251
+ });
247
252
  });
248
- });
249
- req.on('error', (e: any) => {
250
- this.errorLog(`Air Purifier: ${this.accessory.displayName} error message: ${e.message}`);
251
- });
252
- req.write(body);
253
- req.end();
254
- this.debugLog(`Air Purifier: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
255
- this.updateHomeKitCharacteristics();
256
- this.CurrentTemperatureCached = this.CurrentTemperature;
257
- this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
258
- } catch (e: any) {
259
- this.errorLog(`Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
260
- if (this.deviceLogging.includes('debug')) {
261
- this.errorLog(
262
- `Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
263
- );
253
+ req.on('error', (e: any) => {
254
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`);
255
+ });
256
+ req.write(body);
257
+ req.end();
258
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
259
+ this.updateHomeKitCharacteristics();
260
+ this.CurrentTemperatureCached = this.CurrentTemperature;
261
+ this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
262
+ } catch (e: any) {
263
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
264
+ if (this.deviceLogging.includes('debug')) {
265
+ this.errorLog(
266
+ `${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
267
+ + ` Error Message: ${superStringify(e.message)}`,
268
+ );
269
+ }
270
+ this.apiError(e);
264
271
  }
265
- this.apiError(e);
266
272
  }
267
273
  }
268
274
 
269
275
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
270
276
  switch (res.statusCode) {
271
277
  case 151:
272
- this.errorLog(`Air Purifier: ${this.accessory.displayName} Command not supported by this device type.`);
278
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
273
279
  break;
274
280
  case 152:
275
- this.errorLog(`Air Purifier: ${this.accessory.displayName} Device not found.`);
281
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
276
282
  break;
277
283
  case 160:
278
- this.errorLog(`Air Purifier: ${this.accessory.displayName} Command is not supported.`);
284
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
279
285
  break;
280
286
  case 161:
281
- this.errorLog(`Air Purifier: ${this.accessory.displayName} Device is offline.`);
287
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
282
288
  break;
283
289
  case 171:
284
- this.errorLog(`Air Purifier: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
290
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
285
291
  break;
286
292
  case 190:
287
293
  this.errorLog(
288
- `Air Purifier: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
294
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
289
295
  ` with server, Or command: ${superStringify(res)} format is invalid`,
290
296
  );
291
297
  break;
292
298
  case 100:
293
- this.debugLog(`Air Purifier: ${this.accessory.displayName} Command successfully sent.`);
299
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
294
300
  break;
295
301
  default:
296
- this.debugLog(`Air Purifier: ${this.accessory.displayName} Unknown statusCode.`);
302
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
297
303
  }
298
304
  }
299
305
 
@@ -305,6 +311,15 @@ export class AirPurifier {
305
311
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
306
312
  }
307
313
 
314
+ async openAPI() {
315
+ if (!this.device.openAPI) {
316
+ this.OpenAPI = true;
317
+ } else {
318
+ this.OpenAPI = this.device.openAPI;
319
+ }
320
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using OpenAPI: ${this.OpenAPI}`);
321
+ }
322
+
308
323
  async config(device: irdevice & irDevicesConfig): Promise<void> {
309
324
  let config = {};
310
325
  if (device.irpur) {
@@ -313,24 +328,27 @@ export class AirPurifier {
313
328
  if (device.logging !== undefined) {
314
329
  config['logging'] = device.logging;
315
330
  }
331
+ if (device.openAPI !== undefined) {
332
+ config['openAPI'] = device.openAPI;
333
+ }
316
334
  if (Object.entries(config).length !== 0) {
317
- this.infoLog(`Air Purifier: ${this.accessory.displayName} Config: ${superStringify(config)}`);
335
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
318
336
  }
319
337
  }
320
338
 
321
339
  async logs(device: irdevice & irDevicesConfig): Promise<void> {
322
340
  if (this.platform.debugMode) {
323
341
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
324
- this.debugLog(`Air Purifier: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
342
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
325
343
  } else if (device.logging) {
326
344
  this.deviceLogging = this.accessory.context.logging = device.logging;
327
- this.debugLog(`Air Purifier: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
345
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
328
346
  } else if (this.platform.config.options?.logging) {
329
347
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
330
- this.debugLog(`Air Purifier: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
348
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
331
349
  } else {
332
350
  this.deviceLogging = this.accessory.context.logging = 'standard';
333
- this.debugLog(`Air Purifier: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
351
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
334
352
  }
335
353
  }
336
354
 
@@ -21,6 +21,7 @@ export class Camera {
21
21
 
22
22
  // Config
23
23
  deviceLogging!: string;
24
+ OpenAPI?: boolean;
24
25
 
25
26
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) {
26
27
  // default placeholders
@@ -57,7 +58,7 @@ export class Camera {
57
58
  }
58
59
 
59
60
  async OnSet(value: CharacteristicValue): Promise<void> {
60
- this.debugLog(`Camera: ${this.accessory.displayName} On: ${value}`);
61
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${value}`);
61
62
  this.On = value;
62
63
  if (this.On) {
63
64
  this.pushOnChanges();
@@ -68,22 +69,22 @@ export class Camera {
68
69
 
69
70
  async updateHomeKitCharacteristics(): Promise<void> {
70
71
  if (this.On === undefined) {
71
- this.debugLog(`Camera: ${this.accessory.displayName} On: ${this.On}`);
72
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${this.On}`);
72
73
  } else {
73
74
  this.switchService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
74
- this.debugLog(`Camera: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
75
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
75
76
  }
76
77
  }
77
78
 
78
79
  /**
79
80
  * Pushes the requested changes to the SwitchBot API
80
81
  * deviceType commandType Command command parameter Description
81
- * Light: "command" "turnOff" "default" = set to OFF state
82
- * Light: "command" "turnOn" "default" = set to ON state
83
- * Light: "command" "volumeAdd" "default" = volume up
84
- * Light: "command" "volumeSub" "default" = volume down
85
- * Light: "command" "channelAdd" "default" = next channel
86
- * Light: "command" "channelSub" "default" = previous channel
82
+ * Camera - "command" "turnOff" "default" = set to OFF state
83
+ * Camera - "command" "turnOn" "default" = set to ON state
84
+ * Camera - "command" "volumeAdd" "default" = volume up
85
+ * Camera - "command" "volumeSub" "default" = volume down
86
+ * Camera - "command" "channelAdd" "default" = next channel
87
+ * Camera - "command" "channelSub" "default" = previous channel
87
88
  */
88
89
  async pushOnChanges(): Promise<void> {
89
90
  if (this.On) {
@@ -108,86 +109,89 @@ export class Camera {
108
109
  }
109
110
 
110
111
  async pushChanges(body): Promise<void> {
111
- try {
112
+ if (this.OpenAPI) {
113
+ try {
112
114
  // Make Push On request to the API
113
- const t = Date.now();
114
- const nonce = 'requestID';
115
- const data = this.platform.config.credentials?.token + t + nonce;
116
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
117
- .update(Buffer.from(data, 'utf-8'))
118
- .digest();
119
- const sign = signTerm.toString('base64');
120
- this.debugLog(`Camera: ${this.accessory.displayName} sign: ${sign}`);
121
- this.infoLog(`Camera: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
122
- const options = {
123
- hostname: HostDomain,
124
- port: 443,
125
- path: `${DevicePath}/${this.device.deviceId}/commands`,
126
- method: 'POST',
127
- headers: {
128
- 'Authorization': this.platform.config.credentials?.token,
129
- 'sign': sign,
130
- 'nonce': nonce,
131
- 't': t,
132
- 'Content-Type': 'application/json',
133
- 'Content-Length': body.length,
134
- },
135
- };
136
- const req = https.request(options, res => {
137
- this.debugLog(`Camera: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
138
- this.statusCode({ res });
139
- res.on('data', d => {
140
- this.debugLog(`Camera: ${this.accessory.displayName} d: ${d}`);
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`,
128
+ 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} statusCode: ${res.statusCode}`);
140
+ this.statusCode({ res });
141
+ res.on('data', d => {
142
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
143
+ });
141
144
  });
142
- });
143
- req.on('error', (e: any) => {
144
- this.errorLog(`Camera: ${this.accessory.displayName} error message: ${e.message}`);
145
- });
146
- req.write(body);
147
- req.end();
148
- this.debugLog(`Camera: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
149
- this.updateHomeKitCharacteristics();
150
- this.OnCached = this.On;
151
- this.accessory.context.On = this.OnCached;
152
- } catch (e: any) {
153
- this.errorLog(`Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
154
- if (this.deviceLogging.includes('debug')) {
155
- this.errorLog(
156
- `Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
157
- );
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.updateHomeKitCharacteristics();
152
+ this.OnCached = this.On;
153
+ this.accessory.context.On = this.OnCached;
154
+ } catch (e: any) {
155
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
156
+ if (this.deviceLogging.includes('debug')) {
157
+ this.errorLog(
158
+ `${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
159
+ + ` Error Message: ${superStringify(e.message)}`,
160
+ );
161
+ }
162
+ this.apiError(e);
158
163
  }
159
- this.apiError(e);
160
164
  }
161
165
  }
162
166
 
163
167
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
164
168
  switch (res.statusCode) {
165
169
  case 151:
166
- this.errorLog(`Camera: ${this.accessory.displayName} Command not supported by this device type.`);
170
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
167
171
  break;
168
172
  case 152:
169
- this.errorLog(`Camera: ${this.accessory.displayName} Device not found.`);
173
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
170
174
  break;
171
175
  case 160:
172
- this.errorLog(`Camera: ${this.accessory.displayName} Command is not supported.`);
176
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
173
177
  break;
174
178
  case 161:
175
- this.errorLog(`Camera: ${this.accessory.displayName} Device is offline.`);
179
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
176
180
  break;
177
181
  case 171:
178
- this.errorLog(`Camera: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
182
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
179
183
  break;
180
184
  case 190:
181
185
  this.errorLog(
182
- `Camera: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
186
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
183
187
  ` with server, Or command: ${superStringify(res)} format is invalid`,
184
188
  );
185
189
  break;
186
190
  case 100:
187
- this.debugLog(`Camera: ${this.accessory.displayName} Command successfully sent.`);
191
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
188
192
  break;
189
193
  default:
190
- this.debugLog(`Camera: ${this.accessory.displayName} Unknown statusCode.`);
194
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
191
195
  }
192
196
  }
193
197
 
@@ -196,6 +200,15 @@ export class Camera {
196
200
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
197
201
  }
198
202
 
203
+ async openAPI() {
204
+ if (!this.device.openAPI) {
205
+ this.OpenAPI = true;
206
+ } else {
207
+ this.OpenAPI = this.device.openAPI;
208
+ }
209
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using OpenAPI: ${this.OpenAPI}`);
210
+ }
211
+
199
212
  async config(device: irdevice & irDevicesConfig): Promise<void> {
200
213
  let config = {};
201
214
  if (device.ircam) {
@@ -204,24 +217,27 @@ export class Camera {
204
217
  if (device.logging !== undefined) {
205
218
  config['logging'] = device.logging;
206
219
  }
220
+ if (device.openAPI !== undefined) {
221
+ config['openAPI'] = device.openAPI;
222
+ }
207
223
  if (Object.entries(config).length !== 0) {
208
- this.infoLog(`Camera: ${this.accessory.displayName} Config: ${superStringify(config)}`);
224
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
209
225
  }
210
226
  }
211
227
 
212
228
  async logs(device: irdevice & irDevicesConfig): Promise<void> {
213
229
  if (this.platform.debugMode) {
214
230
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
215
- this.debugLog(`Camera: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
231
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
216
232
  } else if (device.logging) {
217
233
  this.deviceLogging = this.accessory.context.logging = device.logging;
218
- this.debugLog(`Camera: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
234
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
219
235
  } else if (this.platform.config.options?.logging) {
220
236
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
221
- this.debugLog(`Camera: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
237
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
222
238
  } else {
223
239
  this.deviceLogging = this.accessory.context.logging = 'standard';
224
- this.debugLog(`Camera: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
240
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
225
241
  }
226
242
  }
227
243