@switchbot/homebridge-switchbot 2.0.0-beta.3 → 2.0.0-beta.31

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 +34 -28
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +655 -649
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +36 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +483 -309
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +18 -8
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +303 -237
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +23 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +541 -498
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +24 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +450 -369
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +27 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +302 -148
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +22 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +340 -262
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +24 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +359 -213
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +18 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +276 -216
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +27 -17
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +292 -251
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +43 -19
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +503 -262
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +9 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +275 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +5 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +151 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +11 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +130 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +10 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +157 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +11 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +134 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +11 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +142 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +12 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +140 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +9 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +129 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +8 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +129 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +14 -12
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +456 -434
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +16 -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 +654 -660
  93. package/src/device/colorbulb.ts +487 -344
  94. package/src/device/contact.ts +306 -241
  95. package/src/device/curtain.ts +546 -512
  96. package/src/device/humidifier.ts +453 -403
  97. package/src/device/lock.ts +311 -149
  98. package/src/device/meter.ts +351 -275
  99. package/src/device/meterplus.ts +369 -219
  100. package/src/device/motion.ts +282 -222
  101. package/src/device/plug.ts +296 -260
  102. package/src/device/striplight.ts +519 -289
  103. package/src/irdevice/airconditioner.ts +279 -241
  104. package/src/irdevice/airpurifier.ts +148 -103
  105. package/src/irdevice/camera.ts +128 -85
  106. package/src/irdevice/fan.ts +154 -106
  107. package/src/irdevice/light.ts +132 -103
  108. package/src/irdevice/other.ts +140 -97
  109. package/src/irdevice/tv.ts +139 -93
  110. package/src/irdevice/vacuumcleaner.ts +128 -89
  111. package/src/irdevice/waterheater.ts +127 -89
  112. package/src/platform.ts +447 -457
  113. package/src/settings.ts +16 -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 { irDevicesConfig, irdevice, HostDomain, DevicePath } from '../settings';
6
7
  import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
