@switchbot/homebridge-switchbot 2.0.0-beta.9 → 2.0.0
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.
- package/CHANGELOG.md +10 -1
- package/README.md +3 -2
- package/config.schema.json +91 -19
- package/dist/device/bot.d.ts +34 -28
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +657 -648
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +137 -0
- package/dist/device/ceilinglight.d.ts.map +1 -0
- package/dist/device/ceilinglight.js +1127 -0
- package/dist/device/ceilinglight.js.map +1 -0
- package/dist/device/colorbulb.d.ts +36 -14
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +472 -297
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +18 -8
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +306 -237
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +23 -16
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +566 -502
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/humidifier.d.ts +24 -18
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +453 -369
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/lock.d.ts +27 -8
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +305 -148
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +22 -16
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +367 -267
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +24 -12
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +381 -213
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +18 -8
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +279 -216
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +27 -17
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +295 -251
- package/dist/device/plug.js.map +1 -1
- package/dist/device/striplight.d.ts +43 -19
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +506 -262
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +9 -12
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +278 -230
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +5 -3
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +154 -104
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +11 -8
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +133 -86
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +10 -7
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +160 -109
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +11 -8
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +137 -103
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +11 -8
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +145 -98
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +12 -9
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +143 -93
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +9 -10
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +132 -89
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +8 -9
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +132 -89
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +13 -12
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +524 -418
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +19 -11
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/homebridge-ui/public/index.html +1 -0
- package/package.json +11 -9
- package/src/device/bot.ts +656 -659
- package/src/device/ceilinglight.ts +1208 -0
- package/src/device/colorbulb.ts +482 -334
- package/src/device/contact.ts +309 -241
- package/src/device/curtain.ts +571 -516
- package/src/device/humidifier.ts +456 -403
- package/src/device/lock.ts +314 -149
- package/src/device/meter.ts +378 -280
- package/src/device/meterplus.ts +391 -219
- package/src/device/motion.ts +285 -222
- package/src/device/plug.ts +299 -260
- package/src/device/striplight.ts +522 -289
- package/src/irdevice/airconditioner.ts +282 -241
- package/src/irdevice/airpurifier.ts +151 -103
- package/src/irdevice/camera.ts +131 -85
- package/src/irdevice/fan.ts +157 -106
- package/src/irdevice/light.ts +135 -103
- package/src/irdevice/other.ts +143 -97
- package/src/irdevice/tv.ts +142 -93
- package/src/irdevice/vacuumcleaner.ts +131 -89
- package/src/irdevice/waterheater.ts +130 -89
- package/src/platform.ts +522 -446
- package/src/settings.ts +20 -11
- package/.github/npm-version-script.js +0 -81
package/src/device/motion.ts
CHANGED
|
@@ -3,9 +3,11 @@ import crypto from 'crypto';
|
|
|
3
3
|
import { Context } from 'vm';
|
|
4
4
|
import { interval, Subject } from 'rxjs';
|
|
5
5
|
import { skipWhile } from 'rxjs/operators';
|
|
6
|
+
import superStringify from 'super-stringify';
|
|
6
7
|
import { SwitchBotPlatform } from '../platform';
|
|
7
8
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
8
9
|
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
|
|
10
|
+
import { IncomingMessage } from 'http';
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* Platform Accessory
|
|
@@ -32,7 +34,6 @@ export class Motion {
|
|
|
32
34
|
// BLE Others
|
|
33
35
|
connected?: boolean;
|
|
34
36
|
switchbot!: switchbot;
|
|
35
|
-
SwitchToOpenAPI?: boolean;
|
|
36
37
|
serviceData!: serviceData;
|
|
37
38
|
address!: ad['address'];
|
|
38
39
|
battery!: serviceData['battery'];
|
|
@@ -50,13 +51,17 @@ export class Motion {
|
|
|
50
51
|
motionUbpdateInProgress!: boolean;
|
|
51
52
|
doMotionUpdate!: Subject<void>;
|
|
52
53
|
|
|
54
|
+
// Connection
|
|
55
|
+
private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI');
|
|
56
|
+
private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI');
|
|
57
|
+
|
|
53
58
|
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
54
59
|
// default placeholders
|
|
55
60
|
this.logs(device);
|
|
56
61
|
this.scan(device);
|
|
57
62
|
this.refreshRate(device);
|
|
58
63
|
this.config(device);
|
|
59
|
-
this.
|
|
64
|
+
this.context();
|
|
60
65
|
|
|
61
66
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
62
67
|
this.doMotionUpdate = new Subject();
|
|
@@ -93,33 +98,33 @@ export class Motion {
|
|
|
93
98
|
|
|
94
99
|
// Light Sensor Service
|
|
95
100
|
if (device.motion?.hide_lightsensor) {
|
|
96
|
-
this.debugLog(
|
|
101
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
|
|
97
102
|
this.lightSensorService = this.accessory.getService(this.platform.Service.LightSensor);
|
|
98
103
|
accessory.removeService(this.lightSensorService!);
|
|
99
104
|
} else if (!this.lightSensorService) {
|
|
100
|
-
this.debugLog(
|
|
105
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
|
|
101
106
|
(this.lightSensorService =
|
|
102
107
|
this.accessory.getService(this.platform.Service.LightSensor) || this.accessory.addService(this.platform.Service.LightSensor)),
|
|
103
108
|
`${accessory.displayName} Light Sensor`;
|
|
104
109
|
|
|
105
110
|
this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
|
|
106
111
|
} else {
|
|
107
|
-
this.debugLog(
|
|
112
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
|
|
108
113
|
}
|
|
109
114
|
|
|
110
115
|
// Battery Service
|
|
111
|
-
if (!
|
|
112
|
-
this.debugLog(
|
|
116
|
+
if (!this.BLE) {
|
|
117
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Battery Service`);
|
|
113
118
|
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
114
119
|
accessory.removeService(this.batteryService!);
|
|
115
|
-
} else if (
|
|
116
|
-
this.debugLog(
|
|
120
|
+
} else if (this.BLE && !this.batteryService) {
|
|
121
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Battery Service`);
|
|
117
122
|
(this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
|
|
118
123
|
`${accessory.displayName} Battery`;
|
|
119
124
|
|
|
120
125
|
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
121
126
|
} else {
|
|
122
|
-
this.debugLog(
|
|
127
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Battery Service Not Added`);
|
|
123
128
|
}
|
|
124
129
|
|
|
125
130
|
// Retrieve initial values and updateHomekit
|
|
@@ -137,18 +142,21 @@ export class Motion {
|
|
|
137
142
|
* Parse the device status from the SwitchBot api
|
|
138
143
|
*/
|
|
139
144
|
async parseStatus(): Promise<void> {
|
|
140
|
-
if (this.
|
|
145
|
+
if (this.BLE) {
|
|
146
|
+
await this.BLEparseStatus();
|
|
147
|
+
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
141
148
|
await this.openAPIparseStatus();
|
|
142
149
|
} else {
|
|
143
|
-
|
|
150
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
151
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
144
152
|
}
|
|
145
153
|
}
|
|
146
154
|
|
|
147
155
|
async BLEparseStatus(): Promise<void> {
|
|
148
|
-
this.debugLog(
|
|
156
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
149
157
|
// Movement
|
|
150
158
|
this.MotionDetected = this.movement!;
|
|
151
|
-
this.debugLog(
|
|
159
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
152
160
|
// Light Level
|
|
153
161
|
if (!this.device.motion?.hide_lightsensor) {
|
|
154
162
|
this.set_minLux = this.minLux();
|
|
@@ -162,7 +170,7 @@ export class Motion {
|
|
|
162
170
|
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
163
171
|
}
|
|
164
172
|
this.debugLog(
|
|
165
|
-
|
|
173
|
+
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
|
|
166
174
|
` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
167
175
|
);
|
|
168
176
|
}
|
|
@@ -176,32 +184,28 @@ export class Motion {
|
|
|
176
184
|
} else {
|
|
177
185
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
178
186
|
}
|
|
179
|
-
this.debugLog(
|
|
187
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
188
|
+
+` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
180
189
|
}
|
|
181
190
|
|
|
182
191
|
async openAPIparseStatus(): Promise<void> {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
this.
|
|
190
|
-
this.
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
break;
|
|
199
|
-
case 'bright':
|
|
200
|
-
default:
|
|
201
|
-
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
202
|
-
}
|
|
203
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
192
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
193
|
+
// Motion State
|
|
194
|
+
this.MotionDetected = this.moveDetected!;
|
|
195
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
196
|
+
// Light Level
|
|
197
|
+
if (!this.device.motion?.hide_lightsensor) {
|
|
198
|
+
this.set_minLux = this.minLux();
|
|
199
|
+
this.set_maxLux = this.maxLux();
|
|
200
|
+
switch (this.brightness) {
|
|
201
|
+
case 'dim':
|
|
202
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
203
|
+
break;
|
|
204
|
+
case 'bright':
|
|
205
|
+
default:
|
|
206
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
204
207
|
}
|
|
208
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
211
|
|
|
@@ -209,15 +213,18 @@ export class Motion {
|
|
|
209
213
|
* Asks the SwitchBot API for the latest device information
|
|
210
214
|
*/
|
|
211
215
|
async refreshStatus(): Promise<void> {
|
|
212
|
-
if (this.
|
|
216
|
+
if (this.BLE) {
|
|
213
217
|
await this.BLERefreshStatus();
|
|
214
|
-
} else {
|
|
218
|
+
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
215
219
|
await this.openAPIRefreshStatus();
|
|
220
|
+
} else {
|
|
221
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
222
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
216
223
|
}
|
|
217
224
|
}
|
|
218
225
|
|
|
219
226
|
async BLERefreshStatus(): Promise<void> {
|
|
220
|
-
this.debugLog(
|
|
227
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
221
228
|
const switchbot = await this.platform.connectBLE();
|
|
222
229
|
// Convert to BLE Address
|
|
223
230
|
this.device.bleMac =
|
|
@@ -226,8 +233,7 @@ export class Motion {
|
|
|
226
233
|
.deviceId!.match(/.{1,2}/g)!
|
|
227
234
|
.join(':')
|
|
228
235
|
.toLowerCase();
|
|
229
|
-
this.debugLog(
|
|
230
|
-
|
|
236
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
231
237
|
this.getCustomBLEAddress(switchbot);
|
|
232
238
|
// Start to monitor advertisement packets
|
|
233
239
|
if (switchbot !== false) {
|
|
@@ -240,28 +246,24 @@ export class Motion {
|
|
|
240
246
|
// Set an event hander
|
|
241
247
|
switchbot.onadvertisement = (ad: any) => {
|
|
242
248
|
this.address = ad.address;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.infoLog(this.device.bleMac);
|
|
246
|
-
this.infoLog(`Motion Sensor: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
|
|
247
|
-
this.infoLog(`Motion Sensor: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
|
|
248
|
-
}
|
|
249
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
250
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
249
251
|
this.serviceData = ad.serviceData;
|
|
250
252
|
this.movement = ad.serviceData.movement;
|
|
251
253
|
this.battery = ad.serviceData.battery;
|
|
252
254
|
this.lightLevel = ad.serviceData.lightLevel;
|
|
253
|
-
this.debugLog(
|
|
255
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
|
|
254
256
|
this.debugLog(
|
|
255
|
-
|
|
257
|
+
`${this.device.deviceType}: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, lightLevel: ` +
|
|
256
258
|
`${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`,
|
|
257
259
|
);
|
|
258
260
|
|
|
259
261
|
if (this.serviceData) {
|
|
260
262
|
this.connected = true;
|
|
261
|
-
this.debugLog(
|
|
263
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
262
264
|
} else {
|
|
263
265
|
this.connected = false;
|
|
264
|
-
this.debugLog(
|
|
266
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
265
267
|
}
|
|
266
268
|
};
|
|
267
269
|
// Wait 10 seconds
|
|
@@ -271,116 +273,74 @@ export class Motion {
|
|
|
271
273
|
// Stop to monitor
|
|
272
274
|
switchbot.stopScan();
|
|
273
275
|
if (this.connected) {
|
|
274
|
-
this.
|
|
276
|
+
this.BLEparseStatus();
|
|
275
277
|
this.updateHomeKitCharacteristics();
|
|
276
278
|
} else {
|
|
277
|
-
await this.
|
|
279
|
+
await this.BLERefreshConnection(switchbot);
|
|
278
280
|
}
|
|
279
281
|
})
|
|
280
282
|
.catch(async (e: any) => {
|
|
281
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
282
|
-
if (this.deviceLogging.includes('debug')) {
|
|
283
|
-
this.errorLog(
|
|
284
|
-
`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` +
|
|
285
|
-
` Error Message: ${JSON.stringify(e.message)}`,
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
if (this.platform.config.credentials?.token) {
|
|
289
|
-
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
290
|
-
this.SwitchToOpenAPI = true;
|
|
291
|
-
await this.openAPIRefreshStatus();
|
|
292
|
-
}
|
|
293
283
|
this.apiError(e);
|
|
284
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
285
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
286
|
+
await this.BLERefreshConnection(switchbot);
|
|
294
287
|
});
|
|
295
288
|
} else {
|
|
296
|
-
await this.
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
301
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
302
|
-
(async () => {
|
|
303
|
-
// Start to monitor advertisement packets
|
|
304
|
-
await switchbot.startScan({
|
|
305
|
-
model: 's',
|
|
306
|
-
});
|
|
307
|
-
// Set an event handler
|
|
308
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
309
|
-
this.warnLog(`Motion Sensor: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
310
|
-
};
|
|
311
|
-
await switchbot.wait(10000);
|
|
312
|
-
// Stop to monitor
|
|
313
|
-
switchbot.stopScan();
|
|
314
|
-
})();
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
async BLEconnection(switchbot: any): Promise<void> {
|
|
319
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
320
|
-
if (this.platform.config.credentials?.token) {
|
|
321
|
-
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
322
|
-
this.SwitchToOpenAPI = true;
|
|
323
|
-
await this.openAPIRefreshStatus();
|
|
289
|
+
await this.BLERefreshConnection(switchbot);
|
|
324
290
|
}
|
|
325
291
|
}
|
|
326
292
|
|
|
327
293
|
async openAPIRefreshStatus(): Promise<void> {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
});
|
|
357
|
-
res.on('end', () => {
|
|
358
|
-
try {
|
|
359
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
360
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
361
|
-
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
362
|
-
this.brightness = this.deviceStatus.body.brightness;
|
|
363
|
-
this.parseStatus();
|
|
364
|
-
this.updateHomeKitCharacteristics();
|
|
365
|
-
} catch (e: any) {
|
|
366
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
|
|
367
|
-
}
|
|
368
|
-
});
|
|
294
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
295
|
+
try {
|
|
296
|
+
const t = Date.now();
|
|
297
|
+
const nonce = 'requestID';
|
|
298
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
299
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
300
|
+
const sign = signTerm.toString('base64');
|
|
301
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
302
|
+
const options = {
|
|
303
|
+
hostname: HostDomain,
|
|
304
|
+
port: 443,
|
|
305
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
306
|
+
method: 'GET',
|
|
307
|
+
headers: {
|
|
308
|
+
Authorization: this.platform.config.credentials?.token,
|
|
309
|
+
sign: sign,
|
|
310
|
+
nonce: nonce,
|
|
311
|
+
t: t,
|
|
312
|
+
'Content-Type': 'application/json',
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
const req = https.request(options, (res) => {
|
|
316
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
317
|
+
this.statusCode({ res });
|
|
318
|
+
let rawData = '';
|
|
319
|
+
res.on('data', (d) => {
|
|
320
|
+
rawData += d;
|
|
321
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
369
322
|
});
|
|
370
|
-
|
|
371
|
-
|
|
323
|
+
res.on('end', () => {
|
|
324
|
+
try {
|
|
325
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
326
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
327
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
328
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
329
|
+
this.openAPIparseStatus();
|
|
330
|
+
this.updateHomeKitCharacteristics();
|
|
331
|
+
} catch (e: any) {
|
|
332
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
333
|
+
}
|
|
372
334
|
});
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
this.errorLog(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
this.apiError(e);
|
|
383
|
-
}
|
|
335
|
+
});
|
|
336
|
+
req.on('error', (e: any) => {
|
|
337
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
338
|
+
});
|
|
339
|
+
req.end();
|
|
340
|
+
} catch (e: any) {
|
|
341
|
+
this.apiError(e);
|
|
342
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
343
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
384
344
|
}
|
|
385
345
|
}
|
|
386
346
|
|
|
@@ -389,115 +349,158 @@ export class Motion {
|
|
|
389
349
|
*/
|
|
390
350
|
async updateHomeKitCharacteristics(): Promise<void> {
|
|
391
351
|
if (this.MotionDetected === undefined) {
|
|
392
|
-
this.debugLog(
|
|
352
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
393
353
|
} else {
|
|
354
|
+
this.accessory.context.MotionDetected = this.MotionDetected;
|
|
394
355
|
this.motionSensorService.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
|
|
395
|
-
this.debugLog(
|
|
356
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
|
|
396
357
|
}
|
|
397
|
-
if (this.
|
|
358
|
+
if (this.BLE) {
|
|
398
359
|
if (this.BatteryLevel === undefined) {
|
|
399
|
-
this.debugLog(
|
|
360
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
400
361
|
} else {
|
|
362
|
+
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
401
363
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
402
|
-
this.debugLog(
|
|
364
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
403
365
|
}
|
|
404
366
|
if (this.StatusLowBattery === undefined) {
|
|
405
|
-
this.debugLog(
|
|
367
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
406
368
|
} else {
|
|
369
|
+
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
407
370
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
408
|
-
this.debugLog(
|
|
371
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
409
372
|
}
|
|
410
373
|
if (this.CurrentAmbientLightLevel === undefined) {
|
|
411
|
-
this.debugLog(
|
|
374
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
412
375
|
} else {
|
|
376
|
+
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
413
377
|
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
414
378
|
this.debugLog(
|
|
415
|
-
|
|
379
|
+
`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
380
|
+
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
416
381
|
);
|
|
417
382
|
}
|
|
418
383
|
}
|
|
419
384
|
}
|
|
420
385
|
|
|
421
|
-
async
|
|
422
|
-
this.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
386
|
+
async getCustomBLEAddress(switchbot: any) {
|
|
387
|
+
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
388
|
+
(async () => {
|
|
389
|
+
// Start to monitor advertisement packets
|
|
390
|
+
await switchbot.startScan({
|
|
391
|
+
model: 's',
|
|
392
|
+
});
|
|
393
|
+
// Set an event handler
|
|
394
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
395
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
|
|
396
|
+
};
|
|
397
|
+
await switchbot.wait(10000);
|
|
398
|
+
// Stop to monitor
|
|
399
|
+
switchbot.stopScan();
|
|
400
|
+
})();
|
|
427
401
|
}
|
|
428
|
-
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
429
402
|
}
|
|
430
403
|
|
|
431
|
-
async
|
|
432
|
-
|
|
433
|
-
if (device.
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
if (device.ble !== undefined) {
|
|
437
|
-
config['ble'] = device.ble;
|
|
438
|
-
}
|
|
439
|
-
if (device.logging !== undefined) {
|
|
440
|
-
config['logging'] = device.logging;
|
|
441
|
-
}
|
|
442
|
-
if (device.refreshRate !== undefined) {
|
|
443
|
-
config['refreshRate'] = device.refreshRate;
|
|
444
|
-
}
|
|
445
|
-
if (device.scanDuration !== undefined) {
|
|
446
|
-
config['scanDuration'] = device.scanDuration;
|
|
447
|
-
}
|
|
448
|
-
if (device.offline !== undefined) {
|
|
449
|
-
config['offline'] = device.offline;
|
|
404
|
+
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
405
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
406
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
407
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
|
|
408
|
+
await this.openAPIRefreshStatus();
|
|
450
409
|
}
|
|
451
|
-
|
|
452
|
-
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
minLux(): number {
|
|
413
|
+
if (this.device.motion?.set_minLux) {
|
|
414
|
+
this.set_minLux = this.device.motion!.set_minLux!;
|
|
415
|
+
} else {
|
|
416
|
+
this.set_minLux = 1;
|
|
453
417
|
}
|
|
418
|
+
return this.set_minLux;
|
|
454
419
|
}
|
|
455
420
|
|
|
456
|
-
|
|
457
|
-
if (device.
|
|
458
|
-
this.
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
462
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
421
|
+
maxLux(): number {
|
|
422
|
+
if (this.device.motion?.set_maxLux) {
|
|
423
|
+
this.set_maxLux = this.device.motion!.set_maxLux!;
|
|
424
|
+
} else {
|
|
425
|
+
this.set_maxLux = 6001;
|
|
463
426
|
}
|
|
427
|
+
return this.set_maxLux;
|
|
464
428
|
}
|
|
465
429
|
|
|
466
430
|
async scan(device: device & devicesConfig): Promise<void> {
|
|
467
431
|
if (device.scanDuration) {
|
|
468
432
|
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
469
|
-
if (
|
|
470
|
-
this.debugLog(
|
|
433
|
+
if (this.BLE) {
|
|
434
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
471
435
|
}
|
|
472
436
|
} else {
|
|
473
437
|
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
474
|
-
if (this.
|
|
475
|
-
this.debugLog(
|
|
438
|
+
if (this.BLE) {
|
|
439
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
476
440
|
}
|
|
477
441
|
}
|
|
478
442
|
}
|
|
479
443
|
|
|
480
|
-
async
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
444
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
445
|
+
switch (res.statusCode) {
|
|
446
|
+
case 151:
|
|
447
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
448
|
+
break;
|
|
449
|
+
case 152:
|
|
450
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
|
|
451
|
+
break;
|
|
452
|
+
case 160:
|
|
453
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
|
|
454
|
+
break;
|
|
455
|
+
case 161:
|
|
456
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
|
|
457
|
+
this.offlineOff();
|
|
458
|
+
break;
|
|
459
|
+
case 171:
|
|
460
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
|
|
461
|
+
this.offlineOff();
|
|
462
|
+
break;
|
|
463
|
+
case 190:
|
|
464
|
+
this.errorLog(
|
|
465
|
+
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
466
|
+
` Or command: ${superStringify(res)} format is invalid`,
|
|
467
|
+
);
|
|
468
|
+
break;
|
|
469
|
+
case 100:
|
|
470
|
+
if (this.platform.debugMode) {
|
|
471
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
|
|
472
|
+
}
|
|
473
|
+
break;
|
|
474
|
+
default:
|
|
475
|
+
if (this.platform.debugMode) {
|
|
476
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
async offlineOff(): Promise<void> {
|
|
482
|
+
if (this.device.offline) {
|
|
483
|
+
this.MotionDetected = false;
|
|
484
|
+
this.motionSensorService.getCharacteristic(this.platform.Characteristic.MotionDetected).updateValue(this.MotionDetected);
|
|
485
|
+
await this.updateHomeKitCharacteristics();
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
async apiError(e: any): Promise<void> {
|
|
490
|
+
this.motionSensorService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
|
|
491
|
+
if (this.BLE) {
|
|
492
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
493
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
494
|
+
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
|
|
493
495
|
}
|
|
494
496
|
}
|
|
495
497
|
|
|
496
498
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
497
499
|
let FirmwareRevision: string;
|
|
498
|
-
this.debugLog(
|
|
499
|
-
|
|
500
|
-
this.debugLog(
|
|
500
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
501
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
502
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
503
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
501
504
|
if (accessory.context.FirmwareRevision) {
|
|
502
505
|
FirmwareRevision = accessory.context.FirmwareRevision;
|
|
503
506
|
} else if (device.firmware) {
|
|
@@ -508,22 +511,66 @@ export class Motion {
|
|
|
508
511
|
return FirmwareRevision;
|
|
509
512
|
}
|
|
510
513
|
|
|
511
|
-
|
|
512
|
-
if (this.
|
|
513
|
-
this.
|
|
514
|
+
async context() {
|
|
515
|
+
if (this.MotionDetected === undefined) {
|
|
516
|
+
this.MotionDetected = false;
|
|
514
517
|
} else {
|
|
515
|
-
this.
|
|
518
|
+
this.MotionDetected = this.accessory.context.MotionDetected;
|
|
516
519
|
}
|
|
517
|
-
return this.set_minLux;
|
|
518
520
|
}
|
|
519
521
|
|
|
520
|
-
|
|
521
|
-
if (
|
|
522
|
-
this.
|
|
522
|
+
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
523
|
+
if (device.refreshRate) {
|
|
524
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
525
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
526
|
+
} else if (this.platform.config.options!.refreshRate) {
|
|
527
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
528
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
async config(device: device & devicesConfig): Promise<void> {
|
|
533
|
+
let config = {};
|
|
534
|
+
if (device.motion) {
|
|
535
|
+
config = device.motion;
|
|
536
|
+
}
|
|
537
|
+
if (device.connectionType !== undefined) {
|
|
538
|
+
config['connectionType'] = device.connectionType;
|
|
539
|
+
}
|
|
540
|
+
if (device.external !== undefined) {
|
|
541
|
+
config['external'] = device.external;
|
|
542
|
+
}
|
|
543
|
+
if (device.logging !== undefined) {
|
|
544
|
+
config['logging'] = device.logging;
|
|
545
|
+
}
|
|
546
|
+
if (device.refreshRate !== undefined) {
|
|
547
|
+
config['refreshRate'] = device.refreshRate;
|
|
548
|
+
}
|
|
549
|
+
if (device.scanDuration !== undefined) {
|
|
550
|
+
config['scanDuration'] = device.scanDuration;
|
|
551
|
+
}
|
|
552
|
+
if (device.offline !== undefined) {
|
|
553
|
+
config['offline'] = device.offline;
|
|
554
|
+
}
|
|
555
|
+
if (Object.entries(config).length !== 0) {
|
|
556
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
async logs(device: device & devicesConfig): Promise<void> {
|
|
561
|
+
if (this.platform.debugMode) {
|
|
562
|
+
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
563
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
564
|
+
} else if (device.logging) {
|
|
565
|
+
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
566
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
567
|
+
} else if (this.platform.config.options?.logging) {
|
|
568
|
+
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
569
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
523
570
|
} else {
|
|
524
|
-
this.
|
|
571
|
+
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
572
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
525
573
|
}
|
|
526
|
-
return this.set_maxLux;
|
|
527
574
|
}
|
|
528
575
|
|
|
529
576
|
/**
|
|
@@ -541,12 +588,28 @@ export class Motion {
|
|
|
541
588
|
}
|
|
542
589
|
}
|
|
543
590
|
|
|
591
|
+
debugWarnLog(...log: any[]): void {
|
|
592
|
+
if (this.enablingDeviceLogging()) {
|
|
593
|
+
if (this.deviceLogging?.includes('debug')) {
|
|
594
|
+
this.platform.log.warn('[DEBUG]', String(...log));
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
544
599
|
errorLog(...log: any[]): void {
|
|
545
600
|
if (this.enablingDeviceLogging()) {
|
|
546
601
|
this.platform.log.error(String(...log));
|
|
547
602
|
}
|
|
548
603
|
}
|
|
549
604
|
|
|
605
|
+
debugErrorLog(...log: any[]): void {
|
|
606
|
+
if (this.enablingDeviceLogging()) {
|
|
607
|
+
if (this.deviceLogging?.includes('debug')) {
|
|
608
|
+
this.platform.log.error('[DEBUG]', String(...log));
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
550
613
|
debugLog(...log: any[]): void {
|
|
551
614
|
if (this.enablingDeviceLogging()) {
|
|
552
615
|
if (this.deviceLogging === 'debug') {
|