@switchbot/homebridge-switchbot 1.7.1-beta.4 → 1.7.1-beta.8
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/config.schema.json +45 -32
- package/dist/devices/bots.d.ts +2 -2
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +10 -28
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +5 -1
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +12 -8
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.d.ts +4 -2
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +13 -34
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +5 -2
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +11 -6
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +7 -2
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +22 -35
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/meters.d.ts +12 -12
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +49 -100
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +3 -4
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +5 -27
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +2 -1
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +2 -1
- package/dist/devices/plugs.js.map +1 -1
- package/package.json +1 -1
- package/src/devices/bots.ts +12 -30
- package/src/devices/colorbulb.ts +17 -9
- package/src/devices/contact.ts +17 -35
- package/src/devices/curtains.ts +16 -8
- package/src/devices/humidifiers.ts +29 -36
- package/src/devices/meters.ts +63 -110
- package/src/devices/motion.ts +8 -30
- package/src/devices/plugs.ts +4 -2
package/src/devices/contact.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
2
2
|
import { skipWhile } from 'rxjs/operators';
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
|
|
5
|
+
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, deviceStatus } from '../settings';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Platform Accessory
|
|
@@ -24,6 +24,9 @@ export class Contact {
|
|
|
24
24
|
StatusLowBattery!: CharacteristicValue;
|
|
25
25
|
|
|
26
26
|
// OpenAPI others
|
|
27
|
+
openState: deviceStatus['openState'];
|
|
28
|
+
moveDetected: deviceStatus['moveDetected'];
|
|
29
|
+
brightness: deviceStatus['brightness'];
|
|
27
30
|
deviceStatus!: deviceStatusResponse;
|
|
28
31
|
|
|
29
32
|
// BLE Others
|
|
@@ -133,7 +136,7 @@ export class Contact {
|
|
|
133
136
|
this.debugLog(`Contact Sensor: ${accessory.displayName} Removing Battery Service`);
|
|
134
137
|
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
135
138
|
accessory.removeService(this.batteryService!);
|
|
136
|
-
} else if (!this.batteryService) {
|
|
139
|
+
} else if (device.ble && !this.batteryService) {
|
|
137
140
|
this.debugLog(`Contact Sensor: ${accessory.displayName} Add Battery Service`);
|
|
138
141
|
(this.batteryService =
|
|
139
142
|
this.accessory.getService(this.platform.Service.Battery) ||
|
|
@@ -287,27 +290,25 @@ export class Contact {
|
|
|
287
290
|
if (this.platform.config.credentials?.openToken) {
|
|
288
291
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
289
292
|
// Contact State
|
|
290
|
-
if (this.
|
|
293
|
+
if (this.openState === 'open') {
|
|
291
294
|
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
292
295
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
293
|
-
} else if (this.
|
|
296
|
+
} else if (this.openState === 'close') {
|
|
294
297
|
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
295
298
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
296
299
|
} else {
|
|
297
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.
|
|
300
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.openState}`);
|
|
298
301
|
}
|
|
299
302
|
// Motion State
|
|
300
303
|
if (!this.device.contact?.hide_motionsensor) {
|
|
301
|
-
|
|
302
|
-
this.MotionDetected = this.deviceStatus.body.moveDetected;
|
|
303
|
-
}
|
|
304
|
+
this.MotionDetected = this.moveDetected!;
|
|
304
305
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
305
306
|
}
|
|
306
307
|
// Light Level
|
|
307
308
|
if (!this.device.contact?.hide_lightsensor) {
|
|
308
309
|
this.set_minLux = this.minLux();
|
|
309
310
|
this.set_maxLux = this.maxLux();
|
|
310
|
-
switch (this.
|
|
311
|
+
switch (this.brightness) {
|
|
311
312
|
case 'dim':
|
|
312
313
|
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
313
314
|
break;
|
|
@@ -331,34 +332,12 @@ export class Contact {
|
|
|
331
332
|
}
|
|
332
333
|
}
|
|
333
334
|
|
|
334
|
-
public async connectBLE() {
|
|
335
|
-
let switchbot: any;
|
|
336
|
-
try {
|
|
337
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
338
|
-
const Switchbot = require('node-switchbot');
|
|
339
|
-
switchbot = new Switchbot();
|
|
340
|
-
// Convert to BLE Address
|
|
341
|
-
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
342
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
343
|
-
} catch (e: any) {
|
|
344
|
-
switchbot = false;
|
|
345
|
-
this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
|
|
346
|
-
if (this.deviceLogging === 'debug') {
|
|
347
|
-
this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
348
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
349
|
-
}
|
|
350
|
-
if (this.platform.debugMode) {
|
|
351
|
-
this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
352
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return switchbot;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
335
|
private async BLERefreshStatus() {
|
|
359
336
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE refreshStatus`);
|
|
360
|
-
|
|
361
|
-
|
|
337
|
+
const switchbot = await this.platform.connectBLE();
|
|
338
|
+
// Convert to BLE Address
|
|
339
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
340
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
362
341
|
// Start to monitor advertisement packets
|
|
363
342
|
if (switchbot !== false) {
|
|
364
343
|
switchbot.startScan({
|
|
@@ -436,6 +415,9 @@ export class Contact {
|
|
|
436
415
|
try {
|
|
437
416
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
438
417
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
418
|
+
this.openState = this.deviceStatus.body.openState;
|
|
419
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
420
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
439
421
|
this.parseStatus();
|
|
440
422
|
this.updateHomeKitCharacteristics();
|
|
441
423
|
} catch (e: any) {
|
package/src/devices/curtains.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
4
4
|
import { SwitchBotPlatform } from '../platform';
|
|
5
5
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
6
6
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
7
|
-
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, payload } from '../settings';
|
|
7
|
+
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, payload, deviceStatus } from '../settings';
|
|
8
8
|
|
|
9
9
|
export class Curtain {
|
|
10
10
|
// Services
|
|
@@ -22,17 +22,20 @@ export class Curtain {
|
|
|
22
22
|
|
|
23
23
|
// OpenAPI Others
|
|
24
24
|
deviceStatus!: deviceStatusResponse;
|
|
25
|
+
slidePosition: deviceStatus['slidePosition'];
|
|
26
|
+
moving: deviceStatus['moving'];
|
|
27
|
+
brightness: deviceStatus['brightness'];
|
|
25
28
|
|
|
26
29
|
// BLE Others
|
|
27
30
|
connected?: boolean;
|
|
28
31
|
switchbot!: switchbot;
|
|
29
32
|
SwitchToOpenAPI?: boolean;
|
|
30
33
|
serviceData!: serviceData;
|
|
34
|
+
spaceBetweenLevels!: number;
|
|
31
35
|
calibration: serviceData['calibration'];
|
|
32
36
|
battery: serviceData['battery'];
|
|
33
37
|
position: serviceData['position'];
|
|
34
38
|
lightLevel: serviceData['lightLevel'];
|
|
35
|
-
spaceBetweenLevels!: number;
|
|
36
39
|
|
|
37
40
|
// Target
|
|
38
41
|
setNewTarget!: boolean;
|
|
@@ -148,7 +151,7 @@ export class Curtain {
|
|
|
148
151
|
this.debugLog(`Curtain: ${accessory.displayName} Removing Battery Service`);
|
|
149
152
|
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
150
153
|
accessory.removeService(this.batteryService!);
|
|
151
|
-
} else if (!this.batteryService) {
|
|
154
|
+
} else if (device.ble && !this.batteryService) {
|
|
152
155
|
this.debugLog(`Curtain: ${accessory.displayName} Add Battery Service`);
|
|
153
156
|
(this.batteryService =
|
|
154
157
|
this.accessory.getService(this.platform.Service.Battery) ||
|
|
@@ -311,6 +314,7 @@ export class Curtain {
|
|
|
311
314
|
|
|
312
315
|
private async BLEparseStatus() {
|
|
313
316
|
this.debugLog(`Curtain: ${this.accessory.displayName} BLE parseStatus`);
|
|
317
|
+
// CurrentPosition
|
|
314
318
|
this.setMinMax();
|
|
315
319
|
this.CurrentPosition = 100 - Number(this.position);
|
|
316
320
|
this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
|
|
@@ -336,6 +340,7 @@ export class Curtain {
|
|
|
336
340
|
// If Curtain calibration distance is short, there will be an error between the current percentage and the target percentage.
|
|
337
341
|
this.TargetPosition = this.CurrentPosition;
|
|
338
342
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
343
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} Stopped`);
|
|
339
344
|
}
|
|
340
345
|
}
|
|
341
346
|
this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},`
|
|
@@ -411,13 +416,13 @@ export class Curtain {
|
|
|
411
416
|
this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
412
417
|
// CurrentPosition
|
|
413
418
|
this.setMinMax();
|
|
414
|
-
this.CurrentPosition = 100 - this.
|
|
419
|
+
this.CurrentPosition = 100 - Number(this.slidePosition);
|
|
415
420
|
this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
416
421
|
if (this.setNewTarget) {
|
|
417
|
-
this.infoLog(`
|
|
422
|
+
this.infoLog(`Curtain: ${this.accessory.displayName} Checking Status ...`);
|
|
418
423
|
}
|
|
419
424
|
|
|
420
|
-
if (this.
|
|
425
|
+
if (this.setNewTarget && this.moving) {
|
|
421
426
|
this.setMinMax();
|
|
422
427
|
if (this.TargetPosition > this.CurrentPosition) {
|
|
423
428
|
this.debugLog(`Curtain: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
|
|
@@ -435,6 +440,7 @@ export class Curtain {
|
|
|
435
440
|
/*If Curtain calibration distance is short, there will be an error between the current percentage and the target percentage.*/
|
|
436
441
|
this.TargetPosition = this.CurrentPosition;
|
|
437
442
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
443
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} Stopped`);
|
|
438
444
|
}
|
|
439
445
|
}
|
|
440
446
|
this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},`
|
|
@@ -444,7 +450,7 @@ export class Curtain {
|
|
|
444
450
|
this.set_minLux = this.minLux();
|
|
445
451
|
this.set_maxLux = this.maxLux();
|
|
446
452
|
// Brightness
|
|
447
|
-
switch (this.
|
|
453
|
+
switch (this.brightness) {
|
|
448
454
|
case 'dim':
|
|
449
455
|
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
450
456
|
break;
|
|
@@ -467,7 +473,6 @@ export class Curtain {
|
|
|
467
473
|
|
|
468
474
|
private async BLERefreshStatus() {
|
|
469
475
|
this.debugLog(`Curtain: ${this.accessory.displayName} BLE refreshStatus`);
|
|
470
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
471
476
|
const switchbot = await this.platform.connectBLE();
|
|
472
477
|
// Convert to BLE Address
|
|
473
478
|
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
@@ -550,6 +555,9 @@ export class Curtain {
|
|
|
550
555
|
try {
|
|
551
556
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
552
557
|
this.debugLog(`Curtain: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
558
|
+
this.slidePosition = this.deviceStatus.body.slidePosition;
|
|
559
|
+
this.moving = this.deviceStatus.body.moving;
|
|
560
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
553
561
|
this.parseStatus();
|
|
554
562
|
this.updateHomeKitCharacteristics();
|
|
555
563
|
} catch (e: any) {
|
|
@@ -3,7 +3,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
5
5
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
6
|
-
import { DeviceURL, device, devicesConfig, serviceData, ad, deviceStatusResponse, payload } from '../settings';
|
|
6
|
+
import { DeviceURL, device, devicesConfig, serviceData, ad, deviceStatusResponse, payload, deviceStatus } from '../settings';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Platform Accessory
|
|
@@ -25,6 +25,12 @@ export class Humidifier {
|
|
|
25
25
|
WaterLevel!: CharacteristicValue;
|
|
26
26
|
|
|
27
27
|
// OpenAPI
|
|
28
|
+
auto: deviceStatus['auto'];
|
|
29
|
+
power: deviceStatus['power'];
|
|
30
|
+
humidity: deviceStatus['humidity'];
|
|
31
|
+
lackWater: deviceStatus['lackWater'];
|
|
32
|
+
temperature: deviceStatus['temperature'];
|
|
33
|
+
nebulizationEfficiency: deviceStatus['nebulizationEfficiency'];
|
|
28
34
|
deviceStatus!: deviceStatusResponse;
|
|
29
35
|
|
|
30
36
|
// BLE Others
|
|
@@ -276,15 +282,15 @@ export class Humidifier {
|
|
|
276
282
|
if (this.platform.config.credentials?.openToken) {
|
|
277
283
|
this.debugLog(`Humidifier: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
278
284
|
// Current Relative Humidity
|
|
279
|
-
this.CurrentRelativeHumidity = this.
|
|
285
|
+
this.CurrentRelativeHumidity = this.humidity!;
|
|
280
286
|
this.debugLog(`Humidifier: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
281
287
|
// Current Temperature
|
|
282
288
|
if (!this.device.humidifier?.hide_temperature) {
|
|
283
|
-
this.CurrentTemperature =
|
|
289
|
+
this.CurrentTemperature = this.temperature!;
|
|
284
290
|
this.debugLog(`Humidifier: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
|
|
285
291
|
}
|
|
286
292
|
// Target Humidifier Dehumidifier State
|
|
287
|
-
switch (this.
|
|
293
|
+
switch (this.auto) {
|
|
288
294
|
case true:
|
|
289
295
|
this.TargetHumidifierDehumidifierState = this.platform.Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER_OR_DEHUMIDIFIER;
|
|
290
296
|
this.CurrentHumidifierDehumidifierState = this.platform.Characteristic.CurrentHumidifierDehumidifierState.HUMIDIFYING;
|
|
@@ -292,10 +298,10 @@ export class Humidifier {
|
|
|
292
298
|
break;
|
|
293
299
|
default:
|
|
294
300
|
this.TargetHumidifierDehumidifierState = this.platform.Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER;
|
|
295
|
-
if (this.
|
|
301
|
+
if (this.nebulizationEfficiency! > 100) {
|
|
296
302
|
this.RelativeHumidityHumidifierThreshold = 100;
|
|
297
303
|
} else {
|
|
298
|
-
this.RelativeHumidityHumidifierThreshold = this.
|
|
304
|
+
this.RelativeHumidityHumidifierThreshold = this.nebulizationEfficiency!;
|
|
299
305
|
}
|
|
300
306
|
if (this.CurrentRelativeHumidity > this.RelativeHumidityHumidifierThreshold) {
|
|
301
307
|
this.CurrentHumidifierDehumidifierState = this.platform.Characteristic.CurrentHumidifierDehumidifierState.IDLE;
|
|
@@ -310,7 +316,7 @@ export class Humidifier {
|
|
|
310
316
|
+ ` RelativeHumidityHumidifierThreshold: ${this.RelativeHumidityHumidifierThreshold}`);
|
|
311
317
|
this.debugLog(`Humidifier: ${this.accessory.displayName} CurrentHumidifierDehumidifierState: ${this.CurrentHumidifierDehumidifierState}`);
|
|
312
318
|
// Active
|
|
313
|
-
switch (this.
|
|
319
|
+
switch (this.power) {
|
|
314
320
|
case 'on':
|
|
315
321
|
this.Active = this.platform.Characteristic.Active.ACTIVE;
|
|
316
322
|
break;
|
|
@@ -319,7 +325,7 @@ export class Humidifier {
|
|
|
319
325
|
}
|
|
320
326
|
this.debugLog(`Humidifier: ${this.accessory.displayName} Active: ${this.Active}`);
|
|
321
327
|
// Water Level
|
|
322
|
-
if (this.
|
|
328
|
+
if (this.lackWater) {
|
|
323
329
|
this.WaterLevel = 0;
|
|
324
330
|
} else {
|
|
325
331
|
this.WaterLevel = 100;
|
|
@@ -339,34 +345,12 @@ export class Humidifier {
|
|
|
339
345
|
}
|
|
340
346
|
}
|
|
341
347
|
|
|
342
|
-
public async connectBLE() {
|
|
343
|
-
let switchbot: any;
|
|
344
|
-
try {
|
|
345
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
346
|
-
const Switchbot = require('node-switchbot');
|
|
347
|
-
switchbot = new Switchbot();
|
|
348
|
-
// Convert to BLE Address
|
|
349
|
-
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
350
|
-
this.debugLog(`Humidifier: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
351
|
-
} catch (e: any) {
|
|
352
|
-
switchbot = false;
|
|
353
|
-
this.errorLog(`Humidifier: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
|
|
354
|
-
if (this.deviceLogging === 'debug') {
|
|
355
|
-
this.errorLog(`Humidifier: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
356
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
357
|
-
}
|
|
358
|
-
if (this.platform.debugMode) {
|
|
359
|
-
this.errorLog(`Humidifier: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
360
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
return switchbot;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
348
|
private async BLERefreshStatus() {
|
|
367
349
|
this.debugLog(`Humidifier: ${this.accessory.displayName} BLE refreshStatus`);
|
|
368
|
-
|
|
369
|
-
|
|
350
|
+
const switchbot = await this.platform.connectBLE();
|
|
351
|
+
// Convert to BLE Address
|
|
352
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
353
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
370
354
|
// Start to monitor advertisement packets
|
|
371
355
|
if (switchbot !== false) {
|
|
372
356
|
switchbot.startScan({
|
|
@@ -438,10 +422,16 @@ export class Humidifier {
|
|
|
438
422
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
439
423
|
if (this.deviceStatus.message === 'success') {
|
|
440
424
|
this.debugLog(`Humidifier: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
425
|
+
this.auto = this.deviceStatus.body.auto;
|
|
426
|
+
this.power = this.deviceStatus.body.power;
|
|
427
|
+
this.lackWater = this.deviceStatus.body.lackWater;
|
|
428
|
+
this.humidity = this.deviceStatus.body.humidity;
|
|
429
|
+
this.temperature = this.deviceStatus.body.temperature;
|
|
430
|
+
this.nebulizationEfficiency = this.deviceStatus.body.nebulizationEfficiency;
|
|
441
431
|
this.parseStatus();
|
|
442
432
|
this.updateHomeKitCharacteristics();
|
|
443
433
|
} else {
|
|
444
|
-
this.
|
|
434
|
+
this.errorLog(`Humidifier: ${this.accessory.displayName} message: ${JSON.stringify(this.deviceStatus.message)}`);
|
|
445
435
|
}
|
|
446
436
|
} catch (e: any) {
|
|
447
437
|
this.errorLog(`Humidifier: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
@@ -477,7 +467,10 @@ export class Humidifier {
|
|
|
477
467
|
|
|
478
468
|
private async BLEpushChanges() {
|
|
479
469
|
this.debugLog(`Humidifier: ${this.accessory.displayName} BLE pushChanges`);
|
|
480
|
-
const switchbot = await this.connectBLE();
|
|
470
|
+
const switchbot = await this.platform.connectBLE();
|
|
471
|
+
// Convert to BLE Address
|
|
472
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
473
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
481
474
|
if (switchbot !== false) {
|
|
482
475
|
switchbot.discover({ model: 'e', quick: true, id: this.device.bleMac }).then((device_list) => {
|
|
483
476
|
this.infoLog(`${this.accessory.displayName} Target Position: ${this.Active}`);
|
package/src/devices/meters.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
2
2
|
import { skipWhile } from 'rxjs/operators';
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature } from '../settings';
|
|
5
|
+
import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature, deviceStatus } from '../settings';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Platform Accessory
|
|
@@ -11,23 +11,24 @@ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceSta
|
|
|
11
11
|
*/
|
|
12
12
|
export class Meter {
|
|
13
13
|
// Services
|
|
14
|
-
private
|
|
15
|
-
temperatureservice?: Service;
|
|
16
|
-
humidityservice?: Service;
|
|
14
|
+
private batteryService?: Service;
|
|
15
|
+
private temperatureservice?: Service;
|
|
16
|
+
private humidityservice?: Service;
|
|
17
17
|
|
|
18
18
|
// Characteristic Values
|
|
19
19
|
CurrentRelativeHumidity!: CharacteristicValue;
|
|
20
20
|
CurrentRelativeHumidityCached!: CharacteristicValue;
|
|
21
|
-
CurrentTemperature
|
|
22
|
-
CurrentTemperatureCached
|
|
23
|
-
BatteryLevel
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
StatusLowBattery!: CharacteristicValue;
|
|
21
|
+
CurrentTemperature?: CharacteristicValue;
|
|
22
|
+
CurrentTemperatureCached?: CharacteristicValue;
|
|
23
|
+
BatteryLevel?: CharacteristicValue;
|
|
24
|
+
ChargingState?: CharacteristicValue;
|
|
25
|
+
StatusLowBattery?: CharacteristicValue;
|
|
27
26
|
Active!: CharacteristicValue;
|
|
28
27
|
WaterLevel!: CharacteristicValue;
|
|
29
28
|
|
|
30
29
|
// OpenAPI Others
|
|
30
|
+
Temperature: deviceStatus['temperature'];
|
|
31
|
+
Humidity: deviceStatus['humidity'];
|
|
31
32
|
deviceStatus!: deviceStatusResponse;
|
|
32
33
|
|
|
33
34
|
// BLE Others
|
|
@@ -57,17 +58,6 @@ export class Meter {
|
|
|
57
58
|
this.logs();
|
|
58
59
|
this.scan();
|
|
59
60
|
this.refreshRate();
|
|
60
|
-
if (this.BatteryLevel === undefined) {
|
|
61
|
-
this.BatteryLevel = 100;
|
|
62
|
-
} else {
|
|
63
|
-
this.BatteryLevel = this.accessory.context.BatteryLevel;
|
|
64
|
-
}
|
|
65
|
-
if (this.BatteryLevel < 15) {
|
|
66
|
-
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
67
|
-
} else {
|
|
68
|
-
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
69
|
-
}
|
|
70
|
-
this.ChargingState = this.platform.Characteristic.ChargingState.NOT_CHARGEABLE;
|
|
71
61
|
if (this.CurrentRelativeHumidity === undefined) {
|
|
72
62
|
this.CurrentRelativeHumidity = 0;
|
|
73
63
|
} else {
|
|
@@ -97,26 +87,6 @@ export class Meter {
|
|
|
97
87
|
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-METERTH-S1')
|
|
98
88
|
.setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
|
|
99
89
|
|
|
100
|
-
// get the Battery service if it exists, otherwise create a new Battery service
|
|
101
|
-
// you can create multiple services for each accessory
|
|
102
|
-
(this.service =
|
|
103
|
-
accessory.getService(this.platform.Service.Battery) ||
|
|
104
|
-
accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
105
|
-
|
|
106
|
-
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
107
|
-
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
108
|
-
// accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Battery, 'NAME', 'USER_DEFINED_SUBTYPE');
|
|
109
|
-
|
|
110
|
-
// set the service name, this is what is displayed as the default name on the Home app
|
|
111
|
-
// in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
|
|
112
|
-
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
|
|
113
|
-
|
|
114
|
-
// each service must implement at-minimum the "required characteristics" for the given service type
|
|
115
|
-
// see https://developers.homebridge.io/#/service/Battery
|
|
116
|
-
|
|
117
|
-
// create handlers for required characteristics
|
|
118
|
-
this.service.setCharacteristic(this.platform.Characteristic.ChargingState, 2);
|
|
119
|
-
|
|
120
90
|
// Temperature Sensor Service
|
|
121
91
|
if (device.meter?.hide_temperature) {
|
|
122
92
|
this.debugLog(`Meter: ${accessory.displayName} Removing Temperature Sensor Service`);
|
|
@@ -128,7 +98,7 @@ export class Meter {
|
|
|
128
98
|
this.accessory.getService(this.platform.Service.TemperatureSensor) ||
|
|
129
99
|
this.accessory.addService(this.platform.Service.TemperatureSensor)), `${accessory.displayName} Temperature Sensor`;
|
|
130
100
|
|
|
131
|
-
this.
|
|
101
|
+
this.temperatureservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
|
|
132
102
|
|
|
133
103
|
this.temperatureservice
|
|
134
104
|
.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
@@ -140,7 +110,7 @@ export class Meter {
|
|
|
140
110
|
minStep: 0.1,
|
|
141
111
|
})
|
|
142
112
|
.onGet(() => {
|
|
143
|
-
return this.CurrentTemperature
|
|
113
|
+
return this.CurrentTemperature!;
|
|
144
114
|
});
|
|
145
115
|
} else {
|
|
146
116
|
this.debugLog(`Meter: ${accessory.displayName} Temperature Sensor Service Not Added`);
|
|
@@ -157,7 +127,7 @@ export class Meter {
|
|
|
157
127
|
this.accessory.getService(this.platform.Service.HumiditySensor) ||
|
|
158
128
|
this.accessory.addService(this.platform.Service.HumiditySensor)), `${accessory.displayName} Humidity Sensor`;
|
|
159
129
|
|
|
160
|
-
this.
|
|
130
|
+
this.humidityservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
|
|
161
131
|
|
|
162
132
|
this.humidityservice
|
|
163
133
|
.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
|
|
@@ -171,6 +141,27 @@ export class Meter {
|
|
|
171
141
|
this.debugLog(`Meter: ${accessory.displayName} Humidity Sensor Service Not Added`);
|
|
172
142
|
}
|
|
173
143
|
|
|
144
|
+
// Battery Service
|
|
145
|
+
if (!device.ble) {
|
|
146
|
+
this.debugLog(`Meter: ${accessory.displayName} Removing Battery Service`);
|
|
147
|
+
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
148
|
+
accessory.removeService(this.batteryService!);
|
|
149
|
+
} else if (device.ble && !this.batteryService) {
|
|
150
|
+
this.debugLog(`Meter: ${accessory.displayName} Add Battery Service`);
|
|
151
|
+
(this.batteryService =
|
|
152
|
+
this.accessory.getService(this.platform.Service.Battery) ||
|
|
153
|
+
this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
154
|
+
|
|
155
|
+
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
156
|
+
|
|
157
|
+
this.batteryService.setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
158
|
+
|
|
159
|
+
} else {
|
|
160
|
+
this.debugLog(`Meter: ${accessory.displayName} Battery Service Not Added`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
174
165
|
// Retrieve initial values and updateHomekit
|
|
175
166
|
this.updateHomeKitCharacteristics();
|
|
176
167
|
|
|
@@ -252,9 +243,9 @@ export class Meter {
|
|
|
252
243
|
}
|
|
253
244
|
this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
254
245
|
|
|
246
|
+
// Humidity
|
|
255
247
|
if (!this.device.meter?.hide_humidity) {
|
|
256
|
-
|
|
257
|
-
this.CurrentRelativeHumidity = Number(this.humidity);
|
|
248
|
+
this.CurrentRelativeHumidity = this.humidity!;
|
|
258
249
|
this.debugLog(`Meter: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
259
250
|
}
|
|
260
251
|
|
|
@@ -272,25 +263,15 @@ export class Meter {
|
|
|
272
263
|
}
|
|
273
264
|
if (this.platform.config.credentials?.openToken) {
|
|
274
265
|
this.debugLog(`Meter: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
275
|
-
if (this.deviceStatus.body) {
|
|
276
|
-
this.BatteryLevel = 100;
|
|
277
|
-
} else {
|
|
278
|
-
this.BatteryLevel = 10;
|
|
279
|
-
}
|
|
280
|
-
if (this.BatteryLevel < 15) {
|
|
281
|
-
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
282
|
-
} else {
|
|
283
|
-
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
284
|
-
}
|
|
285
266
|
// Current Relative Humidity
|
|
286
267
|
if (!this.device.meter?.hide_humidity) {
|
|
287
|
-
this.CurrentRelativeHumidity = this.
|
|
268
|
+
this.CurrentRelativeHumidity = this.Humidity!;
|
|
288
269
|
this.debugLog(`Meter: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
289
270
|
}
|
|
290
271
|
|
|
291
272
|
// Current Temperature
|
|
292
273
|
if (!this.device.meter?.hide_temperature) {
|
|
293
|
-
this.CurrentTemperature =
|
|
274
|
+
this.CurrentTemperature = this.Temperature!;
|
|
294
275
|
this.debugLog(`Meter: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
|
|
295
276
|
}
|
|
296
277
|
}
|
|
@@ -307,34 +288,12 @@ export class Meter {
|
|
|
307
288
|
}
|
|
308
289
|
}
|
|
309
290
|
|
|
310
|
-
private async connectBLE() {
|
|
311
|
-
let switchbot: any;
|
|
312
|
-
try {
|
|
313
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
314
|
-
const Switchbot = require('node-switchbot');
|
|
315
|
-
switchbot = new Switchbot();
|
|
316
|
-
// Convert to BLE Address
|
|
317
|
-
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
318
|
-
this.debugLog(`Meter: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
319
|
-
} catch (e: any) {
|
|
320
|
-
switchbot = false;
|
|
321
|
-
this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
|
|
322
|
-
if (this.deviceLogging === 'debug') {
|
|
323
|
-
this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
324
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
325
|
-
}
|
|
326
|
-
if (this.platform.debugMode) {
|
|
327
|
-
this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
328
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return switchbot;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
291
|
private async BLErefreshStatus() {
|
|
335
292
|
this.debugLog(`Meter: ${this.accessory.displayName} BLE RefreshStatus`);
|
|
336
|
-
|
|
337
|
-
|
|
293
|
+
const switchbot = await this.platform.connectBLE();
|
|
294
|
+
// Convert to BLE Address
|
|
295
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
296
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
338
297
|
// Start to monitor advertisement packets
|
|
339
298
|
if (switchbot !== false) {
|
|
340
299
|
switchbot.startScan({
|
|
@@ -366,12 +325,6 @@ export class Meter {
|
|
|
366
325
|
// Stop to monitor
|
|
367
326
|
switchbot.stopScan();
|
|
368
327
|
if (this.connected) {
|
|
369
|
-
this.CurrentTemperatureCached = this.temperature;
|
|
370
|
-
this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
|
|
371
|
-
this.CurrentRelativeHumidityCached = this.humidity!;
|
|
372
|
-
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
|
|
373
|
-
this.BatteryLevelCached = this.battery!;
|
|
374
|
-
this.accessory.context.BatteryLevel = this.BatteryLevelCached;
|
|
375
328
|
this.parseStatus();
|
|
376
329
|
this.updateHomeKitCharacteristics();
|
|
377
330
|
} else {
|
|
@@ -414,12 +367,8 @@ export class Meter {
|
|
|
414
367
|
try {
|
|
415
368
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
416
369
|
this.debugLog(`Meter: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
417
|
-
this.
|
|
418
|
-
this.
|
|
419
|
-
this.CurrentRelativeHumidityCached = this.deviceStatus.body.humidity!;
|
|
420
|
-
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
|
|
421
|
-
this.BatteryLevelCached = 100;
|
|
422
|
-
this.accessory.context.BatteryLevel = this.BatteryLevelCached;
|
|
370
|
+
this.Humidity = this.deviceStatus.body.humidity!;
|
|
371
|
+
this.Temperature = this.deviceStatus.body.temperature!;
|
|
423
372
|
this.parseStatus();
|
|
424
373
|
this.updateHomeKitCharacteristics();
|
|
425
374
|
} catch (e: any) {
|
|
@@ -441,18 +390,6 @@ export class Meter {
|
|
|
441
390
|
* Updates the status for each of the HomeKit Characteristics
|
|
442
391
|
*/
|
|
443
392
|
updateHomeKitCharacteristics() {
|
|
444
|
-
if (this.StatusLowBattery === undefined) {
|
|
445
|
-
this.debugLog(`Meter: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
446
|
-
} else {
|
|
447
|
-
this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
448
|
-
this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
449
|
-
}
|
|
450
|
-
if (this.BatteryLevel === undefined) {
|
|
451
|
-
this.debugLog(`Meter: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
452
|
-
} else {
|
|
453
|
-
this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
454
|
-
this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
455
|
-
}
|
|
456
393
|
if (!this.device.meter?.hide_humidity) {
|
|
457
394
|
if (this.CurrentRelativeHumidity === undefined) {
|
|
458
395
|
this.debugLog(`Meter: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
@@ -469,17 +406,33 @@ export class Meter {
|
|
|
469
406
|
this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
|
|
470
407
|
}
|
|
471
408
|
}
|
|
409
|
+
if (this.device.ble) {
|
|
410
|
+
if (this.BatteryLevel === undefined) {
|
|
411
|
+
this.debugLog(`Bot: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
412
|
+
} else {
|
|
413
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
414
|
+
this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
415
|
+
}
|
|
416
|
+
if (this.StatusLowBattery === undefined) {
|
|
417
|
+
this.debugLog(`Bot: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
418
|
+
} else {
|
|
419
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
420
|
+
this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
472
423
|
}
|
|
473
424
|
|
|
474
425
|
public apiError(e: any) {
|
|
475
|
-
this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
476
|
-
this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
477
426
|
if (!this.device.meter?.hide_humidity) {
|
|
478
427
|
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, e);
|
|
479
428
|
}
|
|
480
429
|
if (!this.device.meter?.hide_temperature) {
|
|
481
430
|
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
|
|
482
431
|
}
|
|
432
|
+
if (this.device.ble) {
|
|
433
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
434
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
435
|
+
}
|
|
483
436
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
484
437
|
}
|
|
485
438
|
|