@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
@@ -31,6 +31,7 @@ export class Fan {
31
31
  minValue?: number;
32
32
  maxValue?: number;
33
33
  deviceLogging!: string;
34
+ OpenAPI?: boolean;
34
35
 
35
36
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) {
36
37
  // default placeholders
@@ -93,11 +94,11 @@ export class Fan {
93
94
  } else if (this.fanService.testCharacteristic(this.platform.Characteristic.RotationSpeed) && !device.irfan?.swing_mode) {
94
95
  const characteristic = this.fanService.getCharacteristic(this.platform.Characteristic.RotationSpeed);
95
96
  this.fanService.removeCharacteristic(characteristic);
96
- this.debugLog(`Fan: ${this.accessory.displayName} Rotation Speed Characteristic was removed.`);
97
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Rotation Speed Characteristic was removed.`);
97
98
  } else {
98
99
  // eslint-disable-next-line max-len
99
100
  this.debugLog(
100
- `Fan: ${this.accessory.displayName} RotationSpeed Characteristic was not removed/added, ` +
101
+ `${this.device.remoteType}: ${this.accessory.displayName} RotationSpeed Characteristic was not removed/added, ` +
101
102
  `Clear Cache on ${this.accessory.displayName} to remove Chracteristic`,
102
103
  );
103
104
  }
@@ -108,18 +109,18 @@ export class Fan {
108
109
  } else if (this.fanService.testCharacteristic(this.platform.Characteristic.SwingMode) && !device.irfan?.swing_mode) {
109
110
  const characteristic = this.fanService.getCharacteristic(this.platform.Characteristic.SwingMode);
110
111
  this.fanService.removeCharacteristic(characteristic);
111
- this.debugLog(`Fan: ${this.accessory.displayName} Swing Mode Characteristic was removed.`);
112
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Swing Mode Characteristic was removed.`);
112
113
  } else {
113
114
  // eslint-disable-next-line max-len
114
115
  this.debugLog(
115
- `Fan: ${this.accessory.displayName} Swing Mode Characteristic was not removed/added, ` +
116
+ `${this.device.remoteType}: ${this.accessory.displayName} Swing Mode Characteristic was not removed/added, ` +
116
117
  `Clear Cache on ${this.accessory.displayName} To Remove Chracteristic`,
117
118
  );
118
119
  }
119
120
  }
120
121
 
121
122
  async SwingModeSet(value: CharacteristicValue): Promise<void> {
122
- this.debugLog(`Fan: ${this.accessory.displayName} SwingMode: ${value}`);
123
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} SwingMode: ${value}`);
123
124
  if (value > this.SwingMode) {
124
125
  this.SwingMode = 1;
125
126
  await this.pushFanOnChanges();
@@ -134,27 +135,27 @@ export class Fan {
134
135
 
135
136
  async updateHomeKitCharacteristics(): Promise<void> {
136
137
  if (this.Active === undefined) {
137
- this.debugLog(`Fan: ${this.accessory.displayName} Active: ${this.Active}`);
138
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Active: ${this.Active}`);
138
139
  } else {
139
140
  this.fanService?.updateCharacteristic(this.platform.Characteristic.Active, this.Active);
140
- this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
141
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
141
142
  }
142
143
  if (this.SwingMode === undefined) {
143
- this.debugLog(`Fan: ${this.accessory.displayName} SwingMode: ${this.SwingMode}`);
144
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} SwingMode: ${this.SwingMode}`);
144
145
  } else {
145
146
  this.fanService?.updateCharacteristic(this.platform.Characteristic.SwingMode, this.SwingMode);
146
- this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic SwingMode: ${this.SwingMode}`);
147
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic SwingMode: ${this.SwingMode}`);
147
148
  }
148
149
  if (this.RotationSpeed === undefined) {
149
- this.debugLog(`Fan: ${this.accessory.displayName} RotationSpeed: ${this.RotationSpeed}`);
150
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} RotationSpeed: ${this.RotationSpeed}`);
150
151
  } else {
151
152
  this.fanService?.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.RotationSpeed);
