@switchbot/homebridge-switchbot 1.4.0 → 1.4.1-beta.3

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 -0
  2. package/config.schema.json +83 -11
  3. package/dist/devices/bots.d.ts +13 -3
  4. package/dist/devices/bots.d.ts.map +1 -1
  5. package/dist/devices/bots.js +162 -105
  6. package/dist/devices/bots.js.map +1 -1
  7. package/dist/devices/colorbulb.d.ts +13 -3
  8. package/dist/devices/colorbulb.d.ts.map +1 -1
  9. package/dist/devices/colorbulb.js +161 -96
  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 +117 -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 +198 -140
  18. package/dist/devices/curtains.js.map +1 -1
  19. package/dist/devices/humidifiers.d.ts +13 -3
  20. package/dist/devices/humidifiers.d.ts.map +1 -1
  21. package/dist/devices/humidifiers.js +180 -127
  22. package/dist/devices/humidifiers.js.map +1 -1
  23. package/dist/devices/meters.d.ts +13 -3
  24. package/dist/devices/meters.d.ts.map +1 -1
  25. package/dist/devices/meters.js +121 -63
  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 +104 -45
  30. package/dist/devices/motion.js.map +1 -1
  31. package/dist/devices/plugs.d.ts +13 -3
  32. package/dist/devices/plugs.d.ts.map +1 -1
  33. package/dist/devices/plugs.js +99 -35
  34. package/dist/devices/plugs.js.map +1 -1
  35. package/dist/irdevices/airconditioners.d.ts +11 -3
  36. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  37. package/dist/irdevices/airconditioners.js +80 -45
  38. package/dist/irdevices/airconditioners.js.map +1 -1
  39. package/dist/irdevices/airpurifiers.d.ts +11 -3
  40. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  41. package/dist/irdevices/airpurifiers.js +68 -31
  42. package/dist/irdevices/airpurifiers.js.map +1 -1
  43. package/dist/irdevices/cameras.d.ts +11 -3
  44. package/dist/irdevices/cameras.d.ts.map +1 -1
  45. package/dist/irdevices/cameras.js +64 -24
  46. package/dist/irdevices/cameras.js.map +1 -1
  47. package/dist/irdevices/fans.d.ts +11 -3
  48. package/dist/irdevices/fans.d.ts.map +1 -1
  49. package/dist/irdevices/fans.js +74 -35
  50. package/dist/irdevices/fans.js.map +1 -1
  51. package/dist/irdevices/lights.d.ts +11 -3
  52. package/dist/irdevices/lights.d.ts.map +1 -1
  53. package/dist/irdevices/lights.js +65 -25
  54. package/dist/irdevices/lights.js.map +1 -1
  55. package/dist/irdevices/others.d.ts +11 -3
  56. package/dist/irdevices/others.d.ts.map +1 -1
  57. package/dist/irdevices/others.js +71 -31
  58. package/dist/irdevices/others.js.map +1 -1
  59. package/dist/irdevices/tvs.d.ts +11 -3
  60. package/dist/irdevices/tvs.d.ts.map +1 -1
  61. package/dist/irdevices/tvs.js +81 -42
  62. package/dist/irdevices/tvs.js.map +1 -1
  63. package/dist/irdevices/vacuumcleaners.d.ts +11 -3
  64. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  65. package/dist/irdevices/vacuumcleaners.js +64 -24
  66. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  67. package/dist/irdevices/waterheaters.d.ts +11 -3
  68. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  69. package/dist/irdevices/waterheaters.js +64 -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 +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 +70 -66
  80. package/src/devices/bots.ts +169 -105
  81. package/src/devices/colorbulb.ts +170 -99
  82. package/src/devices/contact.ts +124 -64
  83. package/src/devices/curtains.ts +207 -145
  84. package/src/devices/humidifiers.ts +187 -129
  85. package/src/devices/meters.ts +128 -64
  86. package/src/devices/motion.ts +110 -45
  87. package/src/devices/plugs.ts +104 -36
  88. package/src/irdevices/airconditioners.ts +85 -45
  89. package/src/irdevices/airpurifiers.ts +73 -31
  90. package/src/irdevices/cameras.ts +69 -24
  91. package/src/irdevices/fans.ts +79 -36
  92. package/src/irdevices/lights.ts +70 -25
  93. package/src/irdevices/others.ts +76 -31
  94. package/src/irdevices/tvs.ts +86 -42
  95. package/src/irdevices/vacuumcleaners.ts +69 -24
  96. package/src/irdevices/waterheaters.ts +69 -24
  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
@@ -2,7 +2,7 @@ import Switchbot from 'node-switchbot';
2
2
  import { interval, Subject } from 'rxjs';
3
3
  import { skipWhile } from 'rxjs/operators';
4
4
  import { SwitchBotPlatform } from '../platform';
5
- import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
5
+ import { Service, PlatformAccessory, CharacteristicValue, HAPStatus } from 'homebridge';
6
6
  import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
7
7
 
