@switchbot/homebridge-switchbot 2.0.0-beta.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/README.md +3 -2
- package/config.schema.json +91 -19
- package/dist/device/bot.d.ts +34 -28
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +657 -648
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +137 -0
- package/dist/device/ceilinglight.d.ts.map +1 -0
- package/dist/device/ceilinglight.js +1127 -0
- package/dist/device/ceilinglight.js.map +1 -0
- package/dist/device/colorbulb.d.ts +36 -14
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +472 -297
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +18 -8
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +306 -237
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +23 -16
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +566 -502
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/humidifier.d.ts +24 -18
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +453 -369
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/lock.d.ts +27 -8
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +305 -148
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +22 -16
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +367 -267
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +24 -12
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +381 -213
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +18 -8
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +279 -216
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +27 -17
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +295 -251
- package/dist/device/plug.js.map +1 -1
- package/dist/device/striplight.d.ts +43 -19
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +506 -262
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +9 -12
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +278 -230
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +5 -3
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +154 -104
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +11 -8
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +133 -86
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +10 -7
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +160 -109
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +11 -8
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +137 -103
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +11 -8
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +145 -98
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +12 -9
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +143 -93
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +9 -10
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +132 -89
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +8 -9
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +132 -89
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +13 -12
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +524 -418
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +19 -11
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/homebridge-ui/public/index.html +1 -0
- package/package.json +11 -9
- package/src/device/bot.ts +656 -659
- package/src/device/ceilinglight.ts +1208 -0
- package/src/device/colorbulb.ts +482 -334
- package/src/device/contact.ts +309 -241
- package/src/device/curtain.ts +571 -516
- package/src/device/humidifier.ts +456 -403
- package/src/device/lock.ts +314 -149
- package/src/device/meter.ts +378 -280
- package/src/device/meterplus.ts +391 -219
- package/src/device/motion.ts +285 -222
- package/src/device/plug.ts +299 -260
- package/src/device/striplight.ts +522 -289
- package/src/irdevice/airconditioner.ts +282 -241
- package/src/irdevice/airpurifier.ts +151 -103
- package/src/irdevice/camera.ts +131 -85
- package/src/irdevice/fan.ts +157 -106
- package/src/irdevice/light.ts +135 -103
- package/src/irdevice/other.ts +143 -97
- package/src/irdevice/tv.ts +142 -93
- package/src/irdevice/vacuumcleaner.ts +131 -89
- package/src/irdevice/waterheater.ts +130 -89
- package/src/platform.ts +522 -446
- package/src/settings.ts +20 -11
- package/.github/npm-version-script.js +0 -81
package/src/device/meter.ts
CHANGED
|
@@ -6,9 +6,11 @@ import { MqttClient } from 'mqtt';
|
|
|
6
6
|
import { connectAsync } from 'async-mqtt';
|
|
7
7
|
import { interval, Subject } from 'rxjs';
|
|
8
8
|
import { skipWhile } from 'rxjs/operators';
|
|
9
|
+
import superStringify from 'super-stringify';
|
|
9
10
|
import { SwitchBotPlatform } from '../platform';
|
|
10
11
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
11
12
|
import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, HostDomain, DevicePath } from '../settings';
|
|
13
|
+
import { IncomingMessage } from 'http';
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Platform Accessory
|
|
@@ -23,14 +25,10 @@ export class Meter {
|
|
|
23
25
|
|
|
24
26
|
// Characteristic Values
|
|
25
27
|
CurrentRelativeHumidity!: CharacteristicValue;
|
|
26
|
-
CurrentRelativeHumidityCached!: CharacteristicValue;
|
|
27
28
|
CurrentTemperature?: CharacteristicValue;
|
|
28
|
-
CurrentTemperatureCached?: CharacteristicValue;
|
|
29
29
|
BatteryLevel?: CharacteristicValue;
|
|
30
30
|
ChargingState?: CharacteristicValue;
|
|
31
31
|
StatusLowBattery?: CharacteristicValue;
|
|
32
|
-
Active!: CharacteristicValue;
|
|
33
|
-
WaterLevel!: CharacteristicValue;
|
|
34
32
|
|
|
35
33
|
// OpenAPI Others
|
|
36
34
|
Temperature: deviceStatus['temperature'];
|
|
@@ -40,13 +38,18 @@ export class Meter {
|
|
|
40
38
|
// BLE Others
|
|
41
39
|
connected?: boolean;
|
|
42
40
|
switchbot!: switchbot;
|
|
43
|
-
SwitchToOpenAPI?: boolean;
|
|
44
41
|
serviceData!: serviceData;
|
|
45
42
|
address!: ad['address'];
|
|
46
43
|
temperature!: temperature['c'];
|
|
47
44
|
battery!: serviceData['battery'];
|
|
48
45
|
humidity!: serviceData['humidity'];
|
|
49
46
|
|
|
47
|
+
//MQTT stuff
|
|
48
|
+
mqttClient: MqttClient | null = null;
|
|
49
|
+
|
|
50
|
+
// EVE history service handler
|
|
51
|
+
historyService?: any;
|
|
52
|
+
|
|
50
53
|
// Config
|
|
51
54
|
scanDuration!: number;
|
|
52
55
|
deviceLogging!: string;
|
|
@@ -56,30 +59,19 @@ export class Meter {
|
|
|
56
59
|
meterUpdateInProgress!: boolean;
|
|
57
60
|
doMeterUpdate: Subject<void>;
|
|
58
61
|
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// EVE history service handler
|
|
63
|
-
historyService: any;
|
|
62
|
+
// Connection
|
|
63
|
+
private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI');
|
|
64
|
+
private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI');
|
|
64
65
|
|
|
65
66
|
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
66
67
|
// default placeholders
|
|
67
68
|
this.logs(device);
|
|
68
69
|
this.scan(device);
|
|
69
|
-
this.setupHistoryService(device);
|
|
70
70
|
this.refreshRate(device);
|
|
71
71
|
this.config(device);
|
|
72
|
+
this.context();
|
|
73
|
+
this.setupHistoryService(device);
|
|
72
74
|
this.setupMqtt(device);
|
|
73
|
-
if (this.CurrentRelativeHumidity === undefined) {
|
|
74
|
-
this.CurrentRelativeHumidity = 0;
|
|
75
|
-
} else {
|
|
76
|
-
this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity;
|
|
77
|
-
}
|
|
78
|
-
if (this.CurrentTemperature === undefined) {
|
|
79
|
-
this.CurrentTemperature = 0;
|
|
80
|
-
} else {
|
|
81
|
-
this.CurrentTemperature = this.accessory.context.CurrentTemperature;
|
|
82
|
-
}
|
|
83
75
|
|
|
84
76
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
85
77
|
this.doMeterUpdate = new Subject();
|
|
@@ -100,11 +92,11 @@ export class Meter {
|
|
|
100
92
|
|
|
101
93
|
// Temperature Sensor Service
|
|
102
94
|
if (device.meter?.hide_temperature) {
|
|
103
|
-
this.debugLog(
|
|
95
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Temperature Sensor Service`);
|
|
104
96
|
this.temperatureservice = this.accessory.getService(this.platform.Service.TemperatureSensor);
|
|
105
97
|
accessory.removeService(this.temperatureservice!);
|
|
106
98
|
} else if (!this.temperatureservice) {
|
|
107
|
-
this.debugLog(
|
|
99
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Temperature Sensor Service`);
|
|
108
100
|
(this.temperatureservice =
|
|
109
101
|
this.accessory.getService(this.platform.Service.TemperatureSensor) || this.accessory.addService(this.platform.Service.TemperatureSensor)),
|
|
110
102
|
`${accessory.displayName} Temperature Sensor`;
|
|
@@ -124,16 +116,16 @@ export class Meter {
|
|
|
124
116
|
return this.CurrentTemperature!;
|
|
125
117
|
});
|
|
126
118
|
} else {
|
|
127
|
-
this.debugLog(
|
|
119
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Temperature Sensor Service Not Added`);
|
|
128
120
|
}
|
|
129
121
|
|
|
130
122
|
// Humidity Sensor Service
|
|
131
123
|
if (device.meter?.hide_humidity) {
|
|
132
|
-
this.debugLog(
|
|
124
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Humidity Sensor Service`);
|
|
133
125
|
this.humidityservice = this.accessory.getService(this.platform.Service.HumiditySensor);
|
|
134
126
|
accessory.removeService(this.humidityservice!);
|
|
135
127
|
} else if (!this.humidityservice) {
|
|
136
|
-
this.debugLog(
|
|
128
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Humidity Sensor Service`);
|
|
137
129
|
(this.humidityservice =
|
|
138
130
|
this.accessory.getService(this.platform.Service.HumiditySensor) || this.accessory.addService(this.platform.Service.HumiditySensor)),
|
|
139
131
|
`${accessory.displayName} Humidity Sensor`;
|
|
@@ -149,16 +141,16 @@ export class Meter {
|
|
|
149
141
|
return this.CurrentRelativeHumidity;
|
|
150
142
|
});
|
|
151
143
|
} else {
|
|
152
|
-
this.debugLog(
|
|
144
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Humidity Sensor Service Not Added`);
|
|
153
145
|
}
|
|
154
146
|
|
|
155
147
|
// Battery Service
|
|
156
|
-
if (!
|
|
157
|
-
this.debugLog(
|
|
148
|
+
if (!this.BLE) {
|
|
149
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Battery Service`);
|
|
158
150
|
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
159
151
|
accessory.removeService(this.batteryService!);
|
|
160
|
-
} else if (
|
|
161
|
-
this.debugLog(
|
|
152
|
+
} else if (this.BLE && !this.batteryService) {
|
|
153
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Battery Service`);
|
|
162
154
|
(this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
|
|
163
155
|
`${accessory.displayName} Battery`;
|
|
164
156
|
|
|
@@ -166,7 +158,7 @@ export class Meter {
|
|
|
166
158
|
|
|
167
159
|
this.batteryService.setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
168
160
|
} else {
|
|
169
|
-
this.debugLog(
|
|
161
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Battery Service Not Added`);
|
|
170
162
|
}
|
|
171
163
|
|
|
172
164
|
// Retrieve initial values and updateHomekit
|
|
@@ -180,68 +172,22 @@ export class Meter {
|
|
|
180
172
|
});
|
|
181
173
|
}
|
|
182
174
|
|
|
183
|
-
/*
|
|
184
|
-
* Publish MQTT message for topics of
|
|
185
|
-
* 'homebridge-switchbot/meter/xx:xx:xx:xx:xx:xx'
|
|
186
|
-
*/
|
|
187
|
-
mqttPublish(message: any) {
|
|
188
|
-
const mac = this.device.deviceId
|
|
189
|
-
?.toLowerCase()
|
|
190
|
-
.match(/[\s\S]{1,2}/g)
|
|
191
|
-
?.join(':');
|
|
192
|
-
const options = this.device.mqttPubOptions || {};
|
|
193
|
-
this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
|
|
194
|
-
this.debugLog(`Meter: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/*
|
|
198
|
-
* Setup MQTT hadler if URL is specifed.
|
|
199
|
-
*/
|
|
200
|
-
async setupMqtt(device: device & devicesConfig): Promise<void> {
|
|
201
|
-
if (device.mqttURL) {
|
|
202
|
-
try {
|
|
203
|
-
this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
|
|
204
|
-
this.debugLog(`Meter: ${this.accessory.displayName} MQTT connection has been established successfully.`);
|
|
205
|
-
this.mqttClient.on('error', (e: Error) => {
|
|
206
|
-
this.errorLog(`Meter: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
|
|
207
|
-
});
|
|
208
|
-
} catch (e) {
|
|
209
|
-
this.mqttClient = null;
|
|
210
|
-
this.errorLog(`Meter: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/*
|
|
216
|
-
* Setup EVE history graph feature if enabled.
|
|
217
|
-
*/
|
|
218
|
-
async setupHistoryService(device: device & devicesConfig): Promise<void> {
|
|
219
|
-
const mac = this.device
|
|
220
|
-
.deviceId!.match(/.{1,2}/g)!
|
|
221
|
-
.join(':')
|
|
222
|
-
.toLowerCase();
|
|
223
|
-
this.historyService = device.history
|
|
224
|
-
? new this.platform.fakegatoAPI('room', this.accessory, {
|
|
225
|
-
log: this.platform.log,
|
|
226
|
-
storage: 'fs',
|
|
227
|
-
filename: `${hostname().split('.')[0]}_${mac}_persist.json`,
|
|
228
|
-
})
|
|
229
|
-
: null;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
175
|
/**
|
|
233
176
|
* Parse the device status from the SwitchBot api
|
|
234
177
|
*/
|
|
235
178
|
async parseStatus(): Promise<void> {
|
|
236
|
-
if (this.
|
|
179
|
+
if (this.BLE) {
|
|
180
|
+
await this.BLEparseStatus();
|
|
181
|
+
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
237
182
|
await this.openAPIparseStatus();
|
|
238
183
|
} else {
|
|
239
|
-
|
|
184
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
185
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
240
186
|
}
|
|
241
187
|
}
|
|
242
188
|
|
|
243
189
|
async BLEparseStatus(): Promise<void> {
|
|
244
|
-
this.debugLog(
|
|
190
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
245
191
|
|
|
246
192
|
// Battery
|
|
247
193
|
this.BatteryLevel = Number(this.battery);
|
|
@@ -250,39 +196,34 @@ export class Meter {
|
|
|
250
196
|
} else {
|
|
251
197
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
252
198
|
}
|
|
253
|
-
this.debugLog(
|
|
199
|
+
this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
254
200
|
|
|
255
201
|
// Humidity
|
|
256
202
|
if (!this.device.meter?.hide_humidity) {
|
|
257
203
|
this.CurrentRelativeHumidity = this.humidity!;
|
|
258
|
-
this.debugLog(
|
|
204
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
259
205
|
}
|
|
260
206
|
|
|
261
207
|
// Current Temperature
|
|
262
208
|
if (!this.device.meter?.hide_temperature) {
|
|
263
209
|
this.temperature < 0 ? 0 : this.temperature > 100 ? 100 : this.temperature;
|
|
264
210
|
this.CurrentTemperature = this.temperature;
|
|
265
|
-
this.debugLog(
|
|
211
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
|
|
266
212
|
}
|
|
267
213
|
}
|
|
268
214
|
|
|
269
215
|
async openAPIparseStatus(): Promise<void> {
|
|
270
|
-
|
|
271
|
-
|
|
216
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
217
|
+
// Current Relative Humidity
|
|
218
|
+
if (!this.device.meter?.hide_humidity) {
|
|
219
|
+
this.CurrentRelativeHumidity = this.Humidity!;
|
|
220
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
272
221
|
}
|
|
273
|
-
if (this.platform.config.credentials?.token) {
|
|
274
|
-
this.debugLog(`Meter: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
275
|
-
// Current Relative Humidity
|
|
276
|
-
if (!this.device.meter?.hide_humidity) {
|
|
277
|
-
this.CurrentRelativeHumidity = this.Humidity!;
|
|
278
|
-
this.debugLog(`Meter: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
279
|
-
}
|
|
280
222
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
223
|
+
// Current Temperature
|
|
224
|
+
if (!this.device.meter?.hide_temperature) {
|
|
225
|
+
this.CurrentTemperature = this.Temperature!;
|
|
226
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
|
|
286
227
|
}
|
|
287
228
|
}
|
|
288
229
|
|
|
@@ -290,22 +231,25 @@ export class Meter {
|
|
|
290
231
|
* Asks the SwitchBot API for the latest device information
|
|
291
232
|
*/
|
|
292
233
|
async refreshStatus(): Promise<void> {
|
|
293
|
-
if (this.
|
|
294
|
-
this.
|
|
234
|
+
if (this.BLE) {
|
|
235
|
+
await this.BLERefreshStatus();
|
|
236
|
+
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
237
|
+
await this.openAPIRefreshStatus();
|
|
295
238
|
} else {
|
|
296
|
-
this.
|
|
239
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
240
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
297
241
|
}
|
|
298
242
|
}
|
|
299
243
|
|
|
300
|
-
async
|
|
301
|
-
this.debugLog(
|
|
244
|
+
async BLERefreshStatus(): Promise<void> {
|
|
245
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
302
246
|
const switchbot = await this.platform.connectBLE();
|
|
303
247
|
// Convert to BLE Address
|
|
304
248
|
this.device.bleMac = this.device
|
|
305
249
|
.deviceId!.match(/.{1,2}/g)!
|
|
306
250
|
.join(':')
|
|
307
251
|
.toLowerCase();
|
|
308
|
-
this.debugLog(
|
|
252
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
309
253
|
this.getCustomBLEAddress(switchbot);
|
|
310
254
|
// Start to monitor advertisement packets
|
|
311
255
|
if (switchbot !== false) {
|
|
@@ -318,32 +262,28 @@ export class Meter {
|
|
|
318
262
|
// Set an event hander
|
|
319
263
|
switchbot.onadvertisement = (ad: ad) => {
|
|
320
264
|
this.address = ad.address;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
this.infoLog(this.device.bleMac);
|
|
324
|
-
this.infoLog(`Meter: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
|
|
325
|
-
this.infoLog(`Meter: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
|
|
326
|
-
}
|
|
265
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
266
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
327
267
|
if (ad.serviceData.humidity! > 0) {
|
|
328
268
|
// reject unreliable data
|
|
329
|
-
this.serviceData = ad.serviceData;
|
|
330
|
-
this.temperature = ad.serviceData.temperature!.c;
|
|
331
269
|
this.humidity = ad.serviceData.humidity;
|
|
332
|
-
this.battery = ad.serviceData.battery;
|
|
333
270
|
}
|
|
334
|
-
this.
|
|
271
|
+
this.serviceData = ad.serviceData;
|
|
272
|
+
this.temperature = ad.serviceData.temperature!.c;
|
|
273
|
+
this.battery = ad.serviceData.battery;
|
|
274
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
|
|
335
275
|
this.debugLog(
|
|
336
|
-
|
|
337
|
-
`temperature: ${
|
|
276
|
+
`${this.device.deviceType}: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
|
|
277
|
+
`temperature: ${superStringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
|
|
338
278
|
`battery: ${ad.serviceData.battery}`,
|
|
339
279
|
);
|
|
340
280
|
|
|
341
281
|
if (this.serviceData) {
|
|
342
282
|
this.connected = true;
|
|
343
|
-
this.debugLog(
|
|
283
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
344
284
|
} else {
|
|
345
285
|
this.connected = false;
|
|
346
|
-
this.debugLog(
|
|
286
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
347
287
|
}
|
|
348
288
|
};
|
|
349
289
|
// Wait 10 seconds
|
|
@@ -353,114 +293,73 @@ export class Meter {
|
|
|
353
293
|
// Stop to monitor
|
|
354
294
|
switchbot.stopScan();
|
|
355
295
|
if (this.connected) {
|
|
356
|
-
this.
|
|
296
|
+
this.BLEparseStatus();
|
|
357
297
|
this.updateHomeKitCharacteristics();
|
|
358
298
|
} else {
|
|
359
|
-
await this.
|
|
299
|
+
await this.BLERefreshConnection(switchbot);
|
|
360
300
|
}
|
|
361
301
|
})
|
|
362
302
|
.catch(async (e: any) => {
|
|
363
|
-
this.errorLog(`Meter: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
364
|
-
if (this.deviceLogging.includes('debug')) {
|
|
365
|
-
this.errorLog(
|
|
366
|
-
`Meter: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
if (this.platform.config.credentials?.token) {
|
|
370
|
-
this.warnLog(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
371
|
-
this.SwitchToOpenAPI = true;
|
|
372
|
-
this.openAPIRefreshStatus();
|
|
373
|
-
}
|
|
374
303
|
this.apiError(e);
|
|
304
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
305
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
306
|
+
await this.BLERefreshConnection(switchbot);
|
|
375
307
|
});
|
|
376
308
|
} else {
|
|
377
|
-
await this.
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
382
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
383
|
-
(async () => {
|
|
384
|
-
// Start to monitor advertisement packets
|
|
385
|
-
await switchbot.startScan({
|
|
386
|
-
model: 'T',
|
|
387
|
-
});
|
|
388
|
-
// Set an event handler
|
|
389
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
390
|
-
this.warnLog(`Meter: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
391
|
-
};
|
|
392
|
-
await switchbot.wait(10000);
|
|
393
|
-
// Stop to monitor
|
|
394
|
-
switchbot.stopScan();
|
|
395
|
-
})();
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
async BLEconnection(switchbot: any): Promise<void> {
|
|
400
|
-
this.errorLog(`Meter: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
401
|
-
if (this.platform.config.credentials?.token) {
|
|
402
|
-
this.warnLog(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
403
|
-
this.SwitchToOpenAPI = true;
|
|
404
|
-
await this.openAPIRefreshStatus();
|
|
309
|
+
await this.BLERefreshConnection(switchbot);
|
|
405
310
|
}
|
|
406
311
|
}
|
|
407
312
|
|
|
408
313
|
async openAPIRefreshStatus(): Promise<void> {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
this.debugLog(`Meter: ${this.accessory.displayName} d: ${d}`);
|
|
437
|
-
});
|
|
438
|
-
res.on('end', () => {
|
|
439
|
-
try {
|
|
440
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
441
|
-
this.debugLog(`Meter: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
442
|
-
this.Humidity = this.deviceStatus.body.humidity!;
|
|
443
|
-
this.Temperature = this.deviceStatus.body.temperature!;
|
|
444
|
-
this.parseStatus();
|
|
445
|
-
this.updateHomeKitCharacteristics();
|
|
446
|
-
} catch (e: any) {
|
|
447
|
-
this.errorLog(`Meter: ${this.accessory.displayName} error message: ${e.message}`);
|
|
448
|
-
}
|
|
449
|
-
});
|
|
314
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
315
|
+
try {
|
|
316
|
+
const t = Date.now();
|
|
317
|
+
const nonce = 'requestID';
|
|
318
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
319
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
320
|
+
const sign = signTerm.toString('base64');
|
|
321
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
322
|
+
const options = {
|
|
323
|
+
hostname: HostDomain,
|
|
324
|
+
port: 443,
|
|
325
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
326
|
+
method: 'GET',
|
|
327
|
+
headers: {
|
|
328
|
+
Authorization: this.platform.config.credentials?.token,
|
|
329
|
+
sign: sign,
|
|
330
|
+
nonce: nonce,
|
|
331
|
+
t: t,
|
|
332
|
+
'Content-Type': 'application/json',
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
const req = https.request(options, (res) => {
|
|
336
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
337
|
+
let rawData = '';
|
|
338
|
+
res.on('data', (d) => {
|
|
339
|
+
rawData += d;
|
|
340
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
450
341
|
});
|
|
451
|
-
|
|
452
|
-
|
|
342
|
+
res.on('end', () => {
|
|
343
|
+
try {
|
|
344
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
345
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
346
|
+
this.Humidity = this.deviceStatus.body.humidity!;
|
|
347
|
+
this.Temperature = this.deviceStatus.body.temperature!;
|
|
348
|
+
this.openAPIparseStatus();
|
|
349
|
+
this.updateHomeKitCharacteristics();
|
|
350
|
+
} catch (e: any) {
|
|
351
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
352
|
+
}
|
|
453
353
|
});
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
this.errorLog(
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
354
|
+
});
|
|
355
|
+
req.on('error', (e: any) => {
|
|
356
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
357
|
+
});
|
|
358
|
+
req.end();
|
|
359
|
+
} catch (e: any) {
|
|
360
|
+
this.apiError(e);
|
|
361
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
362
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
464
363
|
}
|
|
465
364
|
}
|
|
466
365
|
|
|
@@ -472,44 +371,209 @@ export class Meter {
|
|
|
472
371
|
const entry = { time: Math.round(new Date().valueOf() / 1000) };
|
|
473
372
|
if (!this.device.meter?.hide_humidity) {
|
|
474
373
|
if (this.CurrentRelativeHumidity === undefined) {
|
|
475
|
-
this.debugLog(
|
|
374
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
476
375
|
} else {
|
|
376
|
+
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
|
|
477
377
|
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
|
|
478
|
-
this.debugLog(
|
|
479
|
-
|
|
480
|
-
|
|
378
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
379
|
+
+ ` CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
380
|
+
if (this.device.mqttURL) {
|
|
381
|
+
mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
|
|
382
|
+
}
|
|
383
|
+
if (this.device.history) {
|
|
384
|
+
entry['humidity'] = this.CurrentRelativeHumidity;
|
|
385
|
+
}
|
|
481
386
|
}
|
|
482
387
|
}
|
|
483
388
|
if (!this.device.meter?.hide_temperature) {
|
|
484
389
|
if (this.CurrentTemperature === undefined) {
|
|
485
|
-
this.debugLog(
|
|
390
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
|
|
486
391
|
} else {
|
|
392
|
+
if (this.device.mqttURL) {
|
|
393
|
+
mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
|
|
394
|
+
}
|
|
395
|
+
if (this.device.history) {
|
|
396
|
+
entry['temp'] = this.CurrentTemperature;
|
|
397
|
+
}
|
|
398
|
+
this.accessory.context.CurrentTemperature = this.CurrentTemperature;
|
|
487
399
|
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
|
|
488
|
-
this.debugLog(
|
|
489
|
-
|
|
490
|
-
entry['temp'] = this.CurrentTemperature;
|
|
400
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
|
|
401
|
+
|
|
491
402
|
}
|
|
492
403
|
}
|
|
493
|
-
if (this.
|
|
404
|
+
if (this.BLE) {
|
|
494
405
|
if (this.BatteryLevel === undefined) {
|
|
495
|
-
this.debugLog(
|
|
406
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
496
407
|
} else {
|
|
408
|
+
if (this.device.mqttURL) {
|
|
409
|
+
mqttmessage.push(`"battery": ${this.BatteryLevel}`);
|
|
410
|
+
}
|
|
411
|
+
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
497
412
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
498
|
-
this.debugLog(
|
|
499
|
-
mqttmessage.push(`"battery": ${this.BatteryLevel}`);
|
|
413
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
500
414
|
}
|
|
501
415
|
if (this.StatusLowBattery === undefined) {
|
|
502
|
-
this.debugLog(
|
|
416
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
503
417
|
} else {
|
|
418
|
+
if (this.device.mqttURL) {
|
|
419
|
+
mqttmessage.push(`"lowBattery": ${this.StatusLowBattery}`);
|
|
420
|
+
}
|
|
421
|
+
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
504
422
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
505
|
-
this.debugLog(
|
|
506
|
-
mqttmessage.push(`"lowBattery": ${this.StatusLowBattery}`);
|
|
423
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
507
424
|
}
|
|
508
425
|
}
|
|
509
|
-
this.
|
|
426
|
+
if (this.device.mqttURL) {
|
|
427
|
+
this.mqttPublish(`{${mqttmessage.join(',')}}`);
|
|
428
|
+
}
|
|
510
429
|
if (this.CurrentRelativeHumidity > 0) {
|
|
511
430
|
// reject unreliable data
|
|
512
|
-
this.
|
|
431
|
+
if (this.device.history) {
|
|
432
|
+
this.historyService?.addEntry(entry);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/*
|
|
438
|
+
* Publish MQTT message for topics of
|
|
439
|
+
* 'homebridge-switchbot/meter/xx:xx:xx:xx:xx:xx'
|
|
440
|
+
*/
|
|
441
|
+
mqttPublish(message: any) {
|
|
442
|
+
const mac = this.device.deviceId
|
|
443
|
+
?.toLowerCase()
|
|
444
|
+
.match(/[\s\S]{1,2}/g)
|
|
445
|
+
?.join(':');
|
|
446
|
+
const options = this.device.mqttPubOptions || {};
|
|
447
|
+
this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
|
|
448
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${superStringify(options)}`);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/*
|
|
452
|
+
* Setup MQTT hadler if URL is specifed.
|
|
453
|
+
*/
|
|
454
|
+
async setupMqtt(device: device & devicesConfig): Promise<void> {
|
|
455
|
+
if (device.mqttURL) {
|
|
456
|
+
try {
|
|
457
|
+
this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
|
|
458
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
|
|
459
|
+
this.mqttClient.on('error', (e: Error) => {
|
|
460
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
|
|
461
|
+
});
|
|
462
|
+
} catch (e) {
|
|
463
|
+
this.mqttClient = null;
|
|
464
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/*
|
|
470
|
+
* Setup EVE history graph feature if enabled.
|
|
471
|
+
*/
|
|
472
|
+
async setupHistoryService(device: device & devicesConfig): Promise<void> {
|
|
473
|
+
const mac = this.device
|
|
474
|
+
.deviceId!.match(/.{1,2}/g)!
|
|
475
|
+
.join(':')
|
|
476
|
+
.toLowerCase();
|
|
477
|
+
this.historyService = device.history
|
|
478
|
+
? new this.platform.fakegatoAPI('room', this.accessory, {
|
|
479
|
+
log: this.platform.log,
|
|
480
|
+
storage: 'fs',
|
|
481
|
+
filename: `${hostname().split('.')[0]}_${mac}_persist.json`,
|
|
482
|
+
})
|
|
483
|
+
: null;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
async getCustomBLEAddress(switchbot: any) {
|
|
487
|
+
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
488
|
+
(async () => {
|
|
489
|
+
// Start to monitor advertisement packets
|
|
490
|
+
await switchbot.startScan({
|
|
491
|
+
model: 'T',
|
|
492
|
+
});
|
|
493
|
+
// Set an event handler
|
|
494
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
495
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
|
|
496
|
+
};
|
|
497
|
+
await switchbot.wait(10000);
|
|
498
|
+
// Stop to monitor
|
|
499
|
+
switchbot.stopScan();
|
|
500
|
+
})();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
505
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
506
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
507
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
|
|
508
|
+
await this.openAPIRefreshStatus();
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
async scan(device: device & devicesConfig): Promise<void> {
|
|
513
|
+
if (device.scanDuration) {
|
|
514
|
+
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
515
|
+
if (this.BLE) {
|
|
516
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
520
|
+
if (this.BLE) {
|
|
521
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
527
|
+
switch (res.statusCode) {
|
|
528
|
+
case 151:
|
|
529
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
530
|
+
break;
|
|
531
|
+
case 152:
|
|
532
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
|
|
533
|
+
break;
|
|
534
|
+
case 160:
|
|
535
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
|
|
536
|
+
break;
|
|
537
|
+
case 161:
|
|
538
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
|
|
539
|
+
this.offlineOff();
|
|
540
|
+
break;
|
|
541
|
+
case 171:
|
|
542
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
|
|
543
|
+
this.offlineOff();
|
|
544
|
+
break;
|
|
545
|
+
case 190:
|
|
546
|
+
this.errorLog(
|
|
547
|
+
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
548
|
+
` Or command: ${superStringify(res)} format is invalid`,
|
|
549
|
+
);
|
|
550
|
+
break;
|
|
551
|
+
case 100:
|
|
552
|
+
if (this.platform.debugMode) {
|
|
553
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
|
|
554
|
+
}
|
|
555
|
+
break;
|
|
556
|
+
default:
|
|
557
|
+
if (this.platform.debugMode) {
|
|
558
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
async offlineOff(): Promise<void> {
|
|
564
|
+
if (this.device.offline) {
|
|
565
|
+
if (!this.device.meter?.hide_humidity) {
|
|
566
|
+
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity,
|
|
567
|
+
this.accessory.context.CurrentRelativeHumidity);
|
|
568
|
+
}
|
|
569
|
+
if (!this.device.meter?.hide_temperature) {
|
|
570
|
+
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.accessory.context.CurrentTemperature);
|
|
571
|
+
}
|
|
572
|
+
if (this.BLE) {
|
|
573
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.accessory.context.BatteryLevel);
|
|
574
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.accessory.context.StatusLowBattery);
|
|
575
|
+
}
|
|
576
|
+
await this.updateHomeKitCharacteristics();
|
|
513
577
|
}
|
|
514
578
|
}
|
|
515
579
|
|
|
@@ -520,11 +584,62 @@ export class Meter {
|
|
|
520
584
|
if (!this.device.meter?.hide_temperature) {
|
|
521
585
|
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
|
|
522
586
|
}
|
|
523
|
-
if (this.
|
|
587
|
+
if (this.BLE) {
|
|
524
588
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
525
589
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
526
590
|
}
|
|
527
|
-
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
594
|
+
let FirmwareRevision: string;
|
|
595
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
596
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
597
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
598
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
599
|
+
if (accessory.context.FirmwareRevision) {
|
|
600
|
+
FirmwareRevision = accessory.context.FirmwareRevision;
|
|
601
|
+
} else if (device.firmware) {
|
|
602
|
+
FirmwareRevision = device.firmware;
|
|
603
|
+
} else {
|
|
604
|
+
FirmwareRevision = this.platform.version;
|
|
605
|
+
}
|
|
606
|
+
return FirmwareRevision;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
async context() {
|
|
610
|
+
if (this.CurrentRelativeHumidity === undefined) {
|
|
611
|
+
this.CurrentRelativeHumidity = 0;
|
|
612
|
+
} else {
|
|
613
|
+
this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity;
|
|
614
|
+
}
|
|
615
|
+
if (this.CurrentTemperature === undefined) {
|
|
616
|
+
this.CurrentTemperature = 0;
|
|
617
|
+
} else {
|
|
618
|
+
this.CurrentTemperature = this.accessory.context.CurrentTemperature;
|
|
619
|
+
}
|
|
620
|
+
if (this.BLE) {
|
|
621
|
+
if (this.BatteryLevel === undefined) {
|
|
622
|
+
this.BatteryLevel = 100;
|
|
623
|
+
} else {
|
|
624
|
+
this.BatteryLevel = this.accessory.context.BatteryLevel;
|
|
625
|
+
}
|
|
626
|
+
if (this.StatusLowBattery === undefined) {
|
|
627
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
628
|
+
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
629
|
+
} else {
|
|
630
|
+
this.StatusLowBattery = this.accessory.context.StatusLowBattery;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
636
|
+
if (device.refreshRate) {
|
|
637
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
638
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
639
|
+
} else if (this.platform.config.options!.refreshRate) {
|
|
640
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
641
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
642
|
+
}
|
|
528
643
|
}
|
|
529
644
|
|
|
530
645
|
async config(device: device & devicesConfig): Promise<void> {
|
|
@@ -532,8 +647,14 @@ export class Meter {
|
|
|
532
647
|
if (device.meter) {
|
|
533
648
|
config = device.meter;
|
|
534
649
|
}
|
|
535
|
-
if (device.
|
|
536
|
-
config['
|
|
650
|
+
if (device.connectionType !== undefined) {
|
|
651
|
+
config['connectionType'] = device.connectionType;
|
|
652
|
+
}
|
|
653
|
+
if (device.external !== undefined) {
|
|
654
|
+
config['external'] = device.external;
|
|
655
|
+
}
|
|
656
|
+
if (device.mqttURL !== undefined) {
|
|
657
|
+
config['mqttURL'] = device.mqttURL;
|
|
537
658
|
}
|
|
538
659
|
if (device.logging !== undefined) {
|
|
539
660
|
config['logging'] = device.logging;
|
|
@@ -545,63 +666,24 @@ export class Meter {
|
|
|
545
666
|
config['scanDuration'] = device.scanDuration;
|
|
546
667
|
}
|
|
547
668
|
if (Object.entries(config).length !== 0) {
|
|
548
|
-
this.infoLog(
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
553
|
-
if (device.refreshRate) {
|
|
554
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
555
|
-
this.debugLog(`Meter: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
556
|
-
} else if (this.platform.config.options!.refreshRate) {
|
|
557
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
558
|
-
this.debugLog(`Meter: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
async scan(device: device & devicesConfig): Promise<void> {
|
|
563
|
-
if (device.scanDuration) {
|
|
564
|
-
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
565
|
-
if (device.ble) {
|
|
566
|
-
this.debugLog(`Meter: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
567
|
-
}
|
|
568
|
-
} else {
|
|
569
|
-
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
570
|
-
if (this.device.ble) {
|
|
571
|
-
this.debugLog(`Meter: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
572
|
-
}
|
|
669
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
|
|
573
670
|
}
|
|
574
671
|
}
|
|
575
672
|
|
|
576
673
|
async logs(device: device & devicesConfig): Promise<void> {
|
|
577
674
|
if (this.platform.debugMode) {
|
|
578
675
|
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
579
|
-
this.debugLog(
|
|
676
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
580
677
|
} else if (device.logging) {
|
|
581
678
|
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
582
|
-
this.debugLog(
|
|
679
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
583
680
|
} else if (this.platform.config.options?.logging) {
|
|
584
681
|
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
585
|
-
this.debugLog(
|
|
682
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
586
683
|
} else {
|
|
587
684
|
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
588
|
-
this.debugLog(
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
593
|
-
let FirmwareRevision: string;
|
|
594
|
-
this.debugLog(`Meter: ${this.accessory.displayName} accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
595
|
-
this.debugLog(`Meter: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
596
|
-
this.debugLog(`Meter: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
597
|
-
if (accessory.context.FirmwareRevision) {
|
|
598
|
-
FirmwareRevision = accessory.context.FirmwareRevision;
|
|
599
|
-
} else if (device.firmware) {
|
|
600
|
-
FirmwareRevision = device.firmware;
|
|
601
|
-
} else {
|
|
602
|
-
FirmwareRevision = this.platform.version;
|
|
685
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
603
686
|
}
|
|
604
|
-
return FirmwareRevision;
|
|
605
687
|
}
|
|
606
688
|
|
|
607
689
|
/**
|
|
@@ -619,12 +701,28 @@ export class Meter {
|
|
|
619
701
|
}
|
|
620
702
|
}
|
|
621
703
|
|
|
704
|
+
debugWarnLog(...log: any[]): void {
|
|
705
|
+
if (this.enablingDeviceLogging()) {
|
|
706
|
+
if (this.deviceLogging?.includes('debug')) {
|
|
707
|
+
this.platform.log.warn('[DEBUG]', String(...log));
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
622
712
|
errorLog(...log: any[]): void {
|
|
623
713
|
if (this.enablingDeviceLogging()) {
|
|
624
714
|
this.platform.log.error(String(...log));
|
|
625
715
|
}
|
|
626
716
|
}
|
|
627
717
|
|
|
718
|
+
debugErrorLog(...log: any[]): void {
|
|
719
|
+
if (this.enablingDeviceLogging()) {
|
|
720
|
+
if (this.deviceLogging?.includes('debug')) {
|
|
721
|
+
this.platform.log.error('[DEBUG]', String(...log));
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
628
726
|
debugLog(...log: any[]): void {
|
|
629
727
|
if (this.enablingDeviceLogging()) {
|
|
630
728
|
if (this.deviceLogging === 'debug') {
|