152
- this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic RotationSpeed: ${this.RotationSpeed}`);
153
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic RotationSpeed: ${this.RotationSpeed}`);
153
154
  }
154
155
  }
155
156
 
156
157
  async RotationSpeedSet(value: CharacteristicValue): Promise<void> {
157
- this.debugLog(`Fan: ${this.accessory.displayName} RotationSpeed: ${value}`);
158
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} RotationSpeed: ${value}`);
158
159
  if (value > this.RotationSpeed) {
159
160
  this.RotationSpeed = 1;
160
161
  this.pushFanSpeedUpChanges();
@@ -167,7 +168,7 @@ export class Fan {
167
168
  }
168
169
 
169
170
  async ActiveSet(value: CharacteristicValue): Promise<void> {
170
- this.debugLog(`Fan: ${this.accessory.displayName} Active: ${value}`);
171
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Active: ${value}`);
171
172
  if (value === this.platform.Characteristic.Active.INACTIVE) {
172
173
  this.pushFanOffChanges();
173
174
  } else {
@@ -181,11 +182,11 @@ export class Fan {
181
182
  /**
182
183
  * Pushes the requested changes to the SwitchBot API
183
184
  * deviceType commandType Command command parameter Description
184
- * Fan: "command" "swing" "default" = swing
185
- * Fan: "command" "timer" "default" = timer
186
- * Fan: "command" "lowSpeed" "default" = fan speed to low
187
- * Fan: "command" "middleSpeed" "default" = fan speed to medium
188
- * Fan: "command" "highSpeed" "default" = fan speed to high
185
+ * Fan - "command" "swing" "default" = swing
186
+ * Fan - "command" "timer" "default" = timer
187
+ * Fan - "command" "lowSpeed" "default" = fan speed to low
188
+ * Fan - "command" "middleSpeed" "default" = fan speed to medium
189
+ * Fan - "command" "highSpeed" "default" = fan speed to high
189
190
  */
190
191
  async pushFanOnChanges(): Promise<void> {
191
192
  if (this.Active !== 1) {
@@ -235,84 +236,87 @@ export class Fan {
235
236
  }
236
237
 
237
238
  async pushTVChanges(body): Promise<void> {
238
- try {
239
+ if (this.OpenAPI) {
240
+ try {
239
241
  // Make Push On request to the API
240
- const t = Date.now();
241
- const nonce = 'requestID';
242
- const data = this.platform.config.credentials?.token + t + nonce;
243
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
244
- .update(Buffer.from(data, 'utf-8'))
245
- .digest();
246
- const sign = signTerm.toString('base64');
247
- this.debugLog(`Fan: ${this.accessory.displayName} sign: ${sign}`);
248
- this.infoLog(`Fan: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
249
- const options = {
250
- hostname: HostDomain,
251
- port: 443,
252
- path: `${DevicePath}/${this.device.deviceId}/commands`,
253
- method: 'POST',
254
- headers: {
255
- 'Authorization': this.platform.config.credentials?.token,
256
- 'sign': sign,
257
- 'nonce': nonce,
258
- 't': t,
259
- 'Content-Type': 'application/json',
260
- 'Content-Length': body.length,
261
- },
262
- };
263
- const req = https.request(options, res => {
264
- this.debugLog(`Fan: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
265
- this.statusCode({ res });
266
- res.on('data', d => {
267
- this.debugLog(`Fan: ${this.accessory.displayName} d: ${d}`);
242
+ const t = Date.now();
243
+ const nonce = 'requestID';
244
+ const data = this.platform.config.credentials?.token + t + nonce;
245
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
246
+ .update(Buffer.from(data, 'utf-8'))
247
+ .digest();
248
+ const sign = signTerm.toString('base64');
249
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
250
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
251
+ const options = {
252
+ hostname: HostDomain,
253
+ port: 443,
254
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
255
+ method: 'POST',
256
+ headers: {
257
+ 'Authorization': this.platform.config.credentials?.token,
258
+ 'sign': sign,
259
+ 'nonce': nonce,
260
+ 't': t,
261
+ 'Content-Type': 'application/json',
262
+ 'Content-Length': body.length,
263
+ },
264
+ };
265
+ const req = https.request(options, res => {
266
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
267
+ this.statusCode({ res });
268
+ res.on('data', d => {
269
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
270
+ });
268
271
  });
269
- });
270
- req.on('error', (e: any) => {
271
- this.errorLog(`Fan: ${this.accessory.displayName} error message: ${e.message}`);
272
- });
273
- req.write(body);
274
- req.end();
275
- this.debugLog(`Fan: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
276
- this.updateHomeKitCharacteristics();
277
- } catch (e: any) {
278
- this.errorLog(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
279
- if (this.deviceLogging.includes('debug')) {
280
- this.errorLog(
281
- `Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
282
- );
272
+ req.on('error', (e: any) => {
273
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`);
274
+ });
275
+ req.write(body);
276
+ req.end();
277
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
278
+ this.updateHomeKitCharacteristics();
279
+ } catch (e: any) {
280
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
281
+ if (this.deviceLogging.includes('debug')) {
282
+ this.errorLog(
283
+ `${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
284
+ + ` Error Message: ${superStringify(e.message)}`,
285
+ );
286
+ }
287
+ this.apiError(e);
283
288
  }
284
- this.apiError(e);
285
289
  }
286
290
  }
287
291
 
288
292
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
289
293
  switch (res.statusCode) {
290
294
  case 151:
291
- this.errorLog(`Fan: ${this.accessory.displayName} Command not supported by this device type.`);
295
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
292
296
  break;
293
297
  case 152:
294
- this.errorLog(`Fan: ${this.accessory.displayName} Device not found.`);
298
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
295
299
  break;
296
300
  case 160:
297
- this.errorLog(`Fan: ${this.accessory.displayName} Command is not supported.`);
301
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
298
302
  break;
299
303
  case 161:
300
- this.errorLog(`Fan: ${this.accessory.displayName} Device is offline.`);
304
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
301
305
  break;
302
306
  case 171:
303
- this.errorLog(`Fan: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
307
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
304
308
  break;
305
309
  case 190:
306
310
  this.errorLog(
307
- `Fan: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
311
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
308
312
  ` with server, Or command: ${superStringify(res)} format is invalid`,
309
313
  );
310
314
  break;
311
315
  case 100:
312
- this.debugLog(`Fan: ${this.accessory.displayName} Command successfully sent.`);
316
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
313
317
  break;
314
318
  default:
315
- this.debugLog(`Fan: ${this.accessory.displayName} Unknown statusCode.`);
319
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
316
320
  }
317
321
  }
318
322
 
@@ -323,6 +327,15 @@ export class Fan {
323
327
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
324
328
  }
325
329
 
330
+ async openAPI() {
331
+ if (!this.device.openAPI) {
332
+ this.OpenAPI = true;
333
+ } else {
334
+ this.OpenAPI = this.device.openAPI;
335
+ }
336
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using OpenAPI: ${this.OpenAPI}`);
337
+ }
338
+
326
339
  async config(device: irdevice & irDevicesConfig): Promise<void> {
327
340
  let config = {};
328
341
  if (device.irfan) {
@@ -331,24 +344,27 @@ export class Fan {
331
344
  if (device.logging !== undefined) {
332
345
  config['logging'] = device.logging;
333
346
  }
347
+ if (device.openAPI !== undefined) {
348
+ config['openAPI'] = device.openAPI;
349
+ }
334
350
  if (Object.entries(config).length !== 0) {
335
- this.infoLog(`Fan: ${this.accessory.displayName} Config: ${superStringify(config)}`);
351
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
336
352
  }
337
353
  }
338
354
 
339
355
  async logs(device: irdevice & irDevicesConfig): Promise<void> {
340
356
  if (this.platform.debugMode) {
341
357
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
342
- this.debugLog(`Fan: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
358
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
343
359
  } else if (device.logging) {
344
360
  this.deviceLogging = this.accessory.context.logging = device.logging;
345
- this.debugLog(`Fan: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
361
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
346
362
  } else if (this.platform.config.options?.logging) {
347
363
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
348
- this.debugLog(`Fan: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
364
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
349
365
  } else {
350
366
  this.deviceLogging = this.accessory.context.logging = 'standard';
351
- this.debugLog(`Fan: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
367
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
352
368
  }
353
369
  }
354
370
 
@@ -21,6 +21,7 @@ export class Light {
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
@@ -72,7 +73,7 @@ export class Light {
72
73
  }
73
74
 
74
75
  async OnSet(value: CharacteristicValue): Promise<void> {
75
- this.debugLog(`Light: ${this.accessory.displayName} On: ${value}`);
76
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${value}`);
76
77
  this.On = value;
77
78
  if (this.On) {
78
79
  await this.pushLightOnChanges();
@@ -83,22 +84,22 @@ export class Light {
83
84
 
84
85
  async updateHomeKitCharacteristics(): Promise<void> {
85
86
  if (this.On === undefined) {
86
- this.debugLog(`Light: ${this.accessory.displayName} On: ${this.On}`);
87
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${this.On}`);
87
88
  } else {
88
89
  this.lightBulbService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
89
- this.debugLog(`Light: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
90
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
90
91
  }
91
92
  }
92
93
 
93
94
  /**
94
95
  * Pushes the requested changes to the SwitchBot API
95
96
  * deviceType commandType Command command parameter Description
96
- * Light: "command" "turnOff" "default" = set to OFF state
97
- * Light: "command" "turnOn" "default" = set to ON state
98
- * Light: "command" "volumeAdd" "default" = volume up
99
- * Light: "command" "volumeSub" "default" = volume down
100
- * Light: "command" "channelAdd" "default" = next channel
101
- * Light: "command" "channelSub" "default" = previous channel
97
+ * Light - "command" "turnOff" "default" = set to OFF state
98
+ * Light - "command" "turnOn" "default" = set to ON state
99
+ * Light - "command" "volumeAdd" "default" = volume up
100
+ * Light - "command" "volumeSub" "default" = volume down
101
+ * Light - "command" "channelAdd" "default" = next channel
102
+ * Light - "command" "channelSub" "default" = previous channel
102
103
  */
103
104
  async pushLightOnChanges(): Promise<void> {
104
105
  if (this.On) {
@@ -141,86 +142,89 @@ export class Light {
141
142
  }
142
143
 
143
144
  async pushChanges(body): Promise<void> {
144
- try {
145
+ if (this.OpenAPI) {
146
+ try {
145
147
  // Make Push On request to the API
146
- const t = Date.now();
147
- const nonce = 'requestID';
148
- const data = this.platform.config.credentials?.token + t + nonce;
149
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
150
- .update(Buffer.from(data, 'utf-8'))
151
- .digest();
152
- const sign = signTerm.toString('base64');
153
- this.debugLog(`Light: ${this.accessory.displayName} sign: ${sign}`);
154
- this.infoLog(`Light: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
155
- const options = {
156
- hostname: HostDomain,
157
- port: 443,
158
- path: `${DevicePath}/${this.device.deviceId}/commands`,
159
- method: 'POST',
160
- headers: {
161
- 'Authorization': this.platform.config.credentials?.token,
162
- 'sign': sign,
163
- 'nonce': nonce,
164
- 't': t,
165
- 'Content-Type': 'application/json',
166
- 'Content-Length': body.length,
167
- },
168
- };
169
- const req = https.request(options, res => {
170
- this.debugLog(`Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
171
- this.statusCode({ res });
172
- res.on('data', d => {
173
- this.debugLog(`Light: ${this.accessory.displayName} d: ${d}`);
148
+ const t = Date.now();
149
+ const nonce = 'requestID';
150
+ const data = this.platform.config.credentials?.token + t + nonce;
151
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
152
+ .update(Buffer.from(data, 'utf-8'))
153
+ .digest();
154
+ const sign = signTerm.toString('base64');
155
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
156
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
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
+ 'Content-Length': body.length,
169
+ },
170
+ };
171
+ const req = https.request(options, res => {
172
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
173
+ this.statusCode({ res });
174
+ res.on('data', d => {
175
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
176
+ });
174
177
  });
175
- });
176
- req.on('error', (e: any) => {
177
- this.errorLog(`Light: ${this.accessory.displayName} error message: ${e.message}`);
178
- });
179
- req.write(body);
180
- req.end();
181
- this.debugLog(`Light: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
182
- this.OnCached = this.On;
183
- this.accessory.context.On = this.OnCached;
184
- this.updateHomeKitCharacteristics();
185
- } catch (e: any) {
186
- this.errorLog(`Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
187
- if (this.deviceLogging.includes('debug')) {
188
- this.errorLog(
189
- `Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${superStringify(e.message)}`,
190
- );
178
+ req.on('error', (e: any) => {
179
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`);
180
+ });
181
+ req.write(body);
182
+ req.end();
183
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
184
+ this.OnCached = this.On;
185
+ this.accessory.context.On = this.OnCached;
186
+ this.updateHomeKitCharacteristics();
187
+ } catch (e: any) {
188
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
189
+ if (this.deviceLogging.includes('debug')) {
190
+ this.errorLog(
191
+ `${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
192
+ + ` Error Message: ${superStringify(e.message)}`,
193
+ );
194
+ }
195
+ this.apiError(e);
191
196
  }
192
- this.apiError(e);
193
197
  }
194
198
  }
195
199
 
196
200
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
197
201
  switch (res.statusCode) {
198
202
  case 151:
199
- this.errorLog(`Light: ${this.accessory.displayName} Command not supported by this device type.`);
203
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
200
204
  break;
201
205
  case 152:
202
- this.errorLog(`Light: ${this.accessory.displayName} Device not found.`);
206
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
203
207
  break;
204
208
  case 160:
205
- this.errorLog(`Light: ${this.accessory.displayName} Command is not supported.`);
209
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
206
210
  break;
207
211
  case 161:
208
- this.errorLog(`Light: ${this.accessory.displayName} Device is offline.`);
212
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
209
213
  break;
210
214
  case 171:
211
- this.errorLog(`Light: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
215
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
212
216
  break;
213
217
  case 190:
214
218
  this.errorLog(
215
- `Light: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
219
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
216
220
  ` with server, Or command: ${superStringify(res)} format is invalid`,
217
221
  );
218
222
  break;
219
223
  case 100:
220
- this.debugLog(`Light: ${this.accessory.displayName} Command successfully sent.`);
224
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
221
225
  break;
222
226
  default:
223
- this.debugLog(`Light: ${this.accessory.displayName} Unknown statusCode.`);
227
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
224
228
  }
225
229
  }
226
230
 
@@ -229,6 +233,15 @@ export class Light {
229
233
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
230
234
  }
231
235
 
236
+ async openAPI() {
237
+ if (!this.device.openAPI) {
238
+ this.OpenAPI = true;
239
+ } else {
240
+ this.OpenAPI = this.device.openAPI;
241
+ }
242
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using OpenAPI: ${this.OpenAPI}`);
243
+ }
244
+
232
245
  async config(device: irdevice & irDevicesConfig): Promise<void> {
233
246
  let config = {};
234
247
  if (device.irlight) {
@@ -237,24 +250,27 @@ export class Light {
237
250
  if (device.logging !== undefined) {
238
251
  config['logging'] = device.logging;
239
252
  }
253
+ if (device.openAPI !== undefined) {
254
+ config['openAPI'] = device.openAPI;
255
+ }
240
256
  if (Object.entries(config).length !== 0) {
241
- this.infoLog(`Light: ${this.accessory.displayName} Config: ${superStringify(config)}`);
257
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
242
258
  }
243
259
  }
244
260
 
245
261
  async logs(device: irdevice & irDevicesConfig): Promise<void> {
246
262
  if (this.platform.debugMode) {
247
263
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
248
- this.debugLog(`Light: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
264
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
249
265
  } else if (device.logging) {
250
266
  this.deviceLogging = this.accessory.context.logging = device.logging;
251
- this.debugLog(`Light: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
267
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
252
268
  } else if (this.platform.config.options?.logging) {
253
269
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
254
- this.debugLog(`Light: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
270
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
255
271
  } else {
256
272
  this.deviceLogging = this.accessory.context.logging = 'standard';
257
- this.debugLog(`Light: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
273
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
258
274
  }
259
275
  }
260
276