8
8
  /**
@@ -34,8 +34,8 @@ export class Motion {
34
34
  lightLevel!: serviceData['lightLevel'];
35
35
 
36
36
  // 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;
37
+ deviceLogging!: string;
38
+ deviceRefreshRate!: number;
39
39
 
40
40
  // Updates
41
41
  motionUbpdateInProgress!: boolean;
@@ -47,6 +47,8 @@ export class Motion {
47
47
  public device: device & devicesConfig,
48
48
  ) {
49
49
  // default placeholders
50
+ this.refreshRate();
51
+ this.logs();
50
52
  this.MotionDetected = false;
51
53
 
52
54
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -102,13 +104,46 @@ export class Motion {
102
104
  this.updateHomeKitCharacteristics();
103
105
 
104
106
  // Start an update interval
105
- interval(this.platform.config.options!.refreshRate! * 1000)
107
+ interval(this.deviceRefreshRate * 1000)
106
108
  .pipe(skipWhile(() => this.motionUbpdateInProgress))
107
109
  .subscribe(() => {
108
110
  this.refreshStatus();
109
111
  });
110
112
  }
111
113
 
114
+ refreshRate() {
115
+ if (this.device.refreshRate) {
116
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
117
+ if (this.platform.debugMode) {
118
+ this.warnLog(`Using Device Config refreshRate: ${this.deviceRefreshRate}`);
119
+ }
120
+ } else if (this.platform.config.options!.refreshRate) {
121
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
122
+ if (this.platform.debugMode) {
123
+ this.warnLog(`Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
124
+ }
125
+ }
126
+ }
127
+
128
+ logs() {
129
+ if (this.device.logging) {
130
+ this.deviceLogging = this.accessory.context.logging = this.device.logging;
131
+ if (this.platform.debugMode) {
132
+ this.warnLog(`Using Device Config Logging: ${this.deviceLogging}`);
133
+ }
134
+ } else if (this.platform.config.options?.logging) {
135
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
136
+ if (this.platform.debugMode) {
137
+ this.warnLog(`Using Platform Config Logging: ${this.deviceLogging}`);
138
+ }
139
+ } else {
140
+ this.deviceLogging = this.accessory.context.logging = 'standard';
141
+ if (this.platform.debugMode) {
142
+ this.warnLog('Using Device Standard Logging');
143
+ }
144
+ }
145
+ }
146
+
112
147
  /**
113
148
  * Parse the device status from the SwitchBot api
114
149
  */
@@ -121,9 +156,9 @@ export class Motion {
121
156
  }
122
157
 
123
158
  private async BLEparseStatus() {
124
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} BLE parseStatus`);
159
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE parseStatus`);
125
160
  this.MotionDetected = Boolean(this.movement);
126
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
161
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
127
162
  // Light Level
