@switchbot/homebridge-switchbot 1.3.1-beta.9 → 1.4.1-beta.2

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 (103) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/config.schema.json +82 -32
  3. package/dist/devices/bots.d.ts +15 -3
  4. package/dist/devices/bots.d.ts.map +1 -1
  5. package/dist/devices/bots.js +227 -165
  6. package/dist/devices/bots.js.map +1 -1
  7. package/dist/devices/colorbulb.d.ts +14 -3
  8. package/dist/devices/colorbulb.d.ts.map +1 -1
  9. package/dist/devices/colorbulb.js +163 -105
  10. package/dist/devices/colorbulb.js.map +1 -1
  11. package/dist/devices/contact.d.ts +13 -3
  12. package/dist/devices/contact.d.ts.map +1 -1
  13. package/dist/devices/contact.js +102 -63
  14. package/dist/devices/contact.js.map +1 -1
  15. package/dist/devices/curtains.d.ts +14 -5
  16. package/dist/devices/curtains.d.ts.map +1 -1
  17. package/dist/devices/curtains.js +180 -140
  18. package/dist/devices/curtains.js.map +1 -1
  19. package/dist/devices/humidifiers.d.ts +14 -3
  20. package/dist/devices/humidifiers.d.ts.map +1 -1
  21. package/dist/devices/humidifiers.js +173 -133
  22. package/dist/devices/humidifiers.js.map +1 -1
  23. package/dist/devices/meters.d.ts +17 -13
  24. package/dist/devices/meters.d.ts.map +1 -1
  25. package/dist/devices/meters.js +150 -105
  26. package/dist/devices/meters.js.map +1 -1
  27. package/dist/devices/motion.d.ts +13 -3
  28. package/dist/devices/motion.d.ts.map +1 -1
  29. package/dist/devices/motion.js +89 -45
  30. package/dist/devices/motion.js.map +1 -1
  31. package/dist/devices/plugs.d.ts +15 -3
  32. package/dist/devices/plugs.d.ts.map +1 -1
  33. package/dist/devices/plugs.js +115 -53
  34. package/dist/devices/plugs.js.map +1 -1
  35. package/dist/irdevices/airconditioners.d.ts +13 -3
  36. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  37. package/dist/irdevices/airconditioners.js +97 -46
  38. package/dist/irdevices/airconditioners.js.map +1 -1
  39. package/dist/irdevices/airpurifiers.d.ts +13 -3
  40. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  41. package/dist/irdevices/airpurifiers.js +85 -31
  42. package/dist/irdevices/airpurifiers.js.map +1 -1
  43. package/dist/irdevices/cameras.d.ts +12 -3
  44. package/dist/irdevices/cameras.d.ts.map +1 -1
  45. package/dist/irdevices/cameras.js +73 -24
  46. package/dist/irdevices/cameras.js.map +1 -1
  47. package/dist/irdevices/fans.d.ts +12 -3
  48. package/dist/irdevices/fans.d.ts.map +1 -1
  49. package/dist/irdevices/fans.js +83 -35
  50. package/dist/irdevices/fans.js.map +1 -1
  51. package/dist/irdevices/lights.d.ts +12 -3
  52. package/dist/irdevices/lights.d.ts.map +1 -1
  53. package/dist/irdevices/lights.js +74 -25
  54. package/dist/irdevices/lights.js.map +1 -1
  55. package/dist/irdevices/others.d.ts +12 -3
  56. package/dist/irdevices/others.d.ts.map +1 -1
  57. package/dist/irdevices/others.js +80 -31
  58. package/dist/irdevices/others.js.map +1 -1
  59. package/dist/irdevices/tvs.d.ts +12 -3
  60. package/dist/irdevices/tvs.d.ts.map +1 -1
  61. package/dist/irdevices/tvs.js +90 -42
  62. package/dist/irdevices/tvs.js.map +1 -1
  63. package/dist/irdevices/vacuumcleaners.d.ts +12 -3
  64. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  65. package/dist/irdevices/vacuumcleaners.js +73 -24
  66. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  67. package/dist/irdevices/waterheaters.d.ts +12 -3
  68. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  69. package/dist/irdevices/waterheaters.js +73 -24
  70. package/dist/irdevices/waterheaters.js.map +1 -1
  71. package/dist/platform.d.ts +10 -10
  72. package/dist/platform.d.ts.map +1 -1
  73. package/dist/platform.js +290 -307
  74. package/dist/platform.js.map +1 -1
  75. package/dist/settings.d.ts +9 -6
  76. package/dist/settings.d.ts.map +1 -1
  77. package/dist/settings.js.map +1 -1
  78. package/nodemon.json +1 -1
  79. package/package.json +6 -6
  80. package/src/devices/bots.ts +221 -152
  81. package/src/devices/colorbulb.ts +172 -108
  82. package/src/devices/contact.ts +109 -64
  83. package/src/devices/curtains.ts +190 -146
  84. package/src/devices/humidifiers.ts +181 -135
  85. package/src/devices/meters.ts +156 -105
  86. package/src/devices/motion.ts +95 -45
  87. package/src/devices/plugs.ts +121 -53
  88. package/src/irdevices/airconditioners.ts +102 -46
  89. package/src/irdevices/airpurifiers.ts +91 -31
  90. package/src/irdevices/cameras.ts +79 -24
  91. package/src/irdevices/fans.ts +89 -36
  92. package/src/irdevices/lights.ts +80 -25
  93. package/src/irdevices/others.ts +86 -31
  94. package/src/irdevices/tvs.ts +96 -42
  95. package/src/irdevices/vacuumcleaners.ts +79 -24
  96. package/src/irdevices/waterheaters.ts +79 -24
  97. package/src/platform.ts +285 -302
  98. package/src/settings.ts +10 -6
  99. package/dist/devices/indoorcam.d.ts +0 -64
  100. package/dist/devices/indoorcam.d.ts.map +0 -1
  101. package/dist/devices/indoorcam.js +0 -249
  102. package/dist/devices/indoorcam.js.map +0 -1
  103. package/src/devices/indoorcam.ts +0 -309
