@switchbot/homebridge-switchbot 2.0.0-beta.2 → 2.0.0-beta.20

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 (113) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +75 -20
  4. package/dist/device/bot.d.ts +32 -28
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +646 -648
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +34 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +429 -304
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +16 -7
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +288 -230
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +21 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +519 -489
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +22 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +415 -360
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +22 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +253 -147
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +21 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +325 -255
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +23 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +346 -208
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +17 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +261 -209
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +24 -16
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +267 -242
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +51 -16
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +527 -185
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +7 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +261 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +3 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +137 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +9 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +116 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +8 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +143 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +9 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +120 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +9 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +128 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +10 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +126 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +7 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +115 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +6 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +115 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +3 -5
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +203 -200
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +15 -11
  89. package/dist/settings.d.ts.map +1 -1
  90. package/dist/settings.js.map +1 -1
  91. package/package.json +12 -10
  92. package/src/device/bot.ts +641 -657
  93. package/src/device/colorbulb.ts +440 -339
  94. package/src/device/contact.ts +289 -233
  95. package/src/device/curtain.ts +523 -503
  96. package/src/device/humidifier.ts +421 -396
  97. package/src/device/lock.ts +257 -147
  98. package/src/device/meter.ts +335 -268
  99. package/src/device/meterplus.ts +354 -213
  100. package/src/device/motion.ts +264 -213
  101. package/src/device/plug.ts +270 -251
  102. package/src/device/striplight.ts +552 -207
  103. package/src/irdevice/airconditioner.ts +263 -241
  104. package/src/irdevice/airpurifier.ts +132 -103
  105. package/src/irdevice/camera.ts +112 -85
  106. package/src/irdevice/fan.ts +138 -106
  107. package/src/irdevice/light.ts +116 -103
  108. package/src/irdevice/other.ts +124 -97
  109. package/src/irdevice/tv.ts +123 -93
  110. package/src/irdevice/vacuumcleaner.ts +112 -89
  111. package/src/irdevice/waterheater.ts +111 -89
  112. package/src/platform.ts +195 -216
  113. package/src/settings.ts +15 -11
@@ -1,6 +1,7 @@
1
1
  import https from 'https';
2
2
  import crypto from 'crypto';
3
3
  import { IncomingMessage } from 'http';
4
+ import superStringify from 'super-stringify';
4
5
  import { SwitchBotPlatform } from '../platform';
5
6
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
6
7
  import { irdevice, irDevicesConfig, HostDomain, DevicePath } from '../settings';