@@ -16,7 +17,6 @@ export class VacuumCleaner {
16
17
 
17
18
  // Characteristic Values
18
19
  On!: CharacteristicValue;
19
- OnCached!: CharacteristicValue;
20
20
 
21
21
  // Config
22
22
  deviceLogging!: string;
@@ -25,23 +25,22 @@ export class VacuumCleaner {
25
25
  // default placeholders
26
26
  this.logs(device);
27
27
  this.config(device);
28
- if (this.On === undefined) {
29
- this.On = false;
30
- } else {
31
- this.On = this.accessory.context.On;
32
- }
28
+ this.context();
33
29
 
34
30
  // set accessory information
35
31
  accessory
36
32
  .getService(this.platform.Service.AccessoryInformation)!
37
33
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
38
34
  .setCharacteristic(this.platform.Characteristic.Model, device.remoteType)
39
- .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
35
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
36
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
37
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
38
+ .updateValue(this.FirmwareRevision(accessory, device));
40
39
 
41
40
  // get the Television service if it exists, otherwise create a new Television service
42
41
  // you can create multiple services for each accessory
43
42
  (this.switchService = accessory.getService(this.platform.Service.Switch) || accessory.addService(this.platform.Service.Switch)),
44
- `${accessory.displayName} Vacuum`;
43
+ `${accessory.displayName} ${device.remoteType}`;
45
44
 
46
45
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
47
46
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
@@ -56,8 +55,9 @@ export class VacuumCleaner {
56
55
  }
57
56
 
58
57
  async OnSet(value: CharacteristicValue): Promise<void> {
59
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} On: ${value}`);
58
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${value}`);
60
59
  this.On = value;
60
+ this.accessory.context.On = this.On;
61
61
  if (this.On) {
62
62
  await this.pushOnChanges();
63
63
  } else {
@@ -65,28 +65,15 @@ export class VacuumCleaner {
65
65
  }
66
66
  }
67
67
 
68
- async updateHomeKitCharacteristics(): Promise<void> {
69
- if (this.On === undefined) {
70
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} On: ${this.On}`);
71
- } else {
72
- this.switchService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
73
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
74
- }
75
- }
76
-
77
68
  /**
78
69
  * Pushes the requested changes to the SwitchBot API
79
- * deviceType commandType Command command parameter Description
80
- * Light: "command" "turnOff" "default" = set to OFF state
81
- * Light: "command" "turnOn" "default" = set to ON state
82
- * Light: "command" "volumeAdd" "default" = volume up
83
- * Light: "command" "volumeSub" "default" = volume down
84
- * Light: "command" "channelAdd" "default" = next channel
85
- * Light: "command" "channelSub" "default" = previous channel
70
+ * deviceType CommandType Command Parameter Description
71
+ * Vacuum Cleaner "command" "turnOff" "default" set to OFF state
72
+ * Vacuum Cleaner "command" "turnOn" "default" set to ON state
86
73
  */
87
74
  async pushOnChanges(): Promise<void> {
88
75
  if (this.On) {
89
- const body = JSON.stringify({
76
+ const body = superStringify({
90
77
  'command': 'turnOn',
91
78
  'parameter': 'default',
92
79
  'commandType': 'command',
@@ -97,7 +84,7 @@ export class VacuumCleaner {
97
84
 
98
85
  async pushOffChanges(): Promise<void> {
99
86
  if (!this.On) {
100
- const body = JSON.stringify({
87
+ const body = superStringify({
101
88
  'command': 'turnOff',
102
89
  'parameter': 'default',
103
90
  'commandType': 'command',
@@ -106,94 +93,127 @@ export class VacuumCleaner {
106
93
  }
107
94
  }
108
95
 
109
- async pushChanges(body): Promise<void> {
110
- try {
96
+ async pushChanges(body: any[]): Promise<void> {
97
+ if (this.device.connectionType === 'OpenAPI') {
98
+ try {
111
99
  // Make Push On request to the API
112
- const t = Date.now();
113
- const nonce = 'requestID';
114
- const data = this.platform.config.credentials?.token + t + nonce;
115
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
116
- .update(Buffer.from(data, 'utf-8'))
117
- .digest();
118
- const sign = signTerm.toString('base64');
119
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} sign: ${sign}`);
120
- this.infoLog(`Vacuum Cleaner: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
121
- const options = {
122
- hostname: HostDomain,
123
- port: 443,
124
- path: `${DevicePath}/${this.device.deviceId}/commands`,
125
- method: 'POST',
126
- headers: {
127
- 'Authorization': this.platform.config.credentials?.token,
128
- 'sign': sign,
129
- 'nonce': nonce,
130
- 't': t,
131
- 'Content-Type': 'application/json',
132
- 'Content-Length': body.length,
133
- },
134
- };
135
- const req = https.request(options, res => {
136
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
137
- this.statusCode({ res });
138
- res.on('data', d => {
139
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} d: ${d}`);
100
+ const t = Date.now();
101
+ const nonce = 'requestID';
102
+ const data = this.platform.config.credentials?.token + t + nonce;
103
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
104
+ .update(Buffer.from(data, 'utf-8'))
105
+ .digest();
106
+ const sign = signTerm.toString('base64');
107
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
108
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
109
+ const options = {
110
+ hostname: HostDomain,
111
+ port: 443,
112
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
113
+ method: 'POST',
114
+ headers: {
115
+ 'Authorization': this.platform.config.credentials?.token,
116
+ 'sign': sign,
117
+ 'nonce': nonce,
118
+ 't': t,
119
+ 'Content-Type': 'application/json',
120
+ 'Content-Length': body.length,
121
+ },
122
+ };
123
+ const req = https.request(options, res => {
124
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges statusCode: ${res.statusCode}`);
125
+ this.statusCode({ res });
126
+ res.on('data', d => {
127
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
128
+ });
140
129
  });
141
- });
142
- req.on('error', (e: any) => {
143
- this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} error message: ${e.message}`);
144
- });
145
- req.write(body);
146
- req.end();
147
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
148
- this.OnCached = this.On;
149
- this.accessory.context.On = this.OnCached;
150
- this.updateHomeKitCharacteristics();
151
- } catch (e: any) {
152
- this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
153
- if (this.deviceLogging.includes('debug')) {
154
- this.errorLog(
155
- `Vacuum Cleaner: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` +
156
- ` Error Message: ${JSON.stringify(e.message)}`,
130
+ req.on('error', (e: any) => {
131
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`);
132
+ });
133
+ req.write(body);
134
+ req.end();
135
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
136
+ this.accessory.context.On = this.On;
137
+ this.updateHomeKitCharacteristics();
138
+ } catch (e: any) {
139
+ this.apiError(e);
140
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
141
+ + ` Error Message: ${superStringify(e.message)}`,
157
142
  );
158
143
  }
159
- this.apiError(e);
144
+ } else {
145
+ this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
146
+ + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
147
+ }
148
+ }
149
+
150
+ async updateHomeKitCharacteristics(): Promise<void> {
151
+ if (this.On === undefined) {
152
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${this.On}`);
153
+ } else {
154
+ this.accessory.context.On = this.On;
155
+ this.switchService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
156
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
160
157
  }
161
158
  }
162
159
 
163
160
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
164
161
  switch (res.statusCode) {
165
162
  case 151:
166
- this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} Command not supported by this device type.`);
163
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
167
164
  break;
168
165
  case 152:
169
- this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} Device not found.`);
166
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`);
170
167
  break;
171
168
  case 160:
172
- this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} Command is not supported.`);
169
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`);
173
170
  break;
174
171
  case 161:
175
- this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} Device is offline.`);
172
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
176
173
  break;
