@switchbot/homebridge-switchbot 1.4.1-beta.0 → 1.4.1-beta.4

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