@@ -16,7 +17,6 @@ export class Fan {
16
17
 
17
18
  // Characteristic Values
18
19
  Active!: CharacteristicValue;
19
- ActiveCached!: CharacteristicValue;
20
20
  ActiveIdentifier!: CharacteristicValue;
21
21
  RotationSpeed!: CharacteristicValue;
22
22
  SwingMode!: CharacteristicValue;
@@ -35,18 +35,17 @@ export class Fan {
35
35
  // default placeholders
36
36
  this.logs(device);
37
37
  this.config(device);
38
- if (this.Active === undefined) {
39
- this.Active = this.platform.Characteristic.Active.INACTIVE;
40
- } else {
41
- this.Active = this.accessory.context.Active;
42
- }
38
+ this.context();
43
39
 
44
40
  // set accessory information
45
41
  accessory
46
42
  .getService(this.platform.Service.AccessoryInformation)!
47
43
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
48
44
  .setCharacteristic(this.platform.Characteristic.Model, device.remoteType)
49
- .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
45
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
46
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
47
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
48
+ .updateValue(this.FirmwareRevision(accessory, device));
50
49
 
51
50
  // get the Television service if it exists, otherwise create a new Television service
52
51
  // you can create multiple services for each accessory
@@ -92,11 +91,11 @@ export class Fan {
92
91
  } else if (this.fanService.testCharacteristic(this.platform.Characteristic.RotationSpeed) && !device.irfan?.swing_mode) {
93
92
  const characteristic = this.fanService.getCharacteristic(this.platform.Characteristic.RotationSpeed);
94
93
  this.fanService.removeCharacteristic(characteristic);
95
- this.debugLog(`Fan: ${this.accessory.displayName} Rotation Speed Characteristic was removed.`);
94
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Rotation Speed Characteristic was removed.`);
96
95
  } else {
97
96
  // eslint-disable-next-line max-len
98
97
  this.debugLog(
99
- `Fan: ${this.accessory.displayName} RotationSpeed Characteristic was not removed/added, ` +
98
+ `${this.device.remoteType}: ${this.accessory.displayName} RotationSpeed Characteristic was not removed/added, ` +
100
99
  `Clear Cache on ${this.accessory.displayName} to remove Chracteristic`,
101
100
  );
102
101
  }
@@ -107,18 +106,18 @@ export class Fan {
107
106
  } else if (this.fanService.testCharacteristic(this.platform.Characteristic.SwingMode) && !device.irfan?.swing_mode) {
108
107
  const characteristic = this.fanService.getCharacteristic(this.platform.Characteristic.SwingMode);
109
108
  this.fanService.removeCharacteristic(characteristic);
110
- this.debugLog(`Fan: ${this.accessory.displayName} Swing Mode Characteristic was removed.`);
109
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Swing Mode Characteristic was removed.`);
111
110
  } else {
112
111
  // eslint-disable-next-line max-len
113
112
  this.debugLog(
114
- `Fan: ${this.accessory.displayName} Swing Mode Characteristic was not removed/added, ` +
113
+ `${this.device.remoteType}: ${this.accessory.displayName} Swing Mode Characteristic was not removed/added, ` +
115
114
  `Clear Cache on ${this.accessory.displayName} To Remove Chracteristic`,
116
115
  );
117
116
  }
118
117
  }
119
118
 
120
119
  async SwingModeSet(value: CharacteristicValue): Promise<void> {
121
- this.debugLog(`Fan: ${this.accessory.displayName} SwingMode: ${value}`);
120
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} SwingMode: ${value}`);
122
121
  if (value > this.SwingMode) {
123
122
  this.SwingMode = 1;
124
123
  await this.pushFanOnChanges();
@@ -129,31 +128,11 @@ export class Fan {
129
128
  await this.pushFanSwingChanges();
130
129
  }
131
130
  this.SwingMode = value;
132
- }
133
-
134
- async updateHomeKitCharacteristics(): Promise<void> {
135
- if (this.Active === undefined) {
136
- this.debugLog(`Fan: ${this.accessory.displayName} Active: ${this.Active}`);
137
- } else {
138
- this.fanService?.updateCharacteristic(this.platform.Characteristic.Active, this.Active);
139
- this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
140
- }
141
- if (this.SwingMode === undefined) {
142
- this.debugLog(`Fan: ${this.accessory.displayName} SwingMode: ${this.SwingMode}`);
143
- } else {
144
- this.fanService?.updateCharacteristic(this.platform.Characteristic.SwingMode, this.SwingMode);
145
- this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic SwingMode: ${this.SwingMode}`);
146
- }
147
- if (this.RotationSpeed === undefined) {
148
- this.debugLog(`Fan: ${this.accessory.displayName} RotationSpeed: ${this.RotationSpeed}`);
149
- } else {
150
- this.fanService?.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.RotationSpeed);
151
- this.debugLog(`Fan: ${this.accessory.displayName} updateCharacteristic RotationSpeed: ${this.RotationSpeed}`);
152
- }
131
+ this.accessory.context.SwingMode = this.SwingMode;
153
132
  }
154
133
 