177
174
  case 171:
178
- this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
175
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
179
176
  break;
180
177
  case 190:
181
178
  this.errorLog(
182
- `Vacuum Cleaner: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
183
- ` with server, Or command: ${JSON.stringify(res)} format is invalid`,
179
+ `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
180
+ ` with server, Or command: ${superStringify(res)} format is invalid`,
184
181
  );
185
182
  break;
186
183
  case 100:
187
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} Command successfully sent.`);
184
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
188
185
  break;
189
186
  default:
190
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} Unknown statusCode.`);
187
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode.`);
191
188
  }
192
189
  }
193
190
 
194
191
  async apiError(e: any): Promise<void> {
195
192
  this.switchService.updateCharacteristic(this.platform.Characteristic.On, e);
196
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
193
+ }
194
+
195
+ FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string {
196
+ let FirmwareRevision: string;
197
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
198
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
199
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
200
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
201
+ if (accessory.context.FirmwareRevision) {
202
+ FirmwareRevision = accessory.context.FirmwareRevision;
203
+ } else if (device.firmware) {
204
+ FirmwareRevision = device.firmware;
205
+ } else {
206
+ FirmwareRevision = this.platform.version;
207
+ }
208
+ return FirmwareRevision;
209
+ }
210
+
211
+ async context() {
212
+ if (this.On === undefined) {
213
+ this.On = false;
214
+ } else {
215
+ this.On = this.accessory.context.On;
216
+ }
197
217
  }
198
218
 
199
219
  async config(device: irdevice & irDevicesConfig): Promise<void> {
@@ -204,24 +224,27 @@ export class VacuumCleaner {
204
224
  if (device.logging !== undefined) {
205
225
  config['logging'] = device.logging;
206
226
  }
227
+ if (device.connectionType !== undefined) {
228
+ config['connectionType'] = device.connectionType;
229
+ }
207
230
  if (Object.entries(config).length !== 0) {
208
- this.infoLog(`Vacuum Cleaner: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
231
+ this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
209
232
  }
210
233
  }
211
234
 
212
235
  async logs(device: irdevice & irDevicesConfig): Promise<void> {
213
236
  if (this.platform.debugMode) {
214
237
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
215
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
238
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
216
239
  } else if (device.logging) {
217
240
  this.deviceLogging = this.accessory.context.logging = device.logging;
218
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
241
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
219
242
  } else if (this.platform.config.options?.logging) {
220
243
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
221
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
244
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
222
245
  } else {
223
246
  this.deviceLogging = this.accessory.context.logging = 'standard';
224
- this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
247
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
225
248
  }
226
249
  }
227
250
 
@@ -240,12 +263,28 @@ export class VacuumCleaner {
240
263
  }
241
264
  }
242
265
 
266
+ debugWarnLog(...log: any[]): void {
267
+ if (this.enablingDeviceLogging()) {
268
+ if (this.deviceLogging?.includes('debug')) {
269
+ this.platform.log.warn('[DEBUG]', String(...log));
270
+ }
271
+ }
272
+ }
273
+
243
274
  errorLog(...log: any[]): void {
244
275
  if (this.enablingDeviceLogging()) {
245
276
  this.platform.log.error(String(...log));
246
277
  }
247
278
  }
248
279
 
280
+ debugErrorLog(...log: any[]): void {
281
+ if (this.enablingDeviceLogging()) {
282
+ if (this.deviceLogging?.includes('debug')) {
283
+ this.platform.log.error('[DEBUG]', String(...log));
284
+ }
285
+ }
286
+ }
287
+
249
288
  debugLog(...log: any[]): void {
250
289
  if (this.enablingDeviceLogging()) {
251
290
  if (this.deviceLogging === 'debug') {