@@ -1,7 +1,7 @@
1
1
  import { AxiosResponse } from 'axios';
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { irDevicesConfig, DeviceURL, irdevice, payload } from '../settings';
4
- import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
4
+ import { CharacteristicValue, HAPStatus, PlatformAccessory, Service } from 'homebridge';
5
5
 
6
6
  /**
7
7
  * Platform Accessory
@@ -14,9 +14,11 @@ export class AirConditioner {
14
14
 
15
15
  // Characteristic Values
16
16
  Active!: CharacteristicValue;
17
+ ActiveCached!: CharacteristicValue;
17
18
  RotationSpeed!: CharacteristicValue;
18
19
  LastTemperature!: CharacteristicValue;
19
20
  CurrentTemperature!: CharacteristicValue;
21
+ CurrentTemperatureCached!: CharacteristicValue;
20
22
  TargetHeaterCoolerState?: CharacteristicValue;
21
23
  CurrentHeaterCoolerState!: CharacteristicValue;
22
24
  HeatingThresholdTemperature?: CharacteristicValue;
@@ -33,15 +35,25 @@ export class AirConditioner {
33
35
  static MODE_HEAT: number;
34
36
 
35
37
  // Config
36
- private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
37
- private readonly debugDebug = this.platform.config.options?.debug === 'debug' || this.platform.debugMode;
38
+ deviceLogging!: string;
38
39
 
39
40
  constructor(
40
41
  private readonly platform: SwitchBotPlatform,
41
42
  private accessory: PlatformAccessory,
42
43
  public device: irdevice & irDevicesConfig,
43
44
  ) {
44
- this.CurrentTemperature = 24;
45
+ // default placeholders
46
+ this.logs();
47
+ if (this.Active === undefined) {
48
+ this.Active = this.platform.Characteristic.Active.INACTIVE;
49
+ } else {
50
+ this.Active = this.accessory.context.Active;
51
+ }
52
+ if (this.CurrentTemperature === undefined) {
53
+ this.CurrentTemperature = 24;
54
+ } else {
55
+ this.CurrentTemperature = this.accessory.context.CurrentTemperature;
56
+ }
45
57
 
46
58
  // set accessory information
47
59
  accessory
@@ -131,6 +143,16 @@ export class AirConditioner {
131
143
  .onSet(this.RotationSpeedSet.bind(this));
132
144
  }
133
145
 
146
+ logs() {
147
+ if (this.device.logging) {
148
+ this.deviceLogging = this.accessory.context.logging = this.device.logging;
149
+ } else if (this.platform.config.options?.logging) {
150
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
151
+ } else {
152
+ this.deviceLogging = this.accessory.context.logging = 'standard';
153
+ }
154
+ }
155
+
134
156
  private RotationSpeedSet(value: CharacteristicValue) {
135
157
  if (value === 4) {
136
158
  this.CurrentFanSpeed = 1;
@@ -151,63 +173,65 @@ export class AirConditioner {
151
173
  }
152
174
 
153
175
  private ActiveSet(value: CharacteristicValue) {
154
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} Set Active: ${value}`);
176
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} Set Active: ${value}`);
155
177
 
156
178
  if (value === this.platform.Characteristic.Active.INACTIVE) {
157
179
  this.pushAirConditionerOffChanges();
158
- this.platform.device(`Air Conditioner: ${this.accessory.displayName} pushAirConditionerOffChanges, Active: ${this.Active}`);
180
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} pushAirConditionerOffChanges, Active: ${this.Active}`);
159
181
  } else {
160
182
  this.pushAirConditionerOnChanges();
161
- this.platform.device(`Air Conditioner: ${this.accessory.displayName} pushAirConditionerOffChanges, Active: ${this.Active}`);
183
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} pushAirConditionerOffChanges, Active: ${this.Active}`);
162
184
  }
163
185
  this.Active = value;
186
+ this.ActiveCached = this.Active;
187
+ this.accessory.context.Active = this.ActiveCached;
164
188
  }
165
189
 
166
190
  private updateHomeKitCharacteristics() {
167
191
  if (this.Active === undefined) {
168
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} Active: ${this.Active}`);
192
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} Active: ${this.Active}`);
169
193
  } else {
170
194
  this.service?.updateCharacteristic(this.platform.Characteristic.Active, this.Active);
171
- this.platform.device(`Air Conditioner: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
195
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
172
196
  }
173
197
  if (this.RotationSpeed === undefined) {
174
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} RotationSpeed: ${this.RotationSpeed}`);
198
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} RotationSpeed: ${this.RotationSpeed}`);
175
199
  } else {
176
200
  this.service?.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.RotationSpeed);
177
- this.platform.device(`Air Conditioner: ${this.accessory.displayName} updateCharacteristic RotationSpeed: ${this.RotationSpeed}`);
201
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} updateCharacteristic RotationSpeed: ${this.RotationSpeed}`);
178
202
  }
179
203
  if (this.CurrentTemperature === undefined) {
180
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
204
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
181
205
  } else {
182
206
  this.service?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
183
- this.platform.device(`Air Conditioner: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
207
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
184
208
  }
185
209
  if (this.TargetHeaterCoolerState === undefined) {
186
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} TargetHeaterCoolerState: ${this.TargetHeaterCoolerState}`);
210
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} TargetHeaterCoolerState: ${this.TargetHeaterCoolerState}`);
187
211
  } else {
188
212
  this.service?.updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, this.TargetHeaterCoolerState);
189
- this.platform.device(`Air Conditioner: ${this.accessory.displayName}`
213
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName}`
190
214
  + ` updateCharacteristic TargetHeaterCoolerState: ${this.TargetHeaterCoolerState}`);
191
215
  }
192
216
  if (this.CurrentHeaterCoolerState === undefined) {
193
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
217
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
194
218
  } else {
195
219
  this.service?.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.CurrentHeaterCoolerState);
196
- this.platform.device(`Air Conditioner: ${this.accessory.displayName}`
220
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName}`
197
221
  + ` updateCharacteristic CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
198
222
  }
199
223
  if (this.HeatingThresholdTemperature === undefined) {
200
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} HeatingThresholdTemperature: ${this.HeatingThresholdTemperature}`);
224
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} HeatingThresholdTemperature: ${this.HeatingThresholdTemperature}`);
201
225
  } else {
202
226
  this.service?.updateCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature, this.HeatingThresholdTemperature);
203
- this.platform.device(`Air Conditioner: ${this.accessory.displayName}`
227
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName}`
204
228
  + ` updateCharacteristic HeatingThresholdTemperature: ${this.HeatingThresholdTemperature}`);
205
229
  }
206
230
  }
207
231
 
208
232
  private CurrentTemperatureGet(value: CharacteristicValue) {
209
233
  value = Number(this.CurrentTemperature) || 24;
210
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} Trigger Get CurrentTemperature: ${value}` );
234
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} Trigger Get CurrentTemperature: ${value}`);
211
235
 
212
236
  this.service
213
237
  .getCharacteristic(this.platform.Characteristic.CurrentTemperature)
@@ -243,13 +267,13 @@ export class AirConditioner {
243
267
  } else {
244
268
  this.CurrentHeaterCoolerState = this.platform.Characteristic.CurrentHeaterCoolerState.INACTIVE;
245
269
  }
246
- this.platform.device(`Air Conditioner: ${this.accessory.displayName} CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
270
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
247
271
  return this.CurrentHeaterCoolerState;
248
272
  }
249
273
 
250
274
  private HeatingThresholdTemperatureGet() {
251
275
  this.CurrentTemperature = this.CurrentTemperature || 24;
252
- this.platform.device(`Air Conditioner: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
276
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
253
277
  return this.CurrentTemperature;
254
278
  }
255
279
 
@@ -257,7 +281,7 @@ export class AirConditioner {
257
281
  this.pushAirConditionerStatusChanges();
258
282
  this.LastTemperature = Number(this.CurrentTemperature);
259
283
  this.CurrentTemperature = Number(value);
260
- this.platform.device(`Air Conditioner: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature},`
284
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature},`
261
285
  + ` LastTemperature: ${this.LastTemperature}`);
262
286
  }
263
287
 
@@ -342,63 +366,95 @@ export class AirConditioner {
342
366
 
343
367
  public async pushChanges(payload: payload) {
344
368
  try {
345
- this.platform.log.info(`Air Conditioner: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
369
+ this.infoLog(`Air Conditioner: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
346
370
  + ` parameter: [${payload.parameter}], commandType: ${payload.commandType}`);
347
371
 
348
372
  // Make the API request
349
373
  const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
350
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
374
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
351
375
  this.statusCode(push);
376
+ this.CurrentTemperatureCached = this.CurrentTemperature;
377
+ this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
352
378
  this.updateHomeKitCharacteristics();
353
379
  } catch (e: any) {
354
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} failed pushChanges`);
355
- if (this.deviceDebug) {
356
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} failed pushChanges,`
380
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} failed pushChanges`);
381
+ if (this.deviceLogging === 'debug') {
382
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} failed pushChanges,`
357
383
  + ` Error Message: ${JSON.stringify(e.message)}`);
358
384
  }
359
- if (this.debugDebug) {
360
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} failed pushChanges,`
385
+ if (this.platform.debugMode) {
386
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} failed pushChanges,`
361
387
  + ` Error: ${JSON.stringify(e)}`);
362
388
  }
363
- this.apiError(e);
389
+ this.apiError();
364
390
  }
365
391
  }
366
392
 
367
393
  private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
368
394
  switch (push.data.statusCode) {
369
395
  case 151:
370
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Command not supported by this device type.`);
396
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} Command not supported by this device type.`);
371
397
  break;
372
398
  case 152:
373
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Device not found.`);
399
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} Device not found.`);
374
400
  break;
375
401
  case 160:
376
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Command is not supported.`);
402
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} Command is not supported.`);
377
403
  break;
378
404
  case 161:
379
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Device is offline.`);
405
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} Device is offline.`);
380
406
  break;
381
407
  case 171:
382
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
408
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
383
409
  break;
384
410
  case 190:
385
- this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Device internal error due to device states not synchronized`
411
+ this.errorLog(`Air Conditioner: ${this.accessory.displayName} Device internal error due to device states not synchronized`
386
412
  + ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`);
387
413
  break;
388
414
  case 100:
389
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} Command successfully sent.`);
415
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} Command successfully sent.`);
390
416
  break;
391
417
  default:
392
- this.platform.debug(`Air Conditioner: ${this.accessory.displayName} Unknown statusCode.`);
418
+ this.debugLog(`Air Conditioner: ${this.accessory.displayName} Unknown statusCode.`);
419
+ }
420
+ }
421
+
422
+ public apiError() {
423
+ throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
424
+ }
425
+
426
+ /**
427
+ * Logging for Device
428
+ */
429
+ infoLog(...log: any[]) {
430
+ if (this.enablingDeviceLogging()) {
431
+ this.platform.log.info(String(...log));
432
+ }
433
+ }
434
+
435
+ warnLog(...log: any[]) {
436
+ if (this.enablingDeviceLogging()) {
437
+ this.platform.log.warn(String(...log));
438
+ }
439
+ }
440
+
441
+ errorLog(...log: any[]) {
442
+ if (this.enablingDeviceLogging()) {
443
+ this.platform.log.error(String(...log));
444
+ }
445
+ }
446
+
447
+ debugLog(...log: any[]) {
448
+ if (this.enablingDeviceLogging()) {
449
+ if (this.deviceLogging === 'debug') {
450
+ this.platform.log.info('[DEBUG]', String(...log));
451
+ } else {
452
+ this.platform.log.debug(String(...log));
453
+ }
393
454
  }
394
455
  }
