@switchbot/homebridge-switchbot 3.5.0-beta.23 → 3.5.0-beta.24
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 +23 -2
- package/dist/device/blindtilt.d.ts +21 -98
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +332 -785
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +25 -75
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +566 -778
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +13 -71
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +168 -606
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +13 -78
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +218 -655
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +14 -69
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +196 -553
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +17 -90
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +324 -810
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +58 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +629 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/hub.d.ts +15 -63
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +223 -610
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +10 -69
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +192 -595
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +11 -68
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +156 -599
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +10 -72
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +204 -591
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +15 -66
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +199 -566
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +13 -67
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +152 -592
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +13 -68
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +151 -599
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +13 -73
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +129 -540
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +9 -61
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +71 -476
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +11 -66
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +122 -471
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +9 -66
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +105 -478
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +5 -36
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +228 -337
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +5 -34
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +19 -267
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +5 -34
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +13 -261
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +5 -34
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +13 -260
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +39 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -0
- package/dist/irdevice/irdevice.js +502 -0
- package/dist/irdevice/irdevice.js.map +1 -0
- package/dist/irdevice/light.d.ts +5 -34
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +13 -267
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +18 -48
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +349 -551
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +7 -40
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +79 -325
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +6 -36
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +38 -288
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +6 -36
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +39 -291
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/settings.d.ts +15 -2
- package/dist/settings.d.ts.map +1 -1
- package/dist/utils.d.ts +68 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +71 -0
- package/dist/utils.js.map +1 -1
- package/package.json +8 -8
- package/src/device/blindtilt.ts +356 -809
- package/src/device/bot.ts +601 -865
- package/src/device/ceilinglight.ts +182 -628
- package/src/device/colorbulb.ts +235 -683
- package/src/device/contact.ts +220 -575
- package/src/device/curtain.ts +344 -836
- package/src/device/device.ts +655 -0
- package/src/device/hub.ts +246 -636
- package/src/device/humidifier.ts +224 -645
- package/src/device/iosensor.ts +181 -625
- package/src/device/lightstrip.ts +230 -622
- package/src/device/lock.ts +236 -607
- package/src/device/meter.ts +177 -616
- package/src/device/meterplus.ts +175 -624
- package/src/device/motion.ts +147 -563
- package/src/device/plug.ts +81 -505
- package/src/device/robotvacuumcleaner.ts +139 -494
- package/src/device/waterdetector.ts +126 -506
- package/src/irdevice/airconditioner.ts +228 -353
- package/src/irdevice/airpurifier.ts +23 -282
- package/src/irdevice/camera.ts +18 -277
- package/src/irdevice/fan.ts +18 -275
- package/src/irdevice/irdevice.ts +518 -0
- package/src/irdevice/light.ts +18 -283
- package/src/irdevice/other.ts +394 -621
- package/src/irdevice/tv.ts +97 -344
- package/src/irdevice/vacuumcleaner.ts +46 -310
- package/src/irdevice/waterheater.ts +47 -315
- package/src/settings.ts +20 -3
- package/src/utils.ts +71 -0
package/src/device/meter.ts
CHANGED
|
@@ -1,114 +1,84 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
1
|
+
/* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* meter.ts: @switchbot/homebridge-switchbot.
|
|
4
|
+
*/
|
|
5
|
+
import { deviceBase } from './device.js';
|
|
6
6
|
import { SwitchBotPlatform } from '../platform.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
public readonly log: Logging;
|
|
13
|
-
public readonly config!: SwitchBotPlatformConfig;
|
|
14
|
-
protected readonly hap: HAP;
|
|
7
|
+
import { Subject, interval, skipWhile } from 'rxjs';
|
|
8
|
+
import { CharacteristicValue, PlatformAccessory, Service, Units } from 'homebridge';
|
|
9
|
+
import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
|
|
10
|
+
|
|
11
|
+
export class Meter extends deviceBase {
|
|
15
12
|
// Services
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
BLE_Fahrenheit!: temperature['f'];
|
|
36
|
-
BLE_BatteryLevel!: serviceData['battery'];
|
|
37
|
-
BLE_CurrentTemperature!: serviceData['temperature'];
|
|
38
|
-
BLE_CurrentRelativeHumidity!: serviceData['humidity'];
|
|
39
|
-
|
|
40
|
-
// BLE Others
|
|
41
|
-
BLE_IsConnected?: boolean;
|
|
42
|
-
|
|
43
|
-
//MQTT stuff
|
|
44
|
-
mqttClient: MqttClient | null = null;
|
|
45
|
-
|
|
46
|
-
// EVE history service handler
|
|
47
|
-
historyService?: any;
|
|
48
|
-
|
|
49
|
-
// Config
|
|
50
|
-
scanDuration!: number;
|
|
51
|
-
deviceLogging!: string;
|
|
52
|
-
deviceRefreshRate!: number;
|
|
53
|
-
maxRetries!: number;
|
|
54
|
-
delayBetweenRetries!: number;
|
|
55
|
-
|
|
56
|
-
// Connection
|
|
57
|
-
private readonly OpenAPI: boolean;
|
|
58
|
-
private readonly BLE: boolean;
|
|
13
|
+
private Battery!: {
|
|
14
|
+
Service: Service;
|
|
15
|
+
BatteryLevel: CharacteristicValue;
|
|
16
|
+
StatusLowBattery: CharacteristicValue;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
private HumiditySensor?: {
|
|
20
|
+
Service: Service;
|
|
21
|
+
CurrentRelativeHumidity: CharacteristicValue;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
private TemperatureSensor?: {
|
|
25
|
+
Service: Service;
|
|
26
|
+
CurrentTemperature: CharacteristicValue;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// Updates
|
|
30
|
+
meterUpdateInProgress!: boolean;
|
|
31
|
+
doMeterUpdate: Subject<void>;
|
|
59
32
|
|
|
60
33
|
constructor(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
34
|
+
readonly platform: SwitchBotPlatform,
|
|
35
|
+
accessory: PlatformAccessory,
|
|
36
|
+
device: device & devicesConfig,
|
|
64
37
|
) {
|
|
65
|
-
|
|
66
|
-
this
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
69
|
-
// Connection
|
|
70
|
-
this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
|
|
71
|
-
this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
|
|
72
|
-
// default placeholders
|
|
73
|
-
this.deviceLogs(device);
|
|
74
|
-
this.scan(device);
|
|
75
|
-
this.refreshRate(device);
|
|
76
|
-
this.deviceContext();
|
|
77
|
-
this.setupHistoryService(device);
|
|
78
|
-
this.setupMqtt(device);
|
|
79
|
-
this.deviceRetry(device);
|
|
80
|
-
this.deviceConfig(device);
|
|
81
|
-
|
|
82
|
-
this.CurrentRelativeHumidity = accessory.context.CurrentRelativeHumidity;
|
|
83
|
-
this.CurrentTemperature = accessory.context.CurrentTemperature;
|
|
38
|
+
super(platform, accessory, device);
|
|
39
|
+
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
40
|
+
this.doMeterUpdate = new Subject();
|
|
41
|
+
this.meterUpdateInProgress = false;
|
|
84
42
|
|
|
85
43
|
// Retrieve initial values and updateHomekit
|
|
86
44
|
this.refreshStatus();
|
|
87
45
|
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
46
|
+
// Initialize Temperature Sensor property
|
|
47
|
+
if (!device.meter?.hide_temperature) {
|
|
48
|
+
this.TemperatureSensor = {
|
|
49
|
+
Service: this.accessory.addService(this.hap.Service.TemperatureSensor),
|
|
50
|
+
CurrentTemperature: accessory.context.CurrentTemperature || 30,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Initialize Humidity Sensor property
|
|
55
|
+
if (!device.meter?.hide_humidity) {
|
|
56
|
+
this.HumiditySensor = {
|
|
57
|
+
Service: this.accessory.addService(this.hap.Service.HumiditySensor),
|
|
58
|
+
CurrentRelativeHumidity: accessory.context.CurrentRelativeHumidity || 50,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Initialize Battery property
|
|
63
|
+
this.Battery = {
|
|
64
|
+
Service: this.accessory.addService(this.hap.Service.Battery),
|
|
65
|
+
BatteryLevel: accessory.context.BatteryLevel || 100,
|
|
66
|
+
StatusLowBattery: accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
67
|
+
};
|
|
95
68
|
|
|
96
69
|
// Temperature Sensor Service
|
|
97
70
|
if (device.meter?.hide_temperature) {
|
|
98
71
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Temperature Sensor Service`);
|
|
99
|
-
this.
|
|
100
|
-
accessory.removeService(this.
|
|
101
|
-
} else if (!this.
|
|
72
|
+
this.TemperatureSensor!.Service = this.accessory.getService(this.hap.Service.TemperatureSensor) as Service;
|
|
73
|
+
accessory.removeService(this.TemperatureSensor!.Service);
|
|
74
|
+
} else if (!this.TemperatureSensor!.Service) {
|
|
102
75
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Temperature Sensor Service`);
|
|
103
|
-
const
|
|
104
|
-
(this.
|
|
105
|
-
|| this.accessory.addService(this.hap.Service.TemperatureSensor)),
|
|
76
|
+
const TemperatureSensorService = `${accessory.displayName} Temperature Sensor`;
|
|
77
|
+
(this.TemperatureSensor!.Service = this.accessory.getService(this.hap.Service.TemperatureSensor)
|
|
78
|
+
|| this.accessory.addService(this.hap.Service.TemperatureSensor)), TemperatureSensorService;
|
|
106
79
|
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
this.temperatureService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Temperature Sensor`);
|
|
110
|
-
}
|
|
111
|
-
this.temperatureService
|
|
80
|
+
this.TemperatureSensor!.Service.setCharacteristic(this.hap.Characteristic.Name, TemperatureSensorService);
|
|
81
|
+
this.TemperatureSensor!.Service
|
|
112
82
|
.getCharacteristic(this.hap.Characteristic.CurrentTemperature)
|
|
113
83
|
.setProps({
|
|
114
84
|
unit: Units['CELSIUS'],
|
|
@@ -118,7 +88,7 @@ export class Meter {
|
|
|
118
88
|
minStep: 0.1,
|
|
119
89
|
})
|
|
120
90
|
.onGet(() => {
|
|
121
|
-
return this.CurrentTemperature!;
|
|
91
|
+
return this.TemperatureSensor!.CurrentTemperature!;
|
|
122
92
|
});
|
|
123
93
|
} else {
|
|
124
94
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Temperature Sensor Service Not Added`);
|
|
@@ -127,46 +97,41 @@ export class Meter {
|
|
|
127
97
|
// Humidity Sensor Service
|
|
128
98
|
if (device.meter?.hide_humidity) {
|
|
129
99
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Humidity Sensor Service`);
|
|
130
|
-
this.
|
|
131
|
-
accessory.removeService(this.
|
|
132
|
-
} else if (!this.
|
|
100
|
+
this.HumiditySensor!.Service = this.accessory.getService(this.hap.Service.HumiditySensor) as Service;
|
|
101
|
+
accessory.removeService(this.HumiditySensor!.Service);
|
|
102
|
+
} else if (!this.HumiditySensor!.Service) {
|
|
133
103
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Humidity Sensor Service`);
|
|
134
|
-
const
|
|
135
|
-
(this.
|
|
136
|
-
|| this.accessory.addService(this.hap.Service.HumiditySensor)),
|
|
104
|
+
const HumiditySensorService = `${accessory.displayName} Humidity Sensor`;
|
|
105
|
+
(this.HumiditySensor!.Service = this.accessory.getService(this.hap.Service.HumiditySensor)
|
|
106
|
+
|| this.accessory.addService(this.hap.Service.HumiditySensor)), HumiditySensorService;
|
|
137
107
|
|
|
138
|
-
this.
|
|
139
|
-
|
|
140
|
-
this.humidityService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Humidity Sensor`);
|
|
141
|
-
}
|
|
142
|
-
this.humidityService
|
|
108
|
+
this.HumiditySensor!.Service.setCharacteristic(this.hap.Characteristic.Name, HumiditySensorService);
|
|
109
|
+
this.HumiditySensor!.Service
|
|
143
110
|
.getCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity)
|
|
144
111
|
.setProps({
|
|
145
112
|
minStep: 0.1,
|
|
146
113
|
})
|
|
147
114
|
.onGet(() => {
|
|
148
|
-
return this.CurrentRelativeHumidity!;
|
|
115
|
+
return this.HumiditySensor!.CurrentRelativeHumidity!;
|
|
149
116
|
});
|
|
150
117
|
} else {
|
|
151
118
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Humidity Sensor Service Not Added`);
|
|
152
119
|
}
|
|
153
120
|
|
|
154
121
|
// Battery Service
|
|
155
|
-
const
|
|
156
|
-
(this.
|
|
157
|
-
|| accessory.addService(this.hap.Service.Battery)),
|
|
122
|
+
const BatteryService = `${accessory.displayName} Battery`;
|
|
123
|
+
(this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
|
|
124
|
+
|| accessory.addService(this.hap.Service.Battery)), BatteryService;
|
|
158
125
|
|
|
159
|
-
this.
|
|
160
|
-
|
|
161
|
-
this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
|
|
162
|
-
}
|
|
163
|
-
this.batteryService.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
126
|
+
this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, BatteryService);
|
|
127
|
+
this.Battery.Service.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
164
128
|
|
|
165
129
|
// Retrieve initial values and update Homekit
|
|
166
130
|
this.updateHomeKitCharacteristics();
|
|
167
131
|
|
|
168
132
|
// Start an update interval
|
|
169
133
|
interval(this.deviceRefreshRate * 1000)
|
|
134
|
+
.pipe(skipWhile(() => this.meterUpdateInProgress))
|
|
170
135
|
.subscribe(async () => {
|
|
171
136
|
await this.refreshStatus();
|
|
172
137
|
});
|
|
@@ -179,13 +144,18 @@ export class Meter {
|
|
|
179
144
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
180
145
|
if (context.scale === 'CELSIUS') {
|
|
181
146
|
const { temperature, humidity } = context;
|
|
182
|
-
const { CurrentTemperature
|
|
147
|
+
const { CurrentTemperature } = this.TemperatureSensor || { CurrentTemperature: undefined };
|
|
148
|
+
const { CurrentRelativeHumidity } = this.HumiditySensor || { CurrentRelativeHumidity: undefined };
|
|
183
149
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
|
|
184
150
|
'(temperature, humidity) = ' +
|
|
185
151
|
`Webhook:(${temperature}, ${humidity}), ` +
|
|
186
152
|
`current:(${CurrentTemperature}, ${CurrentRelativeHumidity})`);
|
|
187
|
-
this.
|
|
188
|
-
|
|
153
|
+
if (this.device.meter?.hide_humidity) {
|
|
154
|
+
this.HumiditySensor!.CurrentRelativeHumidity = humidity;
|
|
155
|
+
}
|
|
156
|
+
if (this.device.meter?.hide_temperature) {
|
|
157
|
+
this.TemperatureSensor!.CurrentTemperature = temperature;
|
|
158
|
+
}
|
|
189
159
|
this.updateHomeKitCharacteristics();
|
|
190
160
|
}
|
|
191
161
|
} catch (e: any) {
|
|
@@ -196,90 +166,62 @@ export class Meter {
|
|
|
196
166
|
}
|
|
197
167
|
}
|
|
198
168
|
|
|
199
|
-
|
|
200
|
-
* Parse the device status from the SwitchBot api
|
|
201
|
-
*/
|
|
202
|
-
async parseStatus(): Promise<void> {
|
|
203
|
-
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
204
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
|
|
205
|
-
} else if (this.BLE) {
|
|
206
|
-
await this.BLEparseStatus();
|
|
207
|
-
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
208
|
-
await this.openAPIparseStatus();
|
|
209
|
-
} else {
|
|
210
|
-
await this.offlineOff();
|
|
211
|
-
this.debugWarnLog(
|
|
212
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`,
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
async BLEparseStatus(): Promise<void> {
|
|
169
|
+
async BLEparseStatus(serviceData: serviceData): Promise<void> {
|
|
218
170
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
219
171
|
|
|
220
172
|
// BatteryLevel
|
|
221
|
-
this.BatteryLevel = Number(
|
|
222
|
-
if (this.BatteryLevel < 15) {
|
|
223
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
173
|
+
this.Battery.BatteryLevel = Number(serviceData.battery);
|
|
174
|
+
if (this.Battery.BatteryLevel < 15) {
|
|
175
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
224
176
|
} else {
|
|
225
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
177
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
226
178
|
}
|
|
227
|
-
this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
179
|
+
this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}, StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
228
180
|
|
|
229
181
|
// CurrentRelativeHumidity
|
|
230
182
|
if (!this.device.meter?.hide_humidity) {
|
|
231
|
-
this.CurrentRelativeHumidity =
|
|
232
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
183
|
+
this.HumiditySensor!.CurrentRelativeHumidity = serviceData.humidity!;
|
|
184
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.HumiditySensor!.CurrentRelativeHumidity}%`);
|
|
233
185
|
}
|
|
234
186
|
|
|
235
187
|
// CurrentTemperature
|
|
236
188
|
if (!this.device.meter?.hide_temperature) {
|
|
237
|
-
|
|
238
|
-
this.CurrentTemperature =
|
|
239
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
|
|
189
|
+
serviceData.temperature!.c < 0 ? 0 : serviceData.temperature!.c > 100 ? 100 : serviceData.temperature!.c;
|
|
190
|
+
this.TemperatureSensor!.CurrentTemperature = serviceData.temperature!.c;
|
|
191
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor!.CurrentTemperature}°c`);
|
|
240
192
|
}
|
|
241
193
|
}
|
|
242
194
|
|
|
243
|
-
async openAPIparseStatus(): Promise<void> {
|
|
195
|
+
async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
|
|
244
196
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
245
197
|
|
|
246
|
-
//
|
|
247
|
-
this.BatteryLevel = Number(
|
|
248
|
-
if (this.BatteryLevel <
|
|
249
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
198
|
+
// Battery
|
|
199
|
+
this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
|
|
200
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
201
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
250
202
|
} else {
|
|
251
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
203
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
252
204
|
}
|
|
253
|
-
|
|
205
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
206
|
+
this.Battery.BatteryLevel = 100;
|
|
207
|
+
}
|
|
208
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
209
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
254
210
|
|
|
255
211
|
// CurrentRelativeHumidity
|
|
256
212
|
if (!this.device.meter?.hide_humidity) {
|
|
257
|
-
this.CurrentRelativeHumidity =
|
|
258
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
213
|
+
this.HumiditySensor!.CurrentRelativeHumidity = deviceStatus.body.humidity!;
|
|
214
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.HumiditySensor!.CurrentRelativeHumidity}%`);
|
|
259
215
|
}
|
|
260
216
|
|
|
261
217
|
// CurrentTemperature
|
|
262
218
|
if (!this.device.meter?.hide_temperature) {
|
|
263
|
-
this.CurrentTemperature =
|
|
264
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Battery
|
|
268
|
-
this.BatteryLevel = Number(this.OpenAPI_BatteryLevel);
|
|
269
|
-
if (this.BatteryLevel < 10) {
|
|
270
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
271
|
-
} else {
|
|
272
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
219
|
+
this.TemperatureSensor!.CurrentTemperature = deviceStatus.body.temperature!;
|
|
220
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor!.CurrentTemperature}°c`);
|
|
273
221
|
}
|
|
274
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
275
|
-
this.BatteryLevel = 100;
|
|
276
|
-
}
|
|
277
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
278
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
279
222
|
|
|
280
223
|
// FirmwareRevision
|
|
281
|
-
this.FirmwareRevision =
|
|
282
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
224
|
+
this.accessory.context.FirmwareRevision = deviceStatus.body.version;
|
|
283
225
|
}
|
|
284
226
|
|
|
285
227
|
/**
|
|
@@ -313,97 +255,36 @@ export class Meter {
|
|
|
313
255
|
this.getCustomBLEAddress(switchbot);
|
|
314
256
|
// Start to monitor advertisement packets
|
|
315
257
|
(async () => {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
id: this.device.bleMac,
|
|
319
|
-
});
|
|
258
|
+
// Start to monitor advertisement packets
|
|
259
|
+
await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
|
|
320
260
|
// Set an event handler
|
|
321
261
|
switchbot.onadvertisement = (ad: any) => {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
262
|
+
if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
|
|
263
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
|
|
264
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
|
|
325
265
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
326
|
-
this.BLE_CurrentRelativeHumidity = ad.serviceData.humidity < 0 ? 0 : ad.serviceData.humidity > 100 ? 100 : ad.serviceData.humidity;
|
|
327
|
-
this.BLE_CurrentTemperature = ad.serviceData.temperature;
|
|
328
|
-
this.BLE_Celsius = ad.serviceData.temperature!.c;
|
|
329
|
-
this.BLE_Fahrenheit = ad.serviceData.temperature!.f;
|
|
330
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
331
266
|
} else {
|
|
332
267
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
333
268
|
}
|
|
334
269
|
};
|
|
335
|
-
// Wait
|
|
270
|
+
// Wait 10 seconds
|
|
336
271
|
await switchbot.wait(this.scanDuration * 1000);
|
|
337
272
|
// Stop to monitor
|
|
338
273
|
await switchbot.stopScan();
|
|
339
274
|
// Update HomeKit
|
|
340
|
-
await this.BLEparseStatus();
|
|
275
|
+
await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
|
|
341
276
|
await this.updateHomeKitCharacteristics();
|
|
342
277
|
})();
|
|
343
|
-
|
|
344
|
-
switchbot
|
|
345
|
-
.startScan({
|
|
346
|
-
model: 'T',
|
|
347
|
-
id: this.device.bleMac,
|
|
348
|
-
})
|
|
349
|
-
.then(async () => {
|
|
350
|
-
// Set an event handler
|
|
351
|
-
switchbot.onadvertisement = async (ad: ad) => {
|
|
352
|
-
this.debugLog(
|
|
353
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
|
|
354
|
-
` BLE Address Found: ${ad.address}`,
|
|
355
|
-
);
|
|
356
|
-
if (ad.serviceData.humidity! > 0) {
|
|
357
|
-
// reject unreliable data
|
|
358
|
-
this.BLE_CurrentRelativeHumidity = ad.serviceData.humidity;
|
|
359
|
-
}
|
|
360
|
-
this.BLE_CurrentTemperature = ad.serviceData.temperature;
|
|
361
|
-
this.BLE_Celsius = ad.serviceData.temperature!.c;
|
|
362
|
-
this.BLE_Fahrenheit = ad.serviceData.temperature!.f;
|
|
363
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
364
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
365
|
-
this.debugLog(
|
|
366
|
-
`${this.device.deviceType}: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
|
|
367
|
-
`temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
|
|
368
|
-
`battery: ${ad.serviceData.battery}`,
|
|
369
|
-
);
|
|
370
|
-
|
|
371
|
-
if (ad.serviceData) {
|
|
372
|
-
this.BLE_IsConnected = true;
|
|
373
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
374
|
-
await this.stopScanning(switchbot);
|
|
375
|
-
} else {
|
|
376
|
-
this.BLE_IsConnected = false;
|
|
377
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
// Wait
|
|
381
|
-
return await sleep(this.scanDuration * 1000);
|
|
382
|
-
})
|
|
383
|
-
.then(async () => {
|
|
384
|
-
// Stop to monitor
|
|
385
|
-
await this.stopScanning(switchbot);
|
|
386
|
-
})
|
|
387
|
-
.catch(async (e: any) => {
|
|
388
|
-
this.apiError(e);
|
|
389
|
-
this.errorLog(
|
|
390
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
|
|
391
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
392
|
-
);
|
|
393
|
-
await this.BLERefreshConnection(switchbot);
|
|
394
|
-
});
|
|
395
|
-
} else {
|
|
278
|
+
if (switchbot === undefined) {
|
|
396
279
|
await this.BLERefreshConnection(switchbot);
|
|
397
|
-
}
|
|
280
|
+
}
|
|
398
281
|
}
|
|
399
282
|
|
|
400
283
|
async openAPIRefreshStatus(): Promise<void> {
|
|
401
284
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
402
285
|
try {
|
|
403
|
-
const { body, statusCode } = await this.platform.retryRequest(this.
|
|
404
|
-
`${Devices}/${this.device.deviceId}/status`, {
|
|
405
|
-
headers: this.platform.generateHeaders(),
|
|
406
|
-
});
|
|
286
|
+
const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
|
|
287
|
+
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
407
288
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
408
289
|
const deviceStatus: any = await body.json();
|
|
409
290
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
|
|
@@ -411,11 +292,7 @@ export class Meter {
|
|
|
411
292
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
412
293
|
this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
413
294
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
414
|
-
this.
|
|
415
|
-
this.OpenAPI_CurrentTemperature = deviceStatus.body.temperature!;
|
|
416
|
-
this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
|
|
417
|
-
this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
|
|
418
|
-
this.openAPIparseStatus();
|
|
295
|
+
this.openAPIparseStatus(deviceStatus);
|
|
419
296
|
this.updateHomeKitCharacteristics();
|
|
420
297
|
} else {
|
|
421
298
|
this.statusCode(statusCode);
|
|
@@ -439,64 +316,72 @@ export class Meter {
|
|
|
439
316
|
|
|
440
317
|
// CurrentRelativeHumidity
|
|
441
318
|
if (!this.device.meter?.hide_humidity) {
|
|
442
|
-
if (this.CurrentRelativeHumidity === undefined) {
|
|
443
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
319
|
+
if (this.HumiditySensor!.CurrentRelativeHumidity === undefined) {
|
|
320
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
321
|
+
+ ` CurrentRelativeHumidity: ${this.HumiditySensor!.CurrentRelativeHumidity}`);
|
|
444
322
|
} else {
|
|
323
|
+
this.accessory.context.CurrentRelativeHumidity = this.HumiditySensor!.CurrentRelativeHumidity;
|
|
324
|
+
this.HumiditySensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity,
|
|
325
|
+
this.HumiditySensor!.CurrentRelativeHumidity);
|
|
326
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
327
|
+
+ ` updateCharacteristic CurrentRelativeHumidity: ${this.HumiditySensor!.CurrentRelativeHumidity}`);
|
|
445
328
|
if (this.device.mqttURL) {
|
|
446
|
-
mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
|
|
329
|
+
mqttmessage.push(`"humidity": ${this.HumiditySensor!.CurrentRelativeHumidity}`);
|
|
447
330
|
}
|
|
448
331
|
if (this.device.history) {
|
|
449
|
-
entry['humidity'] = this.CurrentRelativeHumidity;
|
|
332
|
+
entry['humidity'] = this.HumiditySensor!.CurrentRelativeHumidity;
|
|
450
333
|
}
|
|
451
|
-
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
|
|
452
|
-
this.humidityService?.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
|
|
453
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
454
|
-
+ `updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
455
334
|
}
|
|
456
335
|
}
|
|
336
|
+
|
|
457
337
|
// CurrentTemperature
|
|
458
338
|
if (!this.device.meter?.hide_temperature) {
|
|
459
|
-
if (this.CurrentTemperature === undefined) {
|
|
460
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
|
|
339
|
+
if (this.TemperatureSensor!.CurrentTemperature === undefined) {
|
|
340
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.TemperatureSensor!.CurrentTemperature}`);
|
|
461
341
|
} else {
|
|
342
|
+
this.accessory.context.CurrentTemperature = this.TemperatureSensor!.CurrentTemperature;
|
|
343
|
+
this.TemperatureSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.TemperatureSensor!.CurrentTemperature);
|
|
344
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
345
|
+
+ ` CurrentTemperature: ${this.TemperatureSensor!.CurrentTemperature}`);
|
|
462
346
|
if (this.device.mqttURL) {
|
|
463
|
-
mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
|
|
347
|
+
mqttmessage.push(`"temperature": ${this.TemperatureSensor!.CurrentTemperature}`);
|
|
464
348
|
}
|
|
465
349
|
if (this.device.history) {
|
|
466
|
-
entry['temp'] = this.CurrentTemperature;
|
|
350
|
+
entry['temp'] = this.TemperatureSensor!.CurrentTemperature;
|
|
467
351
|
}
|
|
468
|
-
this.accessory.context.CurrentTemperature = this.CurrentTemperature;
|
|
469
|
-
this.temperatureService?.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.CurrentTemperature);
|
|
470
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
|
|
471
352
|
}
|
|
472
353
|
}
|
|
354
|
+
|
|
473
355
|
// BatteryLevel
|
|
474
|
-
if (this.BatteryLevel === undefined) {
|
|
475
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
356
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
357
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
476
358
|
} else {
|
|
359
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
360
|
+
this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
361
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
477
362
|
if (this.device.mqttURL) {
|
|
478
|
-
mqttmessage.push(`"battery": ${this.BatteryLevel}`);
|
|
363
|
+
mqttmessage.push(`"battery": ${this.Battery.BatteryLevel}`);
|
|
479
364
|
}
|
|
480
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
481
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
482
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
483
365
|
}
|
|
484
|
-
if (this.StatusLowBattery === undefined) {
|
|
485
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
366
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
367
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
486
368
|
} else {
|
|
369
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
370
|
+
this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
371
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
372
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
487
373
|
if (this.device.mqttURL) {
|
|
488
|
-
mqttmessage.push(`"lowBattery": ${this.StatusLowBattery}`);
|
|
374
|
+
mqttmessage.push(`"lowBattery": ${this.Battery.StatusLowBattery}`);
|
|
489
375
|
}
|
|
490
|
-
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
491
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
492
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
493
376
|
}
|
|
494
377
|
|
|
495
|
-
// MQTT
|
|
378
|
+
// MQTT Publish
|
|
496
379
|
if (this.device.mqttURL) {
|
|
497
380
|
this.mqttPublish(`{${mqttmessage.join(',')}}`);
|
|
498
381
|
}
|
|
499
|
-
|
|
382
|
+
|
|
383
|
+
// History Service
|
|
384
|
+
if (!this.device.meter?.hide_humidity && (Number(this.HumiditySensor!.CurrentRelativeHumidity) > 0)) {
|
|
500
385
|
// reject unreliable data
|
|
501
386
|
if (this.device.history) {
|
|
502
387
|
this.historyService?.addEntry(entry);
|
|
@@ -504,84 +389,6 @@ export class Meter {
|
|
|
504
389
|
}
|
|
505
390
|
}
|
|
506
391
|
|
|
507
|
-
/*
|
|
508
|
-
* Publish MQTT message for topics of
|
|
509
|
-
* 'homebridge-switchbot/meter/xx:xx:xx:xx:xx:xx'
|
|
510
|
-
*/
|
|
511
|
-
mqttPublish(message: any) {
|
|
512
|
-
const mac = this.device.deviceId
|
|
513
|
-
?.toLowerCase()
|
|
514
|
-
.match(/[\s\S]{1,2}/g)
|
|
515
|
-
?.join(':');
|
|
516
|
-
const options = this.device.mqttPubOptions || {};
|
|
517
|
-
this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
|
|
518
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
/*
|
|
522
|
-
* Setup MQTT hadler if URL is specified.
|
|
523
|
-
*/
|
|
524
|
-
async setupMqtt(device: device & devicesConfig): Promise<void> {
|
|
525
|
-
if (device.mqttURL) {
|
|
526
|
-
try {
|
|
527
|
-
const { connectAsync } = asyncmqtt;
|
|
528
|
-
this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
|
|
529
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
|
|
530
|
-
this.mqttClient.on('error', (e: Error) => {
|
|
531
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
|
|
532
|
-
});
|
|
533
|
-
} catch (e) {
|
|
534
|
-
this.mqttClient = null;
|
|
535
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
/*
|
|
541
|
-
* Setup EVE history graph feature if enabled.
|
|
542
|
-
*/
|
|
543
|
-
async setupHistoryService(device: device & devicesConfig): Promise<void> {
|
|
544
|
-
const mac = this.device
|
|
545
|
-
.deviceId!.match(/.{1,2}/g)!
|
|
546
|
-
.join(':')
|
|
547
|
-
.toLowerCase();
|
|
548
|
-
this.historyService = device.history
|
|
549
|
-
? new this.platform.fakegatoAPI('room', this.accessory, {
|
|
550
|
-
log: this.platform.log,
|
|
551
|
-
storage: 'fs',
|
|
552
|
-
filename: `${hostname().split('.')[0]}_${mac}_persist.json`,
|
|
553
|
-
})
|
|
554
|
-
: null;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
async stopScanning(switchbot: any) {
|
|
558
|
-
switchbot.stopScan();
|
|
559
|
-
if (this.BLE_IsConnected) {
|
|
560
|
-
await this.BLEparseStatus();
|
|
561
|
-
await this.updateHomeKitCharacteristics();
|
|
562
|
-
} else {
|
|
563
|
-
await this.BLERefreshConnection(switchbot);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
568
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
569
|
-
(async () => {
|
|
570
|
-
// Start to monitor advertisement packets
|
|
571
|
-
await switchbot.startScan({
|
|
572
|
-
model: 'T',
|
|
573
|
-
});
|
|
574
|
-
// Set an event handler
|
|
575
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
576
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
577
|
-
};
|
|
578
|
-
await sleep(10000);
|
|
579
|
-
// Stop to monitor
|
|
580
|
-
switchbot.stopScan();
|
|
581
|
-
})();
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
|
|
585
392
|
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
586
393
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
|
|
587
394
|
+ ` ${JSON.stringify(switchbot)}`);
|
|
@@ -591,272 +398,26 @@ export class Meter {
|
|
|
591
398
|
}
|
|
592
399
|
}
|
|
593
400
|
|
|
594
|
-
async scan(device: device & devicesConfig): Promise<void> {
|
|
595
|
-
if (device.scanDuration) {
|
|
596
|
-
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
597
|
-
if (this.BLE) {
|
|
598
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
599
|
-
}
|
|
600
|
-
} else {
|
|
601
|
-
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
602
|
-
if (this.BLE) {
|
|
603
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
async statusCode(statusCode: number): Promise<void> {
|
|
609
|
-
switch (statusCode) {
|
|
610
|
-
case 151:
|
|
611
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
612
|
-
break;
|
|
613
|
-
case 152:
|
|
614
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
615
|
-
break;
|
|
616
|
-
case 160:
|
|
617
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
618
|
-
break;
|
|
619
|
-
case 161:
|
|
620
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
621
|
-
this.offlineOff();
|
|
622
|
-
break;
|
|
623
|
-
case 171:
|
|
624
|
-
this.errorLog(
|
|
625
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
|
|
626
|
-
`Hub: ${this.device.hubDeviceId}`,
|
|
627
|
-
);
|
|
628
|
-
this.offlineOff();
|
|
629
|
-
break;
|
|
630
|
-
case 190:
|
|
631
|
-
this.errorLog(
|
|
632
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
633
|
-
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
634
|
-
);
|
|
635
|
-
break;
|
|
636
|
-
case 100:
|
|
637
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
638
|
-
break;
|
|
639
|
-
case 200:
|
|
640
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
641
|
-
break;
|
|
642
|
-
case 400:
|
|
643
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
|
|
644
|
-
+ `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
|
|
645
|
-
break;
|
|
646
|
-
case 401:
|
|
647
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
|
|
648
|
-
+ `but the request has not been authenticated, statusCode: ${statusCode}`);
|
|
649
|
-
break;
|
|
650
|
-
case 403:
|
|
651
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
|
|
652
|
-
+ `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
|
|
653
|
-
break;
|
|
654
|
-
case 404:
|
|
655
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
|
|
656
|
-
+ `statusCode: ${statusCode}`);
|
|
657
|
-
break;
|
|
658
|
-
case 406:
|
|
659
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
|
|
660
|
-
+ `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
|
|
661
|
-
break;
|
|
662
|
-
case 415:
|
|
663
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
|
|
664
|
-
+ `header that is not supported by the server, statusCode: ${statusCode}`);
|
|
665
|
-
break;
|
|
666
|
-
case 422:
|
|
667
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
|
|
668
|
-
+ `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
|
|
669
|
-
break;
|
|
670
|
-
case 429:
|
|
671
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
|
|
672
|
-
+ `requests allowed for a given time window, statusCode: ${statusCode}`);
|
|
673
|
-
break;
|
|
674
|
-
case 500:
|
|
675
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
|
|
676
|
-
+ `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
|
|
677
|
-
break;
|
|
678
|
-
default:
|
|
679
|
-
this.infoLog(
|
|
680
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
|
|
681
|
-
`${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
|
|
682
|
-
);
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
401
|
async offlineOff(): Promise<void> {
|
|
687
402
|
if (this.device.offline) {
|
|
688
|
-
|
|
689
|
-
|
|
403
|
+
if (!this.device.meter?.hide_humidity) {
|
|
404
|
+
this.HumiditySensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, 50);
|
|
405
|
+
}
|
|
406
|
+
if (!this.device.meter?.hide_temperature) {
|
|
407
|
+
this.TemperatureSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, 30);
|
|
408
|
+
}
|
|
409
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, 100);
|
|
690
410
|
}
|
|
691
411
|
}
|
|
692
412
|
|
|
693
413
|
async apiError(e: any): Promise<void> {
|
|
694
414
|
if (!this.device.meter?.hide_humidity) {
|
|
695
|
-
this.
|
|
415
|
+
this.HumiditySensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity, e);
|
|
696
416
|
}
|
|
697
417
|
if (!this.device.meter?.hide_temperature) {
|
|
698
|
-
this.
|
|
699
|
-
}
|
|
700
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
701
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
async deviceContext() {
|
|
705
|
-
if (this.CurrentRelativeHumidity === undefined) {
|
|
706
|
-
this.CurrentRelativeHumidity = 0;
|
|
707
|
-
} else {
|
|
708
|
-
this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity;
|
|
709
|
-
}
|
|
710
|
-
if (this.CurrentTemperature === undefined) {
|
|
711
|
-
this.CurrentTemperature = 0;
|
|
712
|
-
} else {
|
|
713
|
-
this.CurrentTemperature = this.accessory.context.CurrentTemperature;
|
|
714
|
-
}
|
|
715
|
-
if (this.BatteryLevel === undefined) {
|
|
716
|
-
this.BatteryLevel = 100;
|
|
717
|
-
} else {
|
|
718
|
-
this.BatteryLevel = this.accessory.context.BatteryLevel;
|
|
719
|
-
}
|
|
720
|
-
if (this.StatusLowBattery === undefined) {
|
|
721
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
722
|
-
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
723
|
-
} else {
|
|
724
|
-
this.StatusLowBattery = this.accessory.context.StatusLowBattery;
|
|
725
|
-
}
|
|
726
|
-
if (this.FirmwareRevision === undefined) {
|
|
727
|
-
this.FirmwareRevision = this.platform.version;
|
|
728
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
733
|
-
if (device.refreshRate) {
|
|
734
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
735
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
736
|
-
} else if (this.platform.config.options!.refreshRate) {
|
|
737
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
738
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
async deviceRetry(device: device & devicesConfig): Promise<void> {
|
|
743
|
-
if (!device.maxRetries) {
|
|
744
|
-
this.maxRetries = 5; // Maximum number of retries
|
|
745
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
|
|
746
|
-
} else {
|
|
747
|
-
this.maxRetries = device.maxRetries;
|
|
748
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
|
|
749
|
-
}
|
|
750
|
-
if (!device.delayBetweenRetries) {
|
|
751
|
-
this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
|
|
752
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
|
|
753
|
-
} else {
|
|
754
|
-
this.delayBetweenRetries = device.delayBetweenRetries * 1000;
|
|
755
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
async deviceConfig(device: device & devicesConfig): Promise<void> {
|
|
760
|
-
let config = {};
|
|
761
|
-
if (device.meter) {
|
|
762
|
-
config = device.meter;
|
|
763
|
-
}
|
|
764
|
-
if (device.connectionType !== undefined) {
|
|
765
|
-
config['connectionType'] = device.connectionType;
|
|
766
|
-
}
|
|
767
|
-
if (device.external !== undefined) {
|
|
768
|
-
config['external'] = device.external;
|
|
769
|
-
}
|
|
770
|
-
if (device.mqttURL !== undefined) {
|
|
771
|
-
config['mqttURL'] = device.mqttURL;
|
|
772
|
-
}
|
|
773
|
-
if (device.logging !== undefined) {
|
|
774
|
-
config['logging'] = device.logging;
|
|
775
|
-
}
|
|
776
|
-
if (device.refreshRate !== undefined) {
|
|
777
|
-
config['refreshRate'] = device.refreshRate;
|
|
418
|
+
this.TemperatureSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
|
|
778
419
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
}
|
|
782
|
-
if (device.webhook !== undefined) {
|
|
783
|
-
config['webhook'] = device.webhook;
|
|
784
|
-
}
|
|
785
|
-
if (Object.entries(config).length !== 0) {
|
|
786
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
async deviceLogs(device: device & devicesConfig): Promise<void> {
|
|
791
|
-
if (this.platform.debugMode) {
|
|
792
|
-
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
793
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
794
|
-
} else if (device.logging) {
|
|
795
|
-
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
796
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
797
|
-
} else if (this.platform.config.options?.logging) {
|
|
798
|
-
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
799
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
800
|
-
} else {
|
|
801
|
-
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
802
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* Logging for Device
|
|
808
|
-
*/
|
|
809
|
-
successLog(...log: any[]): void {
|
|
810
|
-
if (this.enablingDeviceLogging()) {
|
|
811
|
-
this.platform.log.success(String(...log));
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
infoLog(...log: any[]): void {
|
|
816
|
-
if (this.enablingDeviceLogging()) {
|
|
817
|
-
this.platform.log.info(String(...log));
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
warnLog(...log: any[]): void {
|
|
822
|
-
if (this.enablingDeviceLogging()) {
|
|
823
|
-
this.platform.log.warn(String(...log));
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
debugWarnLog(...log: any[]): void {
|
|
828
|
-
if (this.enablingDeviceLogging()) {
|
|
829
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
830
|
-
this.platform.log.warn('[DEBUG]', String(...log));
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
errorLog(...log: any[]): void {
|
|
836
|
-
if (this.enablingDeviceLogging()) {
|
|
837
|
-
this.platform.log.error(String(...log));
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
debugErrorLog(...log: any[]): void {
|
|
842
|
-
if (this.enablingDeviceLogging()) {
|
|
843
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
844
|
-
this.platform.log.error('[DEBUG]', String(...log));
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
debugLog(...log: any[]): void {
|
|
850
|
-
if (this.enablingDeviceLogging()) {
|
|
851
|
-
if (this.deviceLogging === 'debug') {
|
|
852
|
-
this.platform.log.info('[DEBUG]', String(...log));
|
|
853
|
-
} else {
|
|
854
|
-
this.platform.log.debug(String(...log));
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
enablingDeviceLogging(): boolean {
|
|
860
|
-
return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
|
|
420
|
+
this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
421
|
+
this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
861
422
|
}
|
|
862
423
|
}
|