@switchbot/homebridge-switchbot 1.12.7-beta.5 → 1.12.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/config.schema.json +6 -6
  3. package/dist/device/bot.js +2 -2
  4. package/dist/device/bot.js.map +1 -1
  5. package/dist/device/colorbulb.d.ts +0 -6
  6. package/dist/device/colorbulb.d.ts.map +1 -1
  7. package/dist/device/colorbulb.js +74 -89
  8. package/dist/device/colorbulb.js.map +1 -1
  9. package/dist/device/curtain.js +1 -1
  10. package/dist/device/curtain.js.map +1 -1
  11. package/dist/device/humidifier.js +2 -2
  12. package/dist/device/humidifier.js.map +1 -1
  13. package/dist/device/lock.d.ts.map +1 -1
  14. package/dist/device/lock.js +1 -21
  15. package/dist/device/lock.js.map +1 -1
  16. package/dist/device/meter.d.ts +0 -1
  17. package/dist/device/meter.d.ts.map +1 -1
  18. package/dist/device/meter.js +1 -14
  19. package/dist/device/meter.js.map +1 -1
  20. package/dist/device/meterplus.d.ts +76 -0
  21. package/dist/device/meterplus.d.ts.map +1 -0
  22. package/dist/device/meterplus.js +464 -0
  23. package/dist/device/meterplus.js.map +1 -0
  24. package/dist/device/plug.js +1 -1
  25. package/dist/device/plug.js.map +1 -1
  26. package/dist/device/striplight.d.ts +90 -0
  27. package/dist/device/striplight.d.ts.map +1 -0
  28. package/dist/device/striplight.js +487 -0
  29. package/dist/device/striplight.js.map +1 -0
  30. package/dist/platform.d.ts +2 -0
  31. package/dist/platform.d.ts.map +1 -1
  32. package/dist/platform.js +119 -9
  33. package/dist/platform.js.map +1 -1
  34. package/package.json +76 -76
  35. package/src/device/bot.ts +2 -2
  36. package/src/device/colorbulb.ts +74 -89
  37. package/src/device/curtain.ts +1 -1
  38. package/src/device/humidifier.ts +2 -2
  39. package/src/device/lock.ts +1 -21
  40. package/src/device/meter.ts +1 -13
  41. package/src/device/meterplus.ts +518 -0
  42. package/src/device/plug.ts +1 -1
  43. package/src/device/striplight.ts +583 -0
  44. package/src/platform.ts +127 -9
