@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,16 +14,24 @@ export class Camera {
14
14
 
15
15
  // Characteristic Values
16
16
  On!: CharacteristicValue;
17
+ OnCached!: CharacteristicValue;
17
18
 
18
19
  // Config
19
- private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
20
- private readonly debugDebug = this.platform.config.options?.debug === 'debug' || this.platform.debugMode;
20
+ deviceLogging!: string;
21
21
 
22
22
  constructor(
23
23
  private readonly platform: SwitchBotPlatform,
24
24
  private accessory: PlatformAccessory,
25
25
  public device: irdevice & irDevicesConfig,
26
26
  ) {
27
+ // default placeholders
28
+ this.logs();
29
+ if (this.On === undefined) {
30
+ this.On = false;
31
+ } else {
32
+ this.On = this.accessory.context.On;
33
+ }
34
+
27
35
  // set accessory information
28
36
  accessory
29
37
  .getService(this.platform.Service.AccessoryInformation)!
@@ -49,8 +57,18 @@ export class Camera {
49
57
  this.service.getCharacteristic(this.platform.Characteristic.On).onSet(this.OnSet.bind(this));
50
58
  }
51
59
 
60
+ logs() {
61
+ if (this.device.logging) {
62
+ this.deviceLogging = this.accessory.context.logging = this.device.logging;
63
+ } else if (this.platform.config.options?.logging) {
64
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
65
+ } else {
66
+ this.deviceLogging = this.accessory.context.logging = 'standard';
67
+ }
68
+ }
69
+
52
70
  private OnSet(value: CharacteristicValue) {
53
- this.platform.debug(`Camera: ${this.accessory.displayName} On: ${value}`);
71
+ this.debugLog(`Camera: ${this.accessory.displayName} On: ${value}`);
54
72
  this.On = value;
55
73
  if (this.On) {
56
74
  this.pushOnChanges();
@@ -61,10 +79,10 @@ export class Camera {
61
79
 
62
80
  private updateHomeKitCharacteristics() {
63
81
  if (this.On === undefined) {
64
- this.platform.debug(`Camera: ${this.accessory.displayName} On: ${this.On}`);
82
+ this.debugLog(`Camera: ${this.accessory.displayName} On: ${this.On}`);
65
83
  } else {
66
84
  this.service?.updateCharacteristic(this.platform.Characteristic.On, this.On);
67
- this.platform.device(`Camera: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
85
+ this.debugLog(`Camera: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
68
86
  }
69
87
  }
70
88
 
@@ -102,58 +120,95 @@ export class Camera {
102
120
 
103
121
  public async pushChanges(payload: payload) {
104
122
  try {
105
- this.platform.log.info(`Camera: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
123
+ this.infoLog(`Camera: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
106
124
  + ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
107
125
 
108
126
  // Make the API request
109
127
  const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
110
- this.platform.debug(`Camera: ${this.accessory.displayName} pushChanges: ${push.data}`);
128
+ this.debugLog(`Camera: ${this.accessory.displayName} pushChanges: ${push.data}`);
111
129
  this.statusCode(push);
112
130
  this.updateHomeKitCharacteristics();
131
+ this.OnCached = this.On;
132
+ this.accessory.context.On = this.OnCached;
113
133
  } catch (e: any) {
114
- this.platform.log.error(`Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
115
- if (this.deviceDebug) {
116
- this.platform.log.error(`Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
134
+ this.errorLog(`Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
135
+ if (this.deviceLogging === 'debug') {
136
+ this.errorLog(`Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
117
137
  + ` Error Message: ${JSON.stringify(e.message)}`);
118
138
  }
119
- if (this.debugDebug) {
120
- this.platform.log.error(`Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
139
+ if (this.platform.debugMode) {
140
+ this.errorLog(`Camera: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
121
141
  + ` Error: ${JSON.stringify(e)}`);
122
142
  }
123
- this.apiError(e);
143
+ this.apiError();
124
144
  }
125
145
  }
126
146
 
127
147
  private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
128
148
  switch (push.data.statusCode) {
129
149
  case 151:
130
- this.platform.log.error(`Camera: ${this.accessory.displayName} Command not supported by this device type.`);
150
+ this.errorLog(`Camera: ${this.accessory.displayName} Command not supported by this device type.`);
131
151
  break;
132
152
  case 152:
133
- this.platform.log.error(`Camera: ${this.accessory.displayName} Device not found.`);
153
+ this.errorLog(`Camera: ${this.accessory.displayName} Device not found.`);
134
154
  break;
135
155
  case 160:
136
- this.platform.log.error(`Camera: ${this.accessory.displayName} Command is not supported.`);
156
+ this.errorLog(`Camera: ${this.accessory.displayName} Command is not supported.`);
137
157
  break;
138
158
  case 161:
139
- this.platform.log.error(`Camera: ${this.accessory.displayName} Device is offline.`);
159
+ this.errorLog(`Camera: ${this.accessory.displayName} Device is offline.`);
140
160
  break;
141
161
  case 171:
142
- this.platform.log.error(`Camera: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
162
+ this.errorLog(`Camera: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
143
163
  break;
144
164
  case 190:
145
- this.platform.log.error(`Camera: ${this.accessory.displayName} Device internal error due to device states not synchronized`
165
+ this.errorLog(`Camera: ${this.accessory.displayName} Device internal error due to device states not synchronized`
146
166
  + ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`);
147
167
  break;
148
168
  case 100:
149
- this.platform.debug(`Camera: ${this.accessory.displayName} Command successfully sent.`);
169
+ this.debugLog(`Camera: ${this.accessory.displayName} Command successfully sent.`);
150
170
  break;
151
171
  default:
152
- this.platform.debug(`Camera: ${this.accessory.displayName} Unknown statusCode.`);
172
+ this.debugLog(`Camera: ${this.accessory.displayName} Unknown statusCode.`);
173
+ }
174
+ }
175
+
176
+ public apiError() {
177
+ throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
178
+ }
179
+
180
+ /**
181
+ * Logging for Device
182
+ */
183
+ infoLog(...log: any[]) {
184
+ if (this.enablingDeviceLogging()) {
185
+ this.platform.log.info(String(...log));
186
+ }
187
+ }
188
+
189
+ warnLog(...log: any[]) {
190
+ if (this.enablingDeviceLogging()) {
191
+ this.platform.log.warn(String(...log));
192
+ }
193
+ }
194
+
195
+ errorLog(...log: any[]) {
196
+ if (this.enablingDeviceLogging()) {
197
+ this.platform.log.error(String(...log));
198
+ }
199
+ }
200
+
201
+ debugLog(...log: any[]) {
202
+ if (this.enablingDeviceLogging()) {
203
+ if (this.deviceLogging === 'debug') {
204
+ this.platform.log.info('[DEBUG]', String(...log));
205
+ } else {
206
+ this.platform.log.debug(String(...log));
207
+ }
153
208
  }
154
209
  }
155
210
 
156
- public apiError(e: any) {
157
- this.service.updateCharacteristic(this.platform.Characteristic.On, e);
211
+ enablingDeviceLogging(): boolean {
212
+ return this.deviceLogging === 'debug' || this.deviceLogging === 'standard';
158
213
  }
159
214
  }
@@ -1,6 +1,6 @@
1
1
  import { AxiosResponse } from 'axios';
2
2
  import { SwitchBotPlatform } from '../platform';
3
- import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
3
+ import { CharacteristicValue, HAPStatus, PlatformAccessory, Service } from 'homebridge';
4
4
  import { DeviceURL, irdevice, deviceStatusResponse, irDevicesConfig, payload } from '../settings';
5
5
 
6
6
  /**
@@ -14,6 +14,7 @@ export class Fan {
14
14
 
15
15
  // Characteristic Values
16
16
  Active!: CharacteristicValue;
17
+ ActiveCached!: CharacteristicValue;
17
18
  ActiveIdentifier!: CharacteristicValue;
18
19
  RotationSpeed!: CharacteristicValue;
19
20
  SwingMode!: CharacteristicValue;
@@ -26,14 +27,21 @@ export class Fan {
26
27
  minStep?: number;
27
28
  minValue?: number;
28
29
  maxValue?: number;
29
- private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
30
- private readonly debugDebug = this.platform.config.options?.debug === 'debug' || this.platform.debugMode;
30
+ deviceLogging!: string;
31
31
 
32
32
  constructor(
33
33
  private readonly platform: SwitchBotPlatform,
34
34
  private accessory: PlatformAccessory,
35
35
  public device: irdevice & irDevicesConfig,
36
36
  ) {
37
+ // default placeholders
38
+ this.logs();
39
+ if (this.Active === undefined) {
40
+ this.Active = this.platform.Characteristic.Active.INACTIVE;
41
+ } else {
42
+ this.Active = this.accessory.context.Active;
43
+ }
44
+
37
45
  // set accessory information
38
46
  accessory
39
47
  .getService(this.platform.Service.AccessoryInformation)!
@@ -88,10 +96,10 @@ export class Fan {
88
96
  !device.irfan?.swing_mode) {
89
97
  const characteristic = this.service.getCharacteristic(this.platform.Characteristic.RotationSpeed);
90
98
  this.service.removeCharacteristic(characteristic);
91
- this.platform.device(`Fan: ${this.accessory.displayName} Rotation Speed Characteristic was removed.`);
99
+ this.debugLog(`Fan: ${this.accessory.displayName} Rotation Speed Characteristic was removed.`);
92
100
  } else {
93
101
  // eslint-disable-next-line max-len
94
- this.platform.device(`Fan: ${this.accessory.displayName} Rotation Speed Characteristic was not removed or not added. To Remove Chracteristic, Clear Cache on this Accessory.`);
102
+ this.debugLog(`Fan: ${this.accessory.displayName} Rotation Speed Characteristic was not removed or not added. To Remove Chracteristic, Clear Cache on this Accessory.`);
95
103
  }
96
104
 
97
105
  if (device.irfan?.swing_mode) {
@@ -100,16 +108,26 @@ export class Fan {
100
108
  } else if (this.service.testCharacteristic(this.platform.Characteristic.SwingMode) && !device.irfan?.swing_mode) {
101
109
  const characteristic = this.service.getCharacteristic(this.platform.Characteristic.SwingMode);
102
110
  this.service.removeCharacteristic(characteristic);
103
- this.platform.device(`Fan: ${this.accessory.displayName} Swing Mode Characteristic was removed.`);
111
+ this.debugLog(`Fan: ${this.accessory.displayName} Swing Mode Characteristic was removed.`);
104
112
  } else {
105
113
  // eslint-disable-next-line max-len
106
- this.platform.device(`Fan: ${this.accessory.displayName} Swing Mode Characteristic was not removed or not added. To Remove Chracteristic, Clear Cache on this Accessory.`);
114
+ this.debugLog(`Fan: ${this.accessory.displayName} Swing Mode Characteristic was not removed or not added. To Remove Chracteristic, Clear Cache on this Accessory.`);
107
115
 
108
116
  }
109
117
  }
110
118
 
119
+ logs() {
120
+ if (this.device.logging) {
121
+ this.deviceLogging = this.accessory.context.logging = this.device.logging;
122
+ } else if (this.platform.config.options?.logging) {
123
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
124
+ } else {
125
+ this.deviceLogging = this.accessory.context.logging = 'standard';
126
+ }
127
+ }
128
+
111
129
  private SwingModeSet(value: CharacteristicValue) {
112
- this.platform.debug(`Fan: ${this.accessory.displayName} SwingMode: ${value}`);
130
+ this.debugLog(`Fan: ${this.accessory.displayName} SwingMode: ${value}`);
113
131
  if (value > this.SwingMode) {
114
132
  this.SwingMode = 1;
115
133
  this.pushFanOnChanges();
@@ -124,27 +142,27 @@ export class Fan {
124
142
 
125
143
  private updateHomeKitCharacteristics() {
126
144
  if (this.Active === undefined) {
127
- this.platform.debug(`Fan: ${this.accessory.displayName} Active: ${this.Active}`);
145
+ this.debugLog(`Fan: ${this.accessory.displayName} Active: ${this.Active}`);
128
146
  } else {
129
147
  this.service?.updateCharacteristic(this.platform.Characteristic.Active, this.Active);
130
- this.platform.device(`Fan: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
148
+ this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
131
149
  }
132
150
  if (this.SwingMode === undefined) {
133
- this.platform.debug(`Fan: ${this.accessory.displayName} SwingMode: ${this.SwingMode}`);
151
+ this.debugLog(`Fan: ${this.accessory.displayName} SwingMode: ${this.SwingMode}`);
134
152
  } else {
135
153
  this.service?.updateCharacteristic(this.platform.Characteristic.SwingMode, this.SwingMode);
136
- this.platform.device(`Fan: ${this.accessory.displayName} updateCharacteristic SwingMode: ${this.SwingMode}`);
154
+ this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic SwingMode: ${this.SwingMode}`);
137
155
  }
138
156
  if (this.RotationSpeed === undefined) {
139
- this.platform.debug(`Fan: ${this.accessory.displayName} RotationSpeed: ${this.RotationSpeed}`);
157
+ this.debugLog(`Fan: ${this.accessory.displayName} RotationSpeed: ${this.RotationSpeed}`);
140
158
  } else {
141
159
  this.service?.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.RotationSpeed);
142
- this.platform.device(`Fan: ${this.accessory.displayName} updateCharacteristic RotationSpeed: ${this.RotationSpeed}`);
160
+ this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic RotationSpeed: ${this.RotationSpeed}`);
143
161
  }
144
162
  }
145
163
 
146
164
  private RotationSpeedSet(value: CharacteristicValue) {
147
- this.platform.debug(`Fan: ${this.accessory.displayName} RotationSpeed: ${value}`);
165
+ this.debugLog(`Fan: ${this.accessory.displayName} RotationSpeed: ${value}`);
148
166
  if (value > this.RotationSpeed) {
149
167
  this.RotationSpeed = 1;
150
168
  this.pushFanSpeedUpChanges();
@@ -157,13 +175,15 @@ export class Fan {
157
175
  }
158
176
 
159
177
  private ActiveSet(value: CharacteristicValue) {
160
- this.platform.debug(`Fan: ${this.accessory.displayName} Active: ${value}`);
178
+ this.debugLog(`Fan: ${this.accessory.displayName} Active: ${value}`);
161
179
  if (value === this.platform.Characteristic.Active.INACTIVE) {
162
180
  this.pushFanOffChanges();
163
181
  } else {
164
182
  this.pushFanOnChanges();
165
183
  }
166
184
  this.Active = value;
185
+ this.ActiveCached = this.Active;
186
+ this.accessory.context.Active = this.ActiveCached;
167
187
  }
168
188
 
169
189
  /**
@@ -224,60 +244,93 @@ export class Fan {
224
244
 
225
245
  public async pushTVChanges(payload: payload) {
226
246
  try {
227
- this.platform.log.info(`Fan: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
247
+ this.infoLog(`Fan: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
228
248
  + ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
229
249
 
230
250
  // Make the API request
231
251
  const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
232
- this.platform.debug(`Fan: ${this.accessory.displayName} pushTVChanges: ${push.data}`);
252
+ this.debugLog(`Fan: ${this.accessory.displayName} pushTVChanges: ${push.data}`);
233
253
  this.statusCode(push);
234
254
  this.updateHomeKitCharacteristics();
235
255
  } catch (e: any) {
236
- this.platform.log.error(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
237
- if (this.deviceDebug) {
238
- this.platform.log.error(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
256
+ this.errorLog(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
257
+ if (this.deviceLogging === 'debug') {
258
+ this.errorLog(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
239
259
  + ` Error Message: ${JSON.stringify(e.message)}`);
240
260
  }
241
- if (this.debugDebug) {
242
- this.platform.log.error(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
261
+ if (this.platform.debugMode) {
262
+ this.errorLog(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
243
263
  + ` Error: ${JSON.stringify(e)}`);
244
264
  }
245
- this.apiError(e);
265
+ this.apiError();
246
266
  }
247
267
  }
248
268
 
249
269
  private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
250
270
  switch (push.data.statusCode) {
251
271
  case 151:
252
- this.platform.log.error(`Fan: ${this.accessory.displayName} Command not supported by this device type.`);
272
+ this.errorLog(`Fan: ${this.accessory.displayName} Command not supported by this device type.`);
253
273
  break;
254
274
  case 152:
255
- this.platform.log.error(`Fan: ${this.accessory.displayName} Device not found.`);
275
+ this.errorLog(`Fan: ${this.accessory.displayName} Device not found.`);
256
276
  break;
257
277
  case 160:
258
- this.platform.log.error(`Fan: ${this.accessory.displayName} Command is not supported.`);
278
+ this.errorLog(`Fan: ${this.accessory.displayName} Command is not supported.`);
259
279
  break;
260
280
  case 161:
261
- this.platform.log.error(`Fan: ${this.accessory.displayName} Device is offline.`);
281
+ this.errorLog(`Fan: ${this.accessory.displayName} Device is offline.`);
262
282
  break;
263
283
  case 171:
264
- this.platform.log.error(`Fan: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
284
+ this.errorLog(`Fan: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
265
285
  break;
266
286
  case 190:
267
- this.platform.log.error(`Fan: ${this.accessory.displayName} Device internal error due to device states not synchronized`
287
+ this.errorLog(`Fan: ${this.accessory.displayName} Device internal error due to device states not synchronized`
268
288
  + ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`);
269
289
  break;
270
290
  case 100:
271
- this.platform.debug(`Fan: ${this.accessory.displayName} Command successfully sent.`);
291
+ this.debugLog(`Fan: ${this.accessory.displayName} Command successfully sent.`);
272
292
  break;
273
293
  default:
274
- this.platform.debug(`Fan: ${this.accessory.displayName} Unknown statusCode.`);
294
+ this.debugLog(`Fan: ${this.accessory.displayName} Unknown statusCode.`);
295
+ }
296
+ }
297
+
298
+ public apiError() {
299
+ throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
300
+ }
301
+
302
+ /**
303
+ * Logging for Device
304
+ */
305
+ infoLog(...log: any[]) {
306
+ if (this.enablingDeviceLogging()) {
307
+ this.platform.log.info(String(...log));
308
+ }
309
+ }
310
+
311
+ warnLog(...log: any[]) {
312
+ if (this.enablingDeviceLogging()) {
313
+ this.platform.log.warn(String(...log));
314
+ }
315
+ }
316
+
317
+ errorLog(...log: any[]) {
318
+ if (this.enablingDeviceLogging()) {
319
+ this.platform.log.error(String(...log));
320
+ }
321
+ }
322
+
323
+ debugLog(...log: any[]) {
324
+ if (this.enablingDeviceLogging()) {
325
+ if (this.deviceLogging === 'debug') {
326
+ this.platform.log.info('[DEBUG]', String(...log));
327
+ } else {
328
+ this.platform.log.debug(String(...log));
329
+ }
275
330
  }
276
331
  }
277
332
 
278
- public apiError(e: any) {
279
- this.service.updateCharacteristic(this.platform.Characteristic.Active, e);
280
- this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, e);
281
- this.service.updateCharacteristic(this.platform.Characteristic.SwingMode, e);
333
+ enablingDeviceLogging(): boolean {
334
+ return this.deviceLogging === 'debug' || this.deviceLogging === 'standard';
282
335
  }
283
336
  }
@@ -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,16 +14,24 @@ export class Light {
14
14
 
15
15
  // Characteristic Values
16
16
  On!: CharacteristicValue;
17
+ OnCached!: CharacteristicValue;
17
18
 
18
19
  // Config
19
- private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
20
- private readonly debugDebug = this.platform.config.options?.debug === 'debug' || this.platform.debugMode;
20
+ deviceLogging!: string;
21
21
 
22
22
  constructor(
23
23
  private readonly platform: SwitchBotPlatform,
24
24
  private accessory: PlatformAccessory,
25
25
  public device: irdevice & irDevicesConfig,
26
26
  ) {
27
+ // default placeholders
28
+ this.logs();
29
+ if (this.On === undefined) {
30
+ this.On = false;
31
+ } else {
32
+ this.On = this.accessory.context.On;
33
+ }
34
+
27
35
  // set accessory information
28
36
  accessory
29
37
  .getService(this.platform.Service.AccessoryInformation)!
@@ -52,7 +60,7 @@ export class Light {
52
60
  /* this.service
53
61
  .getCharacteristic(this.platform.Characteristic.Brightness)
54
62
  .on(CharacteristicEventTypes.SET, (value: any, callback: CharacteristicGetCallback) => {
55
- this.platform.debug(`${this.device.remoteType} ${this.accessory.displayName} Set Brightness: ${value}`);
63
+ this.debugLog(`${this.device.remoteType} ${this.accessory.displayName} Set Brightness: ${value}`);
56
64
  this.Brightness = value;
57
65
  if (value > this.Brightness) {
58
66
  this.pushLightBrightnessUpChanges();
@@ -64,8 +72,18 @@ export class Light {
64
72
  });*/
65
73
  }
66
74
 
75
+ logs() {
76
+ if (this.device.logging) {
77
+ this.deviceLogging = this.accessory.context.logging = this.device.logging;
78
+ } else if (this.platform.config.options?.logging) {
79
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
80
+ } else {
81
+ this.deviceLogging = this.accessory.context.logging = 'standard';
82
+ }
83
+ }
84
+
67
85
  private OnSet(value: CharacteristicValue) {
68
- this.platform.debug(`Light: ${this.accessory.displayName} On: ${value}`);
86
+ this.debugLog(`Light: ${this.accessory.displayName} On: ${value}`);
69
87
  this.On = value;
70
88
  if (this.On) {
71
89
  this.pushLightOnChanges();
@@ -76,10 +94,10 @@ export class Light {
76
94
 
77
95
  private updateHomeKitCharacteristics() {
78
96
  if (this.On === undefined) {
79
- this.platform.debug(`Light: ${this.accessory.displayName} On: ${this.On}`);
97
+ this.debugLog(`Light: ${this.accessory.displayName} On: ${this.On}`);
80
98
  } else {
81
99
  this.service?.updateCharacteristic(this.platform.Characteristic.On, this.On);
82
- this.platform.device(`Light: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
100
+ this.debugLog(`Light: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
83
101
  }
84
102
  }
85
103
 
@@ -135,25 +153,27 @@ export class Light {
135
153
 
136
154
  public async pushChanges(payload: payload) {
137
155
  try {
138
- this.platform.log.info(`Light: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
156
+ this.infoLog(`Light: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
139
157
  + ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
140
158
 
141
159
  // Make the API request
142
160
  const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
143
- this.platform.debug(`Light: ${this.accessory.displayName} pushChanges: ${push.data}`);
161
+ this.debugLog(`Light: ${this.accessory.displayName} pushChanges: ${push.data}`);
144
162
  this.statusCode(push);
163
+ this.OnCached = this.On;
164
+ this.accessory.context.On = this.OnCached;
145
165
  this.updateHomeKitCharacteristics();
146
166
  } catch (e: any) {
147
- this.platform.log.error(`Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
148
- if (this.deviceDebug) {
149
- this.platform.log.error(`Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
167
+ this.errorLog(`Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
168
+ if (this.deviceLogging === 'debug') {
169
+ this.errorLog(`Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
150
170
  + ` Error Message: ${JSON.stringify(e.message)}`);
151
171
  }
152
- if (this.debugDebug) {
153
- this.platform.log.error(`Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
172
+ if (this.platform.debugMode) {
173
+ this.errorLog(`Light: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
154
174
  + ` Error: ${JSON.stringify(e)}`);
155
175
  }
156
- this.apiError(e);
176
+ this.apiError();
157
177
  }
158
178
  }
159
179
 
@@ -161,33 +181,68 @@ export class Light {
161
181
  private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
162
182
  switch (push.data.statusCode) {
163
183
  case 151:
164
- this.platform.log.error(`Light: ${this.accessory.displayName} Command not supported by this device type.`);
184
+ this.errorLog(`Light: ${this.accessory.displayName} Command not supported by this device type.`);
165
185
  break;
166
186
  case 152:
167
- this.platform.log.error(`Light: ${this.accessory.displayName} Device not found.`);
187
+ this.errorLog(`Light: ${this.accessory.displayName} Device not found.`);
168
188
  break;
169
189
  case 160:
170
- this.platform.log.error(`Light: ${this.accessory.displayName} Command is not supported.`);
190
+ this.errorLog(`Light: ${this.accessory.displayName} Command is not supported.`);
171
191
  break;
172
192
  case 161:
173
- this.platform.log.error(`Light: ${this.accessory.displayName} Device is offline.`);
193
+ this.errorLog(`Light: ${this.accessory.displayName} Device is offline.`);
174
194
  break;
175
195
  case 171:
176
- this.platform.log.error(`Light: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
196
+ this.errorLog(`Light: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
177
197
  break;
178
198
  case 190:
179
- this.platform.log.error(`Light: ${this.accessory.displayName} Device internal error due to device states not synchronized`
199
+ this.errorLog(`Light: ${this.accessory.displayName} Device internal error due to device states not synchronized`
180
200
  + ` with server, Or command: ${JSON.stringify(push.data)} format is invalid`);
181
201
  break;
182
202
  case 100:
183
- this.platform.debug(`Light: ${this.accessory.displayName} Command successfully sent.`);
203
+ this.debugLog(`Light: ${this.accessory.displayName} Command successfully sent.`);
184
204
  break;
185
205
  default:
186
- this.platform.debug(`Light: ${this.accessory.displayName} Unknown statusCode.`);
206
+ this.debugLog(`Light: ${this.accessory.displayName} Unknown statusCode.`);
207
+ }
208
+ }
209
+
210
+ public apiError() {
211
+ throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
212
+ }
213
+
214
+ /**
215
+ * Logging for Device
216
+ */
217
+ infoLog(...log: any[]) {
218
+ if (this.enablingDeviceLogging()) {
219
+ this.platform.log.info(String(...log));
220
+ }
221
+ }
222
+
223
+ warnLog(...log: any[]) {
224
+ if (this.enablingDeviceLogging()) {
225
+ this.platform.log.warn(String(...log));
226
+ }
227
+ }
228
+
229
+ errorLog(...log: any[]) {
230
+ if (this.enablingDeviceLogging()) {
231
+ this.platform.log.error(String(...log));
232
+ }
233
+ }
234
+
235
+ debugLog(...log: any[]) {
236
+ if (this.enablingDeviceLogging()) {
237
+ if (this.deviceLogging === 'debug') {
238
+ this.platform.log.info('[DEBUG]', String(...log));
239
+ } else {
240
+ this.platform.log.debug(String(...log));
241
+ }
187
242
  }
188
243
  }
189
244
 
190
- public apiError(e: any) {
191
- this.service.updateCharacteristic(this.platform.Characteristic.On, e);
245
+ enablingDeviceLogging(): boolean {
246
+ return this.deviceLogging === 'debug' || this.deviceLogging === 'standard';
192
247
  }
193
248
  }