128
163
  switch (this.lightLevel) {
129
164
  case 'dark':
@@ -144,9 +179,9 @@ export class Motion {
144
179
 
145
180
  private async openAPIparseStatus() {
146
181
  if (this.platform.config.credentials?.openToken) {
147
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
182
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
148
183
  this.MotionDetected = Boolean(this.deviceStatus.body.moveDetected);
149
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
184
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
150
185
  }
151
186
  }
152
187
 
@@ -164,12 +199,12 @@ export class Motion {
164
199
  private connectBLE() {
165
200
  const switchbot = new Switchbot();
166
201
  this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
167
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
202
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
168
203
  return switchbot;
169
204
  }
170
205
 
171
206
  private async BLERefreshStatus() {
172
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} BLE RefreshStatus`);
207
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE RefreshStatus`);
173
208
  // eslint-disable-next-line @typescript-eslint/no-var-requires
174
209
  const switchbot = this.connectBLE();
175
210
  // Start to monitor advertisement packets
@@ -183,16 +218,16 @@ export class Motion {
183
218
  this.movement = ad.serviceData.movement;
184
219
  this.battery = ad.serviceData.battery;
185
220
  this.lightLevel = ad.serviceData.lightLevel;
186
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
187
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, lightLevel: `
221
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
222
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, lightLevel: `
188
223
  + `${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`);
189
224
 
190
225
  if (this.serviceData) {
191
226
  this.connected = true;
192
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
227
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
193
228
  } else {
194
229
  this.connected = false;
195
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
230
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
196
231
  }
197
232
  };
198
233
  // Wait 10 seconds
@@ -204,49 +239,49 @@ export class Motion {
204
239
  this.parseStatus();
205
240
  this.updateHomeKitCharacteristics();
206
241
  } else {
207
- this.platform.log.error(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
242
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
208
243
  if (this.platform.config.credentials?.openToken) {
209
- this.platform.log.warn(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
244
+ this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
210
245
  await this.openAPIRefreshStatus();
211
246
  }
212
247
  }
213
248
  }).catch(async (e: any) => {
214
- this.platform.log.error(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
215
- if (this.deviceDebug) {
216
- this.platform.log.error(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
249
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
250
+ if (this.deviceLogging === 'debug') {
251
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
217
252
  + ` Error Message: ${JSON.stringify(e.message)}`);
218
253
  }
219
- if (this.debugDebug) {
220
- this.platform.log.error(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
254
+ if (this.platform.debugMode) {
255
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
221
256
  + ` Error: ${JSON.stringify(e)}`);
222
257
  }
223
258
  if (this.platform.config.credentials?.openToken) {
224
- this.platform.log.warn(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
259
+ this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
225
260
  await this.openAPIRefreshStatus();
226
261
  }
227
- this.apiError(e);
262
+ this.apiError();
228
263
  });
229
264
  }
230
265
 
231
266
  private async openAPIRefreshStatus() {
232
267
  if (this.platform.config.credentials?.openToken) {
233
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} OpenAPI RefreshStatus`);
268
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI RefreshStatus`);
234
269
  try {
235
270
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
236
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
271
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
237
272
  this.parseStatus();
238
273
  this.updateHomeKitCharacteristics();
239
274
  } catch (e: any) {
240
- this.platform.log.error(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
241
- if (this.deviceDebug) {
242
- this.platform.log.error(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
275
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
276
+ if (this.deviceLogging === 'debug') {
277
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
243
278
  + ` Error Message: ${JSON.stringify(e.message)}`);
244
279
  }
245
- if (this.debugDebug) {
246
- this.platform.log.error(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
280
+ if (this.platform.debugMode) {
281
+ this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
247
282
  + ` Error: ${JSON.stringify(e)}`);
248
283
  }
249
- this.apiError(e);
284
+ this.apiError();
250
285
  }
251
286
  }
252
287
  }
@@ -256,40 +291,70 @@ export class Motion {
256
291
  */
257
292
  updateHomeKitCharacteristics() {
258
293
  if (this.MotionDetected === undefined) {
259
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
294
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
260
295
  } else {
261
296
  this.service.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
262
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
297
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
263
298
  }
264
299
  if (this.device.ble) {
265
300
  if (this.BatteryLevel === undefined) {
266
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
301
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
267
302
  } else {
268
303
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
269
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
304
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
270
305
  }
271
306
  if (this.StatusLowBattery === undefined) {
272
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
307
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
273
308
  } else {
274
309
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
275
- this.platform.device(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
310
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
276
311
  }
277
312
  if (this.CurrentAmbientLightLevel === undefined) {
278
- this.platform.debug(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
313
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
279
314
  } else {
280
315
  this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
281
- this.platform.device(`Motion Sensor: ${this.accessory.displayName}`
316
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName}`
282
317
  + ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
283
318
  }
284
319
  }
285
320
  }
286
321
 
287
- public apiError(e: any) {
288
- this.service.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
289
- if (this.device.ble) {
290
- this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
291
- this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
292
- this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
322
+ public apiError() {
323
+ throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
324
+ }
325
+
326
+ /**
327
+ * Logging for Device
328
+ */
329
+ infoLog(...log: any[]) {
330
+ if (this.enablingDeviceLogging()) {
331
+ this.platform.log.info(String(...log));
332
+ }
333
+ }
334
+
335
+ warnLog(...log: any[]) {
336
+ if (this.enablingDeviceLogging()) {
337
+ this.platform.log.warn(String(...log));
338
+ }
339
+ }
340
+
341
+ errorLog(...log: any[]) {
342
+ if (this.enablingDeviceLogging()) {
343
+ this.platform.log.error(String(...log));
293
344
  }
294
345
  }
346
+
347
+ debugLog(...log: any[]) {
348
+ if (this.enablingDeviceLogging()) {
349
+ if (this.deviceLogging === 'debug') {
350
+ this.platform.log.info('[DEBUG]', String(...log));
351
+ } else {
352
+ this.platform.log.debug(String(...log));
353
+ }
354
+ }
355
+ }
356
+
357
+ enablingDeviceLogging(): boolean {
358
+ return this.deviceLogging === 'debug' || this.deviceLogging === 'standard';
359
+ }
295
360
  }
@@ -3,7 +3,7 @@ import { AxiosResponse } from 'axios';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { SwitchBotPlatform } from '../platform';
5
5
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
6
- import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
6
+ import { Service, PlatformAccessory, CharacteristicValue, HAPStatus } from 'homebridge';
7
7
  import { DeviceURL, device, devicesConfig, deviceStatusResponse, payload } from '../settings';
8
8
 
9
9
  export class Plug {
@@ -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,21 +99,54 @@ 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
- this.apiError(e);
111
+ this.apiError();
110
112
  }
111
113
  this.plugUpdateInProgress = false;
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,26 +155,26 @@ 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
- this.apiError(e);
177
+ this.apiError();
143
178
  }
144
179
  }
145
180
 
@@ -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,45 +217,45 @@ 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
 
192
- public apiError(e: any) {
193
- this.service.updateCharacteristic(this.platform.Characteristic.On, e);
227
+ public apiError() {
228
+ throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
194
229
  }
195
230
 
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
  }