395
456
 
396
- public apiError(e: any) {
397
- this.service.updateCharacteristic(this.platform.Characteristic.Active, e);
398
- this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, e);
399
- this.service.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
400
- this.service.updateCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState, e);
401
- this.service.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, e);
402
- this.service.updateCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature, e);
457
+ enablingDeviceLogging(): boolean {
458
+ return this.deviceLogging === 'debug' || this.deviceLogging === 'standard';
403
459
  }
404
460
  }
@@ -1,7 +1,7 @@
1
1
  import { AxiosResponse } from 'axios';
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { irDevicesConfig, DeviceURL, irdevice, payload } from '../settings';
4
- import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
4
+ import { CharacteristicValue, HAPStatus, PlatformAccessory, Service } from 'homebridge';
5
5
 
6
6
  /**
7
7
  * Platform Accessory
@@ -15,11 +15,13 @@ export class AirPurifier {
15
15
  // Characteristic Values
16
16
  Active!: CharacteristicValue;
17
17
  APActive!: CharacteristicValue;
18
+ ActiveCached!: CharacteristicValue;
18
19
  CurrentAPTemp!: CharacteristicValue;
19
20
  CurrentAPMode!: CharacteristicValue;
20
21
  RotationSpeed!: CharacteristicValue;
21
22
  CurrentAPFanSpeed!: CharacteristicValue;
22
23
  CurrentTemperature!: CharacteristicValue;
24
+ CurrentTemperatureCached!: CharacteristicValue;
23
25
  CurrentAirPurifierState!: CharacteristicValue;
24
26
  CurrentHeaterCoolerState!: CharacteristicValue;
25
27
 
@@ -34,14 +36,26 @@ export class AirPurifier {
34
36
  static PURIFYING_AIR: number;
35
37
 
36
38
  // Config
37
- private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
38
- private readonly debugDebug = this.platform.config.options?.debug === 'debug' || this.platform.debugMode;
39
+ deviceLogging!: string;
39
40
 
40
41
  constructor(
41
42
  private readonly platform: SwitchBotPlatform,
42
43
  private accessory: PlatformAccessory,
43
44
  public device: irdevice & irDevicesConfig,
44
45
  ) {
46
+ // default placeholders
47
+ this.logs();
48
+ if (this.Active === undefined) {
49
+ this.Active = this.platform.Characteristic.Active.INACTIVE;
50
+ } else {
51
+ this.Active = this.accessory.context.Active;
52
+ }
53
+ if (this.CurrentTemperature === undefined) {
54
+ this.CurrentTemperature = 24;
55
+ } else {
56
+ this.CurrentTemperature = this.accessory.context.CurrentTemperature;
57
+ }
58
+
45
59
  // set accessory information
46
60
  accessory
47
61
  .getService(this.platform.Service.AccessoryInformation)!
@@ -73,35 +87,47 @@ export class AirPurifier {
73
87
  this.service.getCharacteristic(this.platform.Characteristic.TargetAirPurifierState).onSet(this.TargetAirPurifierStateSet.bind(this));
74
88
  }
75
89
 
90
+ logs() {
91
+ if (this.device.logging) {
92
+ this.deviceLogging = this.accessory.context.logging = this.device.logging;
93
+ } else if (this.platform.config.options?.logging) {
94
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
95
+ } else {
96
+ this.deviceLogging = this.accessory.context.logging = 'standard';
97
+ }
98
+ }
99
+
76
100
  private ActiveSet(value: CharacteristicValue) {
77
- this.platform.debug(`Air Purifier: ${this.accessory.displayName} Set Active: ${value}`);
101
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} Set Active: ${value}`);
78
102
  if (value === this.platform.Characteristic.Active.INACTIVE) {
79
103
  this.pushAirConditionerOffChanges();
80
104
  } else {
81
105
  this.pushAirConditionerOnChanges();
82
106
  }
83
107
  this.Active = value;
108
+ this.ActiveCached = this.Active;
109
+ this.accessory.context.Active = this.ActiveCached;
84
110
  }
85
111
 
86
112
  private updateHomeKitCharacteristics() {
87
113
  if (this.Active === undefined) {
88
- this.platform.debug(`Air Purifier: ${this.accessory.displayName} Active: ${this.Active}`);
114
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} Active: ${this.Active}`);
89
115
  } else {
90
116
  this.service?.updateCharacteristic(this.platform.Characteristic.Active, this.Active);
91
- this.platform.device(`Air Purifier: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
117
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
92
118
  }
93
119
  if (this.CurrentAirPurifierState === undefined) {
94
- this.platform.debug(`Air Purifier: ${this.accessory.displayName} CurrentAirPurifierState: ${this.CurrentAirPurifierState}`);
120
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} CurrentAirPurifierState: ${this.CurrentAirPurifierState}`);
95
121
  } else {
96
122
  this.service?.updateCharacteristic(this.platform.Characteristic.CurrentAirPurifierState, this.CurrentAirPurifierState);
97
- this.platform.device(`Air Purifier: ${this.accessory.displayName}`
123
+ this.debugLog(`Air Purifier: ${this.accessory.displayName}`
98
124
  + ` updateCharacteristic CurrentAirPurifierState: ${this.CurrentAirPurifierState}`);
99
125
  }
100
126
  if (this.CurrentHeaterCoolerState === undefined) {
101
- this.platform.debug(`Air Purifier: ${this.accessory.displayName} CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
127
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
102
128
  } else {
103
129
  this.service?.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, this.CurrentHeaterCoolerState);
104
- this.platform.device(`Air Purifier: ${this.accessory.displayName}`
130
+ this.debugLog(`Air Purifier: ${this.accessory.displayName}`
105
131
  + ` updateCharacteristic CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
106
132
  }
107
133
  }
@@ -202,61 +228,95 @@ export class AirPurifier {
202
228
 
203
229
  public async pushChanges(payload: payload) {
204
230
  try {
205
- this.platform.log.info(`Air Purifier: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
231
+ this.infoLog(`Air Purifier: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
206
232
  + ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
207
233
 
208
234
  // Make the API request
209
235
  const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
210
- this.platform.debug(`Air Purifier: ${this.accessory.displayName} pushChanges: ${push.data}`);
236
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} pushChanges: ${push.data}`);
211
237
  this.statusCode(push);
212
238
  this.updateHomeKitCharacteristics();
239
+ this.CurrentTemperatureCached = this.CurrentTemperature;
240
+ this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
213
241
  } catch (e: any) {
214
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
215
- if (this.deviceDebug) {
216
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
242
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
243
+ if (this.deviceLogging === 'debug') {
244
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
217
245
  + ` Error Message: ${JSON.stringify(e.message)}`);
218
246
  }
219
- if (this.debugDebug) {
220
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
247
+ if (this.platform.debugMode) {
248
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
221
249
  + ` Error: ${JSON.stringify(e)}`);
222
250
  }
223
- this.apiError(e);
251
+ this.apiError();
224
252
  }
225
253
  }
226
254
 
227
255
  private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
228
256
  switch (push.data.statusCode) {
229
257
  case 151:
230
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Command not supported by this device type.`);
258
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} Command not supported by this device type.`);
231
259
  break;
232
260
  case 152:
233
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Device not found.`);
261
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} Device not found.`);
234
262
  break;
235
263
  case 160:
236
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Command is not supported.`);
264
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} Command is not supported.`);
237
265
  break;
238
266
  case 161:
239
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Device is offline.`);
267
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} Device is offline.`);
240
268
  break;
241
269
  case 171:
242
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
270
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
243
271
  break;
244
272
  case 190:
245
- this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Device internal error due to device states not synchronized`
273
+ this.errorLog(`Air Purifier: ${this.accessory.displayName} Device internal error due to device states not synchronized`
246
274
  + ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`);
247
275
  break;
248
276
  case 100:
249
- this.platform.debug(`Air Purifier: ${this.accessory.displayName} Command successfully sent.`);
277
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} Command successfully sent.`);
250
278
  break;
251
279
  default:
252
- this.platform.debug(`Air Purifier: ${this.accessory.displayName} Unknown statusCode.`);
280
+ this.debugLog(`Air Purifier: ${this.accessory.displayName} Unknown statusCode.`);
281
+ }
282
+ }
283
+
284
+ public apiError() {
285
+ throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
286
+ }
287
+
288
+ /**
289
+ * Logging for Device
290
+ */
291
+ infoLog(...log: any[]) {
292
+ if (this.enablingDeviceLogging()) {
293
+ this.platform.log.info(String(...log));
294
+ }
295
+ }
296
+
297
+ warnLog(...log: any[]) {
298
+ if (this.enablingDeviceLogging()) {
299
+ this.platform.log.warn(String(...log));
300
+ }
301
+ }
302
+
303
+ errorLog(...log: any[]) {
304
+ if (this.enablingDeviceLogging()) {
305
+ this.platform.log.error(String(...log));
306
+ }
307
+ }
308
+
309
+ debugLog(...log: any[]) {
310
+ if (this.enablingDeviceLogging()) {
311
+ if (this.deviceLogging === 'debug') {
312
+ this.platform.log.info('[DEBUG]', String(...log));
313
+ } else {
314
+ this.platform.log.debug(String(...log));
315
+ }
253
316
  }
254
317
  }
255
318
 
256
- public apiError(e: any) {
257
- this.service.updateCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState, e);
258
- this.service.updateCharacteristic(this.platform.Characteristic.CurrentAirPurifierState, e);
259
- this.service.updateCharacteristic(this.platform.Characteristic.TargetAirPurifierState, e);
260
- this.service.updateCharacteristic(this.platform.Characteristic.Active, e);
319
+ enablingDeviceLogging(): boolean {
320
+ return this.deviceLogging === 'debug' || this.deviceLogging === 'standard';
261
321
  }
262
322
  }