155
134
  async RotationSpeedSet(value: CharacteristicValue): Promise<void> {
156
- this.debugLog(`Fan: ${this.accessory.displayName} RotationSpeed: ${value}`);
135
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} RotationSpeed: ${value}`);
157
136
  if (value > this.RotationSpeed) {
158
137
  this.RotationSpeed = 1;
159
138
  this.pushFanSpeedUpChanges();
@@ -163,32 +142,32 @@ export class Fan {
163
142
  this.pushFanSpeedDownChanges();
164
143
  }
165
144
  this.RotationSpeed = value;
145
+ this.accessory.context.RotationSpeed = this.RotationSpeed;
166
146
  }
167
147
 
168
148
  async ActiveSet(value: CharacteristicValue): Promise<void> {
169
- this.debugLog(`Fan: ${this.accessory.displayName} Active: ${value}`);
149
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Active: ${value}`);
150
+ this.Active = value;
151
+ this.accessory.context.Active = this.Active;
170
152
  if (value === this.platform.Characteristic.Active.INACTIVE) {
171
153
  this.pushFanOffChanges();
172
154
  } else {
173
155
  this.pushFanOnChanges();
174
156
  }
175
- this.Active = value;
176
- this.ActiveCached = this.Active;
177
- this.accessory.context.Active = this.ActiveCached;
178
157
  }
179
158
 
180
159
  /**
181
160
  * Pushes the requested changes to the SwitchBot API
182
161
  * deviceType commandType Command command parameter Description
183
- * Fan: "command" "swing" "default" = swing
184
- * Fan: "command" "timer" "default" = timer
185
- * Fan: "command" "lowSpeed" "default" = fan speed to low
186
- * Fan: "command" "middleSpeed" "default" = fan speed to medium
187
- * Fan: "command" "highSpeed" "default" = fan speed to high
162
+ * Fan - "command" "swing" "default" = swing
163
+ * Fan - "command" "timer" "default" = timer
164
+ * Fan - "command" "lowSpeed" "default" = fan speed to low
165
+ * Fan - "command" "middleSpeed" "default" = fan speed to medium
166
+ * Fan - "command" "highSpeed" "default" = fan speed to high
188
167
  */