@@ -87,7 +87,7 @@ export class Curtain {
87
87
 
88
88
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
89
89
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
90
- // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Lightbulb, 'NAME', 'USER_DEFINED_SUBTYPE');
90
+ // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.WindowCovering, 'NAME', 'USER_DEFINED_SUBTYPE');
91
91
 
92
92
  // set the service name, this is what is displayed as the default name on the Home app
93
93
  // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
@@ -79,7 +79,7 @@ export class Humidifier {
79
79
  .setCharacteristic(this.platform.Characteristic.Model, 'W0801800')
80
80
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
81
81
 
82
- // get the LightBulb service if it exists, otherwise create a new LightBulb service
82
+ // get the service if it exists, otherwise create a new service
83
83
  // you can create multiple services for each accessory
84
84
  (this.humidifierService =
85
85
  accessory.getService(this.platform.Service.HumidifierDehumidifier) || accessory.addService(this.platform.Service.HumidifierDehumidifier)),
@@ -87,7 +87,7 @@ export class Humidifier {
87
87
 
88
88
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
89
89
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
90
- // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Lightbulb, 'NAME', 'USER_DEFINED_SUBTYPE');
90
+ // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.HumidifierDehumidifier, 'NAME', 'USER_DEFINED_SUBTYPE');
91
91
 
92
92
  // set the service name, this is what is displayed as the default name on the Home app
93
93
  // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
@@ -62,7 +62,7 @@ export class Lock {
62
62
 
63
63
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
64
64
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
65
- // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Lightbulb, 'NAME', 'USER_DEFINED_SUBTYPE');
65
+ // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.LockMechanism, 'NAME', 'USER_DEFINED_SUBTYPE');
66
66
 
67
67
  // set the service name, this is what is displayed as the default name on the Home app
68
68
  // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
@@ -119,26 +119,6 @@ export class Lock {
119
119
  }
120
120
 
121
121
  async refreshStatus(): Promise<void> {
122
- const switchbot = await this.platform.connectBLE();
123
- // Convert to BLE Address
124
- this.device.bleMac = this.device
125
- .deviceId!.match(/.{1,2}/g)!
126
- .join(':')
127
- .toLowerCase();
128
- this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
129
- (async () => {
130
- // Start to monitor advertisement packets
131
- await switchbot.startScan({
132
- model: 'o',
133
- });
134
- // Set an event handler
135
- switchbot.onadvertisement = (ad: any) => {
136
- this.warnLog(JSON.stringify(ad, null, ' '));
137
- };
138
- await switchbot.wait(10000);
139
- // Stop to monitor
140
- switchbot.stopScan();
141
- })();
142
122
  try {
143
123
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
144
124
  this.debugLog(`Lock: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
@@ -78,7 +78,7 @@ export class Meter {
78
78
  accessory
79
79
  .getService(this.platform.Service.AccessoryInformation)!
80
80
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
81
- .setCharacteristic(this.platform.Characteristic.Model, this.model(device))
81
+ .setCharacteristic(this.platform.Characteristic.Model, 'METERTH-S1')
82
82
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
83
83
 
84
84
  // Temperature Sensor Service
@@ -408,18 +408,6 @@ export class Meter {
408
408
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
409
409
  }
410
410
 
411
- model(device: device & devicesConfig): CharacteristicValue {
412
- let model: string;
413
- if (device.deviceType === 'Meter Plus (US)') {
414
- model = 'W2301500';
415
- } else if (device.deviceType === 'Meter Plus (JP)') {
416
- model = 'W2201500';
417
- } else {
418
- model = 'S1';
419
- }
420
- return model;
421
- }
422
-
423
411
  async config(device: device & devicesConfig): Promise<void> {
424
412
  let config = {};
425
413
  if (device.meter) {
@@ -0,0 +1,518 @@
1
+ import { interval, Subject } from 'rxjs';
2
+ import { skipWhile } from 'rxjs/operators';
3
+ import { SwitchBotPlatform } from '../platform';
4
+ import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
5
+ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature, deviceStatus } from '../settings';
6
+
7
+ /**
8
+ * Platform Accessory
9
+ * An instance of this class is created for each accessory your platform registers
10
+ * Each accessory may expose multiple services of different service types.
11
+ */
12
+ export class MeterPlus {
13
+ // Services
14
+ batteryService?: Service;
15
+ temperatureservice?: Service;
16
+ humidityservice?: Service;
17
+
18
+ // Characteristic Values
19
+ CurrentRelativeHumidity!: CharacteristicValue;
20
+ CurrentRelativeHumidityCached!: CharacteristicValue;
21
+ CurrentTemperature?: CharacteristicValue;
22
+ CurrentTemperatureCached?: CharacteristicValue;
23
+ BatteryLevel?: CharacteristicValue;
24
+ ChargingState?: CharacteristicValue;
25
+ StatusLowBattery?: CharacteristicValue;
26
+ Active!: CharacteristicValue;
27
+ WaterLevel!: CharacteristicValue;
28
+
29
+ // OpenAPI Others
30
+ Temperature: deviceStatus['temperature'];
31
+ Humidity: deviceStatus['humidity'];
32
+ deviceStatus!: deviceStatusResponse;
33
+
34
+ // BLE Others
35
+ connected?: boolean;
36
+ switchbot!: switchbot;
37
+ SwitchToOpenAPI?: boolean;
38
+ serviceData!: serviceData;
39
+ address!: ad['address'];
40
+ temperature!: temperature['c'];
41
+ battery!: serviceData['battery'];
42
+ humidity!: serviceData['humidity'];
43
+
44
+ // Config
45
+ scanDuration!: number;
46
+ deviceLogging!: string;
47
+ deviceRefreshRate!: number;
48
+
49
+ // Updates
50
+ meterUpdateInProgress!: boolean;
51
+ doMeterUpdate: Subject<void>;
52
+
53
+ constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
54
+ // default placeholders
55
+ this.logs(device);
56
+ this.scan(device);
57
+ this.refreshRate(device);
58
+ this.config(device);
59
+ if (this.CurrentRelativeHumidity === undefined) {
60
+ this.CurrentRelativeHumidity = 0;
61
+ } else {
62
+ this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity;
63
+ }
64
+ if (this.CurrentTemperature === undefined) {
65
+ this.CurrentTemperature = 0;
66
+ } else {
67
+ this.CurrentTemperature = this.accessory.context.CurrentTemperature;
68
+ }
69
+
70
+ // this is subject we use to track when we need to POST changes to the SwitchBot API
71
+ this.doMeterUpdate = new Subject();
72
+ this.meterUpdateInProgress = false;
73
+
74
+ // Retrieve initial values and updateHomekit
75
+ this.refreshStatus();
76
+
77
+ // set accessory information
78
+ accessory
79
+ .getService(this.platform.Service.AccessoryInformation)!
80
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
81
+ .setCharacteristic(this.platform.Characteristic.Model, this.model(device))
82
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
83
+
84
+ // Temperature Sensor Service
85
+ if (device.meter?.hide_temperature) {
86
+ this.debugLog(`Meter Plus: ${accessory.displayName} Removing Temperature Sensor Service`);
87
+ this.temperatureservice = this.accessory.getService(this.platform.Service.TemperatureSensor);
88
+ accessory.removeService(this.temperatureservice!);
89
+ } else if (!this.temperatureservice) {
90
+ this.debugLog(`Meter Plus: ${accessory.displayName} Add Temperature Sensor Service`);
91
+ (this.temperatureservice =
92
+ this.accessory.getService(this.platform.Service.TemperatureSensor) || this.accessory.addService(this.platform.Service.TemperatureSensor)),
93
+ `${accessory.displayName} Temperature Sensor`;
94
+
95
+ this.temperatureservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
96
+
97
+ this.temperatureservice
98
+ .getCharacteristic(this.platform.Characteristic.CurrentTemperature)
99
+ .setProps({
100
+ unit: Units['CELSIUS'],
101
+ validValueRanges: [-273.15, 100],
102
+ minValue: -273.15,
103
+ maxValue: 100,
104
+ minStep: 0.1,
105
+ })
106
+ .onGet(() => {
107
+ return this.CurrentTemperature!;
108
+ });
109
+ } else {
110
+ this.debugLog(`Meter Plus: ${accessory.displayName} Temperature Sensor Service Not Added`);
111
+ }
112
+
113
+ // Humidity Sensor Service
114
+ if (device.meter?.hide_humidity) {
115
+ this.debugLog(`Meter Plus: ${accessory.displayName} Removing Humidity Sensor Service`);
116
+ this.humidityservice = this.accessory.getService(this.platform.Service.HumiditySensor);
117
+ accessory.removeService(this.humidityservice!);
118
+ } else if (!this.humidityservice) {
119
+ this.debugLog(`Meter Plus: ${accessory.displayName} Add Humidity Sensor Service`);
120
+ (this.humidityservice =
121
+ this.accessory.getService(this.platform.Service.HumiditySensor) || this.accessory.addService(this.platform.Service.HumiditySensor)),
122
+ `${accessory.displayName} Humidity Sensor`;
123
+
124
+ this.humidityservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
125
+
126
+ this.humidityservice
127
+ .getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
128
+ .setProps({
129
+ minStep: 0.1,
130
+ })
131
+ .onGet(() => {
132
+ return this.CurrentRelativeHumidity;
133
+ });
134
+ } else {
135
+ this.debugLog(`Meter Plus: ${accessory.displayName} Humidity Sensor Service Not Added`);
136
+ }
137
+
138
+ // Battery Service
139
+ if (!device.ble) {
140
+ this.debugLog(`Meter Plus: ${accessory.displayName} Removing Battery Service`);
141
+ this.batteryService = this.accessory.getService(this.platform.Service.Battery);
142
+ accessory.removeService(this.batteryService!);
143
+ } else if (device.ble && !this.batteryService) {
144
+ this.debugLog(`Meter Plus: ${accessory.displayName} Add Battery Service`);
145
+ (this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
146
+ `${accessory.displayName} Battery`;
147
+
148
+ this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
149
+
150
+ this.batteryService.setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.Characteristic.ChargingState.NOT_CHARGEABLE);
151
+ } else {
152
+ this.debugLog(`Meter Plus: ${accessory.displayName} Battery Service Not Added`);
153
+ }
154
+
155
+ // Retrieve initial values and updateHomekit
156
+ this.updateHomeKitCharacteristics();
157
+
158
+ // Start an update interval
159
+ interval(this.deviceRefreshRate * 1000)
160
+ .pipe(skipWhile(() => this.meterUpdateInProgress))
161
+ .subscribe(async () => {
162
+ await this.refreshStatus();
163
+ });
164
+ }
165
+
166
+ /**
167
+ * Parse the device status from the SwitchBot api
168
+ */
169
+ async parseStatus(): Promise<void> {
170
+ if (this.SwitchToOpenAPI || !this.device.ble) {
171
+ await this.openAPIparseStatus();
172
+ } else {
173
+ await this.BLEparseStatus();
174
+ }
175
+ }
176
+
177
+ async BLEparseStatus(): Promise<void> {
178
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} BLE parseStatus`);
179
+
180
+ // Battery
181
+ this.BatteryLevel = Number(this.battery);
182
+ if (this.BatteryLevel < 15) {
183
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
184
+ } else {
185
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
186
+ }
187
+ this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
188
+
189
+ // Humidity
190
+ if (!this.device.meter?.hide_humidity) {
191
+ this.CurrentRelativeHumidity = this.humidity!;
192
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
193
+ }
194
+
195
+ // Current Temperature
196
+ if (!this.device.meter?.hide_temperature) {
197
+ this.temperature < 0 ? 0 : this.temperature > 100 ? 100 : this.temperature;
198
+ this.CurrentTemperature = this.temperature;
199
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
200
+ }
201
+ }
202
+
203
+ async openAPIparseStatus(): Promise<void> {
204
+ if (this.device.ble) {
205
+ this.SwitchToOpenAPI = false;
206
+ }
207
+ if (this.platform.config.credentials?.openToken) {
208
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} OpenAPI parseStatus`);
209
+ // Current Relative Humidity
210
+ if (!this.device.meter?.hide_humidity) {
211
+ this.CurrentRelativeHumidity = this.Humidity!;
212
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
213
+ }
214
+
215
+ // Current Temperature
216
+ if (!this.device.meter?.hide_temperature) {
217
+ this.CurrentTemperature = this.Temperature!;
218
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
219
+ }
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Asks the SwitchBot API for the latest device information
225
+ */
226
+ async refreshStatus(): Promise<void> {
227
+ if (this.device.ble) {
228
+ this.BLErefreshStatus();
229
+ } else {
230
+ this.openAPIRefreshStatus();
231
+ }
232
+ }
233
+
234
+ async BLErefreshStatus(): Promise<void> {
235
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} BLE RefreshStatus`);
236
+ const switchbot = await this.platform.connectBLE();
237
+ // Convert to BLE Address
238
+ this.device.bleMac = this.device
239
+ .deviceId!.match(/.{1,2}/g)!
240
+ .join(':')
241
+ .toLowerCase();
242
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
243
+ this.getCustomBLEAddress(switchbot);
244
+ // Start to monitor advertisement packets
245
+ if (switchbot !== false) {
246
+ switchbot
247
+ .startScan({
248
+ model: 'i',
249
+ id: this.device.bleMac,
250
+ })
251
+ .then(() => {
252
+ // Set an event hander
253
+ switchbot.onadvertisement = (ad: ad) => {
254
+ this.address = ad.address;
255
+ if (this.deviceLogging.includes('debug')) {
256
+ this.infoLog(this.address);
257
+ this.infoLog(this.device.bleMac);
258
+ this.infoLog(`Meter Plus: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
259
+ this.infoLog(`Meter Plus: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
260
+ }
261
+ this.serviceData = ad.serviceData;
262
+ this.temperature = ad.serviceData.temperature!.c;
263
+ this.humidity = ad.serviceData.humidity;
264
+ this.battery = ad.serviceData.battery;
265
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
266
+ this.debugLog(
267
+ `Meter Plus: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
268
+ `temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
269
+ `battery: ${ad.serviceData.battery}`,
270
+ );
271
+
272
+ if (this.serviceData) {
273
+ this.connected = true;
274
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} connected: ${this.connected}`);
275
+ } else {
276
+ this.connected = false;
277
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} connected: ${this.connected}`);
278
+ }
279
+ };
280
+ // Wait 10 seconds
281
+ return switchbot.wait(this.scanDuration * 1000);
282
+ })
283
+ .then(async () => {
284
+ // Stop to monitor
285
+ switchbot.stopScan();
286
+ if (this.connected) {
287
+ this.parseStatus();
288
+ this.updateHomeKitCharacteristics();
289
+ } else {
290
+ await this.BLEconnection(switchbot);
291
+ }
292
+ })
293
+ .catch(async (e: any) => {
294
+ this.errorLog(`Meter Plus: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
295
+ if (this.deviceLogging.includes('debug')) {
296
+ this.errorLog(
297
+ `Meter Plus: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
298
+ );
299
+ }
300
+ if (this.platform.config.credentials?.openToken) {
301
+ this.warnLog(`Meter Plus: ${this.accessory.displayName} Using OpenAPI Connection`);
302
+ this.SwitchToOpenAPI = true;
303
+ this.openAPIRefreshStatus();
304
+ }
305
+ this.apiError(e);
306
+ });
307
+ } else {
308
+ await this.BLEconnection(switchbot);
309
+ }
310
+ }
311
+
312
+ async getCustomBLEAddress(switchbot: any) {
313
+ if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
314
+ (async () => {
315
+ // Start to monitor advertisement packets
316
+ await switchbot.startScan({
317
+ model: 'i',
318
+ });
319
+ // Set an event handler
320
+ switchbot.onadvertisement = (ad: any) => {
321
+ this.warnLog(JSON.stringify(ad, null, ' '));
322
+ };
323
+ await switchbot.wait(10000);
324
+ // Stop to monitor
325
+ switchbot.stopScan();
326
+ })();
327
+ }
328
+ }
329
+
330
+ async BLEconnection(switchbot: any): Promise<void> {
331
+ this.errorLog(`Meter Plus: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
332
+ if (this.platform.config.credentials?.openToken) {
333
+ this.warnLog(`Meter Plus: ${this.accessory.displayName} Using OpenAPI Connection`);
334
+ this.SwitchToOpenAPI = true;
335
+ await this.openAPIRefreshStatus();
336
+ }
337
+ }
338
+
339
+ async openAPIRefreshStatus(): Promise<void> {
340
+ if (this.platform.config.credentials?.openToken) {
341
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} OpenAPI RefreshStatus`);
342
+ try {
343
+ this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
344
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
345
+ this.Humidity = this.deviceStatus.body.humidity!;
346
+ this.Temperature = this.deviceStatus.body.temperature!;
347
+ this.parseStatus();
348
+ this.updateHomeKitCharacteristics();
349
+ } catch (e: any) {
350
+ this.errorLog(`Meter Plus: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
351
+ if (this.deviceLogging.includes('debug')) {
352
+ this.errorLog(
353
+ `Meter Plus: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` +
354
+ ` Error Message: ${JSON.stringify(e.message)}`,
355
+ );
356
+ }
357
+ this.apiError(e);
358
+ }
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Updates the status for each of the HomeKit Characteristics
364
+ */
365
+ async updateHomeKitCharacteristics(): Promise<void> {
366
+ if (!this.device.meter?.hide_humidity) {
367
+ if (this.CurrentRelativeHumidity === undefined) {
368
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
369
+ } else {
370
+ this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
371
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
372
+ }
373
+ }
374
+ if (!this.device.meter?.hide_temperature) {
375
+ if (this.CurrentTemperature === undefined) {
376
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
377
+ } else {
378
+ this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
379
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
380
+ }
381
+ }
382
+ if (this.device.ble) {
383
+ if (this.BatteryLevel === undefined) {
384
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
385
+ } else {
386
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
387
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
388
+ }
389
+ if (this.StatusLowBattery === undefined) {
390
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
391
+ } else {
392
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
393
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
394
+ }
395
+ }
396
+ }
397
+
398
+ async apiError(e: any): Promise<void> {
399
+ if (!this.device.meter?.hide_humidity) {
400
+ this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, e);
401
+ }
402
+ if (!this.device.meter?.hide_temperature) {
403
+ this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
404
+ }
405
+ if (this.device.ble) {
406
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
407
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
408
+ }
409
+ //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
410
+ }
411
+
412
+ model(device: device & devicesConfig): CharacteristicValue {
413
+ let model: string;
414
+ if (device.deviceType === 'Meter Plus (JP)') {
415
+ model = 'W2201500';
416
+ } else {
417
+ model = 'W2301500';
418
+ }
419
+ return model;
420
+ }
421
+
422
+ async config(device: device & devicesConfig): Promise<void> {
423
+ let config = {};
424
+ if (device.meter) {
425
+ config = device.meter;
426
+ }
427
+ if (device.ble !== undefined) {
428
+ config['ble'] = device.ble;
429
+ }
430
+ if (device.logging !== undefined) {
431
+ config['logging'] = device.logging;
432
+ }
433
+ if (device.refreshRate !== undefined) {
434
+ config['refreshRate'] = device.refreshRate;
435
+ }
436
+ if (device.scanDuration !== undefined) {
437
+ config['scanDuration'] = device.scanDuration;
438
+ }
439
+ if (Object.entries(config).length !== 0) {
440
+ this.infoLog(`Meter Plus: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
441
+ }
442
+ }
443
+
444
+ async refreshRate(device: device & devicesConfig): Promise<void> {
445
+ if (device.refreshRate) {
446
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
447
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
448
+ } else if (this.platform.config.options!.refreshRate) {
449
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
450
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
451
+ }
452
+ }
453
+
454
+ async scan(device: device & devicesConfig): Promise<void> {
455
+ if (device.scanDuration) {
456
+ this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
457
+ if (device.ble) {
458
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
459
+ }
460
+ } else {
461
+ this.scanDuration = this.accessory.context.scanDuration = 1;
462
+ if (this.device.ble) {
463
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
464
+ }
465
+ }
466
+ }
467
+
468
+ async logs(device: device & devicesConfig): Promise<void> {
469
+ if (this.platform.debugMode) {
470
+ this.deviceLogging = this.accessory.context.logging = 'debugMode';
471
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
472
+ } else if (device.logging) {
473
+ this.deviceLogging = this.accessory.context.logging = device.logging;
474
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
475
+ } else if (this.platform.config.options?.logging) {
476
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
477
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
478
+ } else {
479
+ this.deviceLogging = this.accessory.context.logging = 'standard';
480
+ this.debugLog(`Meter Plus: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
481
+ }
482
+ }
483
+
484
+ /**
485
+ * Logging for Device
486
+ */
487
+ infoLog(...log: any[]): void {
488
+ if (this.enablingDeviceLogging()) {
489
+ this.platform.log.info(String(...log));
490
+ }
491
+ }
492
+
493
+ warnLog(...log: any[]): void {
494
+ if (this.enablingDeviceLogging()) {
495
+ this.platform.log.warn(String(...log));
496
+ }
497
+ }
498
+
499
+ errorLog(...log: any[]): void {
500
+ if (this.enablingDeviceLogging()) {
501
+ this.platform.log.error(String(...log));
502
+ }
503
+ }
504
+
505
+ debugLog(...log: any[]): void {
506
+ if (this.enablingDeviceLogging()) {
507
+ if (this.deviceLogging === 'debug') {
508
+ this.platform.log.info('[DEBUG]', String(...log));
509
+ } else {
510
+ this.platform.log.debug(String(...log));
511
+ }
512
+ }
513
+ }
514
+
515
+ enablingDeviceLogging(): boolean {
516
+ return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
517
+ }
518
+ }
@@ -59,7 +59,7 @@ export class Plug {
59
59
 
60
60
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
61
61
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
62
- // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Lightbulb, 'NAME', 'USER_DEFINED_SUBTYPE');
62
+ // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Outlet, 'NAME', 'USER_DEFINED_SUBTYPE');
63
63
 
64
64
  // set the service name, this is what is displayed as the default name on the Home app
65
65
  // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.