189
168
  async pushFanOnChanges(): Promise<void> {
190
169
  if (this.Active !== 1) {
191
- const body = JSON.stringify({
170
+ const body = superStringify({
192
171
  'command': 'turnOn',
193
172
  'parameter': 'default',
194
173
  'commandType': 'command',
@@ -198,7 +177,7 @@ export class Fan {
198
177
  }
199
178
 
200
179
  async pushFanOffChanges(): Promise<void> {
201
- const body = JSON.stringify({
180
+ const body = superStringify({
202
181
  'command': 'turnOff',
203
182
  'parameter': 'default',
204
183
  'commandType': 'command',
@@ -207,7 +186,7 @@ export class Fan {
207
186
  }
208
187
 
209
188
  async pushFanSpeedUpChanges(): Promise<void> {
210
- const body = JSON.stringify({
189
+ const body = superStringify({
211
190
  'command': 'highSpeed',
212
191
  'parameter': 'default',
213
192
  'commandType': 'command',
@@ -216,7 +195,7 @@ export class Fan {
216
195
  }
217
196
 
218
197
  async pushFanSpeedDownChanges(): Promise<void> {
219
- const body = JSON.stringify({
198
+ const body = superStringify({
220
199
  'command': 'lowSpeed',
221
200
  'parameter': 'default',
222
201
  'commandType': 'command',
@@ -225,7 +204,7 @@ export class Fan {
225
204
  }
226
205
 
227
206
  async pushFanSwingChanges(): Promise<void> {
228
- const body = JSON.stringify({
207
+ const body = superStringify({
229
208
  'command': 'swing',
230
209
  'parameter': 'default',
231
210
  'commandType': 'command',
@@ -234,84 +213,110 @@ export class Fan {
234
213
  }
235
214
 
236
215
  async pushTVChanges(body): Promise<void> {
237
- try {
216
+ if (this.device.connectionType === 'OpenAPI') {
217
+ try {
238
218
  // Make Push On request to the API
239
- const t = Date.now();
240
- const nonce = 'requestID';
241
- const data = this.platform.config.credentials?.token + t + nonce;
242
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
243
- .update(Buffer.from(data, 'utf-8'))
244
- .digest();
245
- const sign = signTerm.toString('base64');
246
- this.debugLog(`Fan: ${this.accessory.displayName} sign: ${sign}`);
247
- this.infoLog(`Fan: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
248
- const options = {
249
- hostname: HostDomain,
250
- port: 443,
251
- path: `${DevicePath}/${this.device.deviceId}/commands`,
252
- method: 'POST',
253
- headers: {
254
- 'Authorization': this.platform.config.credentials?.token,
255
- 'sign': sign,
256
- 'nonce': nonce,
257
- 't': t,
258
- 'Content-Type': 'application/json',
259
- 'Content-Length': body.length,
260
- },
261
- };
262
- const req = https.request(options, res => {
263
- this.debugLog(`Fan: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
264
- this.statusCode({ res });
265
- res.on('data', d => {
266
- this.debugLog(`Fan: ${this.accessory.displayName} d: ${d}`);
219
+ const t = Date.now();
220
+ const nonce = 'requestID';
221
+ const data = this.platform.config.credentials?.token + t + nonce;
222
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
223
+ .update(Buffer.from(data, 'utf-8'))
224
+ .digest();
225
+ const sign = signTerm.toString('base64');
226
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
227
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
228
+ const options = {
229
+ hostname: HostDomain,
230
+ port: 443,
231
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
232
+ method: 'POST',
233
+ headers: {
234
+ 'Authorization': this.platform.config.credentials?.token,
235
+ 'sign': sign,
236
+ 'nonce': nonce,
237
+ 't': t,
238
+ 'Content-Type': 'application/json',
239
+ 'Content-Length': body.length,
240
+ },
241
+ };
242
+ const req = https.request(options, res => {
243
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges statusCode: ${res.statusCode}`);
244
+ this.statusCode({ res });
245
+ res.on('data', d => {
246
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
247
+ });
267
248
  });
268
- });
269
- req.on('error', (e: any) => {
270
- this.errorLog(`Fan: ${this.accessory.displayName} error message: ${e.message}`);
271
- });
272
- req.write(body);
273
- req.end();
274
- this.debugLog(`Fan: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
275
- this.updateHomeKitCharacteristics();
276
- } catch (e: any) {
277
- this.errorLog(`Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
278
- if (this.deviceLogging.includes('debug')) {
279
- this.errorLog(
280
- `Fan: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
249
+ req.on('error', (e: any) => {
250
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`);
251
+ });
252
+ req.write(body);
253
+ req.end();
254
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
255
+ this.updateHomeKitCharacteristics();
256
+ } catch (e: any) {
257
+ this.apiError(e);
258
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
259
+ + ` Error Message: ${superStringify(e.message)}`,
281
260
  );
282
261
  }
283
- this.apiError(e);
262
+ } else {
263
+ this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
264
+ + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
265
+ }
266
+ }
267
+
268
+ async updateHomeKitCharacteristics(): Promise<void> {
269
+ if (this.Active === undefined) {
270
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Active: ${this.Active}`);
271
+ } else {
272
+ this.accessory.context.Active = this.Active;
273
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.Active, this.Active);
274
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.Active}`);
275
+ }
276
+ if (this.SwingMode === undefined) {
277
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} SwingMode: ${this.SwingMode}`);
278
+ } else {
279
+ this.accessory.context.SwingMode = this.SwingMode;
280
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.SwingMode, this.SwingMode);
281
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic SwingMode: ${this.SwingMode}`);
282
+ }
283
+ if (this.RotationSpeed === undefined) {
284
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} RotationSpeed: ${this.RotationSpeed}`);
285
+ } else {
286
+ this.accessory.context.RotationSpeed = this.RotationSpeed;
287
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.RotationSpeed);
288
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic RotationSpeed: ${this.RotationSpeed}`);
284
289
  }
285
290
  }
286
291
 
287
292
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
288
293
  switch (res.statusCode) {
289
294
  case 151:
290
- this.errorLog(`Fan: ${this.accessory.displayName} Command not supported by this device type.`);
295
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
291
296
  break;
292
297
  case 152:
293
- this.errorLog(`Fan: ${this.accessory.displayName} Device not found.`);
298
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
294
299
  break;
295
300
  case 160:
296
- this.errorLog(`Fan: ${this.accessory.displayName} Command is not supported.`);
301
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
297
302
  break;
298
303
  case 161:
299
- this.errorLog(`Fan: ${this.accessory.displayName} Device is offline.`);
304
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
300
305
  break;
301
306
  case 171:
302
- this.errorLog(`Fan: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
307
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
303
308
  break;
304
309
  case 190:
305
310
  this.errorLog(
306
- `Fan: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
307
- ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
311
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
312
+ ` with server, Or command: ${superStringify(res)} format is invalid`,
308
313
  );
309
314
  break;
310
315
  case 100:
311
- this.debugLog(`Fan: ${this.accessory.displayName} Command successfully sent.`);
316
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
312
317
  break;
313
318
  default:
314
- this.debugLog(`Fan: ${this.accessory.displayName} Unknown statusCode.`);
319
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
315
320
  }
316
321
  }
317
322
 
@@ -319,9 +324,33 @@ export class Fan {
319
324
  this.fanService.updateCharacteristic(this.platform.Characteristic.Active, e);
320
325
  this.fanService.updateCharacteristic(this.platform.Characteristic.RotationSpeed, e);
321
326
  this.fanService.updateCharacteristic(this.platform.Characteristic.SwingMode, e);
322
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
323
327
  }
324
328
 
329
+ FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string {
330
+ let FirmwareRevision: string;
331
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
332
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
333
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
334
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
335
+ if (accessory.context.FirmwareRevision) {
336
+ FirmwareRevision = accessory.context.FirmwareRevision;
337
+ } else if (device.firmware) {
338
+ FirmwareRevision = device.firmware;
339
+ } else {
340
+ FirmwareRevision = this.platform.version;
341
+ }
342
+ return FirmwareRevision;
343
+ }
344
+
345
+ async context() {
346
+ if (this.Active === undefined) {
347
+ this.Active = this.platform.Characteristic.Active.INACTIVE;
348
+ } else {
349
+ this.Active = this.accessory.context.Active;
350
+ }
351
+ }
352
+
353
+
325
354
  async config(device: irdevice & irDevicesConfig): Promise<void> {
326
355
  let config = {};
327
356
  if (device.irfan) {
@@ -330,24 +359,27 @@ export class Fan {
330
359
  if (device.logging !== undefined) {
331
360
  config['logging'] = device.logging;
332
361
  }
362
+ if (device.connectionType !== undefined) {
363
+ config['connectionType'] = device.connectionType;
364
+ }
333
365
  if (Object.entries(config).length !== 0) {
334
- this.infoLog(`Fan: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
366
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
335
367
  }
336
368
  }
337
369
 
338
370
  async logs(device: irdevice & irDevicesConfig): Promise<void> {
339
371
  if (this.platform.debugMode) {
340
372
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
341
- this.debugLog(`Fan: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
373
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
342
374
  } else if (device.logging) {
343
375
  this.deviceLogging = this.accessory.context.logging = device.logging;
344
- this.debugLog(`Fan: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
376
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
345
377
  } else if (this.platform.config.options?.logging) {
346
378
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
347
- this.debugLog(`Fan: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
379
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
348
380
  } else {
349
381
  this.deviceLogging = this.accessory.context.logging = 'standard';
350
- this.debugLog(`Fan: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
382
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
351
383
  }
352
384
  }
353
385