@switchbot/homebridge-switchbot 0.1.2-beta.7 → 0.2.0-alpha.1
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/.github/ISSUE_TEMPLATE/feature-request.yml +1 -1
- package/.github/dependabot.yml +2 -0
- package/.github/workflows/codeql-analysis.yml +71 -0
- package/CHANGELOG.md +5 -1
- package/README.md +2 -1
- package/config.schema.json +420 -471
- package/dist/devices/bots.d.ts +19 -5
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +172 -148
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/bulb.d.ts +8 -6
- package/dist/devices/bulb.d.ts.map +1 -1
- package/dist/devices/bulb.js +45 -28
- package/dist/devices/bulb.js.map +1 -1
- package/dist/devices/contact.d.ts +10 -5
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +94 -63
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +14 -5
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +174 -120
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +6 -6
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +78 -94
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/indoorcam.d.ts +43 -0
- package/dist/devices/indoorcam.d.ts.map +1 -0
- package/dist/devices/indoorcam.js +241 -0
- package/dist/devices/indoorcam.js.map +1 -0
- package/dist/devices/meters.d.ts +8 -5
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +126 -92
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +9 -5
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +74 -59
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +5 -4
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +65 -56
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +3 -3
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +12 -7
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +3 -3
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +1 -1
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.d.ts +3 -3
- package/dist/irdevices/cameras.d.ts.map +1 -1
- package/dist/irdevices/cameras.js +1 -1
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.d.ts +3 -3
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +11 -12
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.d.ts +3 -3
- package/dist/irdevices/lights.d.ts.map +1 -1
- package/dist/irdevices/lights.js +1 -1
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.d.ts +3 -3
- package/dist/irdevices/others.d.ts.map +1 -1
- package/dist/irdevices/others.js +8 -8
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts +3 -3
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +16 -6
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.d.ts +3 -3
- package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +2 -3
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.d.ts +3 -3
- package/dist/irdevices/waterheaters.d.ts.map +1 -1
- package/dist/irdevices/waterheaters.js +2 -2
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts +14 -5
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +420 -418
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +18 -15
- package/dist/settings.d.ts.map +1 -1
- package/package.json +65 -65
- package/src/devices/bots.ts +188 -165
- package/src/devices/bulb.ts +48 -40
- package/src/devices/contact.ts +100 -73
- package/src/devices/curtains.ts +192 -140
- package/src/devices/humidifiers.ts +82 -124
- package/src/devices/indoorcam.ts +303 -0
- package/src/devices/meters.ts +130 -110
- package/src/devices/motion.ts +80 -69
- package/src/devices/plugs.ts +67 -65
- package/src/irdevices/airconditioners.ts +14 -10
- package/src/irdevices/airpurifiers.ts +4 -4
- package/src/irdevices/cameras.ts +4 -4
- package/src/irdevices/fans.ts +14 -18
- package/src/irdevices/lights.ts +4 -4
- package/src/irdevices/others.ts +12 -14
- package/src/irdevices/tvs.ts +21 -10
- package/src/irdevices/vacuumcleaners.ts +5 -9
- package/src/irdevices/waterheaters.ts +5 -5
- package/src/platform.ts +455 -619
- package/src/settings.ts +19 -15
- package/.github/workflows/issue-validate.yml +0 -18
package/src/devices/meters.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Service, PlatformAccessory, Units, CharacteristicValue, MacAddress } fr
|
|
|
2
2
|
import { SwitchBotPlatform } from '../platform';
|
|
3
3
|
import { interval, Subject } from 'rxjs';
|
|
4
4
|
import { skipWhile } from 'rxjs/operators';
|
|
5
|
-
import { DeviceURL, device,
|
|
5
|
+
import { DeviceURL, device, devicesConfig } from '../settings';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Platform Accessory
|
|
@@ -25,7 +25,7 @@ export class Meter {
|
|
|
25
25
|
WaterLevel!: CharacteristicValue;
|
|
26
26
|
|
|
27
27
|
// Others
|
|
28
|
-
deviceStatus!:
|
|
28
|
+
deviceStatus!: any;
|
|
29
29
|
BLEtemperature!: number;
|
|
30
30
|
BLEHumidity!: number;
|
|
31
31
|
switchbot!: {
|
|
@@ -50,7 +50,7 @@ export class Meter {
|
|
|
50
50
|
constructor(
|
|
51
51
|
private readonly platform: SwitchBotPlatform,
|
|
52
52
|
private accessory: PlatformAccessory,
|
|
53
|
-
public device: device,
|
|
53
|
+
public device: device & devicesConfig,
|
|
54
54
|
) {
|
|
55
55
|
// default placeholders
|
|
56
56
|
this.BatteryLevel = 0;
|
|
@@ -58,16 +58,16 @@ export class Meter {
|
|
|
58
58
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
59
59
|
this.CurrentRelativeHumidity = 0;
|
|
60
60
|
this.CurrentTemperature = 0;
|
|
61
|
-
|
|
61
|
+
|
|
62
|
+
// BLE Connection
|
|
63
|
+
if (device.ble) {
|
|
62
64
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
63
65
|
const SwitchBot = require('node-switchbot');
|
|
64
66
|
this.switchbot = new SwitchBot();
|
|
65
67
|
const colon = device.deviceId!.match(/.{1,2}/g);
|
|
66
68
|
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
67
69
|
this.device.bleMac = bleMac.toLowerCase();
|
|
68
|
-
|
|
69
|
-
this.platform.log.warn(this.device.bleMac.toLowerCase());
|
|
70
|
-
}
|
|
70
|
+
this.platform.device(this.device.bleMac.toLowerCase());
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
@@ -88,7 +88,7 @@ export class Meter {
|
|
|
88
88
|
// you can create multiple services for each accessory
|
|
89
89
|
(this.service =
|
|
90
90
|
accessory.getService(this.platform.Service.Battery) ||
|
|
91
|
-
accessory.addService(this.platform.Service.Battery)), `${
|
|
91
|
+
accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
92
92
|
|
|
93
93
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
94
94
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -105,19 +105,17 @@ export class Meter {
|
|
|
105
105
|
this.service.setCharacteristic(this.platform.Characteristic.ChargingState, 2);
|
|
106
106
|
|
|
107
107
|
// Temperature Sensor Service
|
|
108
|
-
if (
|
|
109
|
-
|
|
110
|
-
this.platform.log.error('Removing service');
|
|
111
|
-
}
|
|
108
|
+
if (device.meter?.hide_temperature) {
|
|
109
|
+
this.platform.device('Removing Temperature Sensor Service');
|
|
112
110
|
this.temperatureservice = this.accessory.getService(this.platform.Service.TemperatureSensor);
|
|
113
111
|
accessory.removeService(this.temperatureservice!);
|
|
114
112
|
} else if (!this.temperatureservice) {
|
|
115
|
-
|
|
116
|
-
this.platform.log.warn('Adding service');
|
|
117
|
-
}
|
|
113
|
+
this.platform.device('Adding Temperature Sensor Service');
|
|
118
114
|
(this.temperatureservice =
|
|
119
115
|
this.accessory.getService(this.platform.Service.TemperatureSensor) ||
|
|
120
|
-
this.accessory.addService(this.platform.Service.TemperatureSensor)), `${
|
|
116
|
+
this.accessory.addService(this.platform.Service.TemperatureSensor)), `${accessory.displayName} Temperature Sensor`;
|
|
117
|
+
|
|
118
|
+
this.service.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
|
|
121
119
|
|
|
122
120
|
this.temperatureservice
|
|
123
121
|
.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
@@ -129,26 +127,24 @@ export class Meter {
|
|
|
129
127
|
minStep: 0.1,
|
|
130
128
|
})
|
|
131
129
|
.onGet(() => {
|
|
132
|
-
return this.CurrentTemperature;
|
|
130
|
+
return Number.isNaN(this.CurrentTemperature);
|
|
133
131
|
});
|
|
134
|
-
this.platform.log.info(this.device.deviceName + ' current temperature: ' + this.CurrentTemperature + '\u2103');
|
|
135
132
|
} else {
|
|
136
|
-
|
|
137
|
-
this.platform.log.warn('TemperatureSensor not added.');
|
|
138
|
-
}
|
|
133
|
+
this.platform.device('Temperature Sensor Not Added');
|
|
139
134
|
}
|
|
140
135
|
|
|
141
136
|
// Humidity Sensor Service
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
this.platform.log.error('Removing service');
|
|
145
|
-
}
|
|
137
|
+
if (device.meter?.hide_humidity) {
|
|
138
|
+
this.platform.device('Removing Humidity Sensor Service');
|
|
146
139
|
this.humidityservice = this.accessory.getService(this.platform.Service.HumiditySensor);
|
|
147
140
|
accessory.removeService(this.humidityservice!);
|
|
148
141
|
} else if (!this.humidityservice) {
|
|
142
|
+
this.platform.device('Adding Humidity Sensor Service');
|
|
149
143
|
(this.humidityservice =
|
|
150
144
|
this.accessory.getService(this.platform.Service.HumiditySensor) ||
|
|
151
|
-
this.accessory.addService(this.platform.Service.HumiditySensor)), `${
|
|
145
|
+
this.accessory.addService(this.platform.Service.HumiditySensor)), `${accessory.displayName} Humidity Sensor`;
|
|
146
|
+
|
|
147
|
+
this.service.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
|
|
152
148
|
|
|
153
149
|
this.humidityservice
|
|
154
150
|
.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
|
|
@@ -158,11 +154,8 @@ export class Meter {
|
|
|
158
154
|
.onGet(() => {
|
|
159
155
|
return this.CurrentRelativeHumidity;
|
|
160
156
|
});
|
|
161
|
-
this.platform.log.info(this.device.deviceName + ' current humidity: ' + this.CurrentRelativeHumidity + '%');
|
|
162
157
|
} else {
|
|
163
|
-
|
|
164
|
-
this.platform.log.warn('HumiditySensor not added.');
|
|
165
|
-
}
|
|
158
|
+
this.platform.device('Adding Humidity Sensor Not Added');
|
|
166
159
|
}
|
|
167
160
|
|
|
168
161
|
// Retrieve initial values and updateHomekit
|
|
@@ -179,8 +172,32 @@ export class Meter {
|
|
|
179
172
|
/**
|
|
180
173
|
* Parse the device status from the SwitchBot api
|
|
181
174
|
*/
|
|
182
|
-
parseStatus() {
|
|
183
|
-
|
|
175
|
+
async parseStatus() {
|
|
176
|
+
if (this.device.ble) {
|
|
177
|
+
this.platform.device('BLE');
|
|
178
|
+
await this.BLEparseStatus();
|
|
179
|
+
} else {
|
|
180
|
+
this.platform.device('OpenAPI');
|
|
181
|
+
await this.openAPIparseStatus();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private async BLEparseStatus() {
|
|
186
|
+
if (this.deviceStatus.body) {
|
|
187
|
+
this.BatteryLevel = 100;
|
|
188
|
+
} else {
|
|
189
|
+
this.BatteryLevel = 10;
|
|
190
|
+
}
|
|
191
|
+
if (this.BatteryLevel < 15) {
|
|
192
|
+
this.StatusLowBattery = 1;
|
|
193
|
+
} else {
|
|
194
|
+
this.StatusLowBattery = 0;
|
|
195
|
+
}
|
|
196
|
+
this.platform.debug(`${this.accessory.displayName}
|
|
197
|
+
, BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private async openAPIparseStatus() {
|
|
184
201
|
if (this.deviceStatus.body) {
|
|
185
202
|
this.BatteryLevel = 100;
|
|
186
203
|
} else {
|
|
@@ -192,8 +209,8 @@ export class Meter {
|
|
|
192
209
|
this.StatusLowBattery = 0;
|
|
193
210
|
}
|
|
194
211
|
// Current Relative Humidity
|
|
195
|
-
if (!this.
|
|
196
|
-
if (this.
|
|
212
|
+
if (!this.device.meter?.hide_humidity) {
|
|
213
|
+
if (this.device.ble) {
|
|
197
214
|
this.CurrentRelativeHumidity = this.BLEHumidity;
|
|
198
215
|
} else {
|
|
199
216
|
this.CurrentRelativeHumidity = this.deviceStatus.body.humidity!;
|
|
@@ -202,16 +219,16 @@ export class Meter {
|
|
|
202
219
|
}
|
|
203
220
|
|
|
204
221
|
// Current Temperature
|
|
205
|
-
if (!this.
|
|
206
|
-
if (this.
|
|
222
|
+
if (!this.device.meter?.hide_temperature) {
|
|
223
|
+
if (this.device.ble) {
|
|
207
224
|
this.CurrentTemperature = this.BLEtemperature;
|
|
208
225
|
} else {
|
|
209
|
-
if (this.
|
|
226
|
+
if (this.device.meter?.unit === 1) {
|
|
210
227
|
this.CurrentTemperature = this.toFahrenheit(this.deviceStatus.body.temperature!);
|
|
211
|
-
} else if (this.
|
|
228
|
+
} else if (this.device.meter?.unit === 0) {
|
|
212
229
|
this.CurrentTemperature = this.toCelsius(this.deviceStatus.body.temperature!);
|
|
213
230
|
} else {
|
|
214
|
-
this.CurrentTemperature = this.deviceStatus.body.temperature
|
|
231
|
+
this.CurrentTemperature = this.deviceStatus.body.temperature;
|
|
215
232
|
}
|
|
216
233
|
}
|
|
217
234
|
this.platform.debug(`Meter ${this.accessory.displayName} - Temperature: ${this.CurrentTemperature}°c`);
|
|
@@ -222,81 +239,78 @@ export class Meter {
|
|
|
222
239
|
* Asks the SwitchBot API for the latest device information
|
|
223
240
|
*/
|
|
224
241
|
async refreshStatus() {
|
|
225
|
-
if (this.
|
|
226
|
-
this.platform.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
if (this.device.ble) {
|
|
243
|
+
this.platform.device('BLE');
|
|
244
|
+
await this.BLErefreshStatus();
|
|
245
|
+
} else {
|
|
246
|
+
this.platform.device('OpenAPI');
|
|
247
|
+
await this.openAPIRefreshStatus();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private async BLErefreshStatus() {
|
|
252
|
+
this.platform.debug('Meter BLE Device RefreshStatus');
|
|
253
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
254
|
+
const Switchbot = require('node-switchbot');
|
|
255
|
+
const switchbot = new Switchbot();
|
|
256
|
+
const colon = this.device.deviceId!.match(/.{1,2}/g);
|
|
257
|
+
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
258
|
+
this.device.bleMac = bleMac.toLowerCase();
|
|
259
|
+
this.platform.device(this.device.bleMac!);
|
|
260
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
261
|
+
this.platform.debug(JSON.stringify(ad, null, ' '));
|
|
262
|
+
this.platform.device('ad:', JSON.stringify(ad));
|
|
263
|
+
this.platform.device(`Temperature: ${ad.serviceData.temperature.c}`);
|
|
264
|
+
this.platform.device(`Humidity: ${ad.serviceData.humidity}`);
|
|
265
|
+
this.BLEtemperature = ad.serviceData.temperature.c;
|
|
266
|
+
this.BLEHumidity = ad.serviceData.humidity;
|
|
267
|
+
};
|
|
268
|
+
this.parseStatus();
|
|
269
|
+
this.updateHomeKitCharacteristics();
|
|
270
|
+
switchbot
|
|
271
|
+
.startScan({
|
|
272
|
+
id: this.device.bleMac,
|
|
273
|
+
})
|
|
274
|
+
.then(() => {
|
|
275
|
+
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
276
|
+
})
|
|
277
|
+
.then(() => {
|
|
278
|
+
switchbot.stopScan();
|
|
279
|
+
})
|
|
280
|
+
.catch(async (error: any) => {
|
|
281
|
+
this.platform.log.error(error);
|
|
282
|
+
await this.openAPIRefreshStatus();
|
|
283
|
+
});
|
|
284
|
+
setInterval(() => {
|
|
285
|
+
this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
244
286
|
switchbot
|
|
245
287
|
.startScan({
|
|
246
|
-
|
|
288
|
+
mode: 'T',
|
|
289
|
+
id: bleMac,
|
|
247
290
|
})
|
|
248
291
|
.then(() => {
|
|
249
292
|
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
250
293
|
})
|
|
251
294
|
.then(() => {
|
|
252
295
|
switchbot.stopScan();
|
|
296
|
+
this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
253
297
|
})
|
|
254
298
|
.catch(async (error: any) => {
|
|
255
299
|
this.platform.log.error(error);
|
|
256
300
|
await this.openAPIRefreshStatus();
|
|
257
301
|
});
|
|
258
|
-
|
|
259
|
-
this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
260
|
-
switchbot
|
|
261
|
-
.startScan({
|
|
262
|
-
mode: 'T',
|
|
263
|
-
id: bleMac,
|
|
264
|
-
})
|
|
265
|
-
.then(() => {
|
|
266
|
-
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
267
|
-
})
|
|
268
|
-
.then(() => {
|
|
269
|
-
switchbot.stopScan();
|
|
270
|
-
this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
271
|
-
})
|
|
272
|
-
.catch(async (error: any) => {
|
|
273
|
-
this.platform.log.error(error);
|
|
274
|
-
await this.openAPIRefreshStatus();
|
|
275
|
-
});
|
|
276
|
-
}, this.platform.config.options!.refreshRate! * 60000);
|
|
277
|
-
} else {
|
|
278
|
-
await this.openAPIRefreshStatus();
|
|
279
|
-
}
|
|
302
|
+
}, this.platform.config.options!.refreshRate! * 60000);
|
|
280
303
|
}
|
|
281
304
|
|
|
282
305
|
private async openAPIRefreshStatus() {
|
|
283
306
|
try {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
this.deviceStatus = deviceStatus;
|
|
289
|
-
this.platform.debug(`Meter ${this.accessory.displayName} openAPIRefreshStatus - ${JSON.stringify(this.deviceStatus)}`);
|
|
290
|
-
this.parseStatus();
|
|
291
|
-
this.updateHomeKitCharacteristics();
|
|
292
|
-
}
|
|
307
|
+
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
308
|
+
this.platform.debug(`Meter ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
309
|
+
this.parseStatus();
|
|
310
|
+
this.updateHomeKitCharacteristics();
|
|
293
311
|
} catch (e: any) {
|
|
294
|
-
this.platform.log.error(
|
|
295
|
-
|
|
296
|
-
this.device.deviceName,
|
|
297
|
-
JSON.stringify(e.message),
|
|
298
|
-
this.platform.debug(`Meter ${this.accessory.displayName} - ${JSON.stringify(e)}`),
|
|
299
|
-
);
|
|
312
|
+
this.platform.log.error(`Meter ${this.accessory.displayName} failed to refresh status, Error Message: ${JSON.stringify(e.message)}`);
|
|
313
|
+
this.platform.debug(`Meter ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
|
|
300
314
|
this.apiError(e);
|
|
301
315
|
}
|
|
302
316
|
}
|
|
@@ -305,33 +319,39 @@ export class Meter {
|
|
|
305
319
|
* Updates the status for each of the HomeKit Characteristics
|
|
306
320
|
*/
|
|
307
321
|
updateHomeKitCharacteristics() {
|
|
308
|
-
if (this.StatusLowBattery
|
|
322
|
+
if (this.StatusLowBattery === undefined) {
|
|
323
|
+
this.platform.debug(`Meter ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
324
|
+
} else {
|
|
309
325
|
this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
326
|
+
this.platform.device(`Meter ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
310
327
|
}
|
|
311
|
-
if (this.BatteryLevel
|
|
328
|
+
if (this.BatteryLevel === undefined) {
|
|
329
|
+
this.platform.debug(`Meter ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
330
|
+
} else {
|
|
312
331
|
this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
332
|
+
this.platform.device(`Meter ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
313
333
|
}
|
|
314
|
-
if (
|
|
315
|
-
this.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
);
|
|
334
|
+
if (this.device.meter?.hide_humidity && this.CurrentRelativeHumidity === undefined) {
|
|
335
|
+
this.platform.debug(`Meter ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
336
|
+
} else {
|
|
337
|
+
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
|
|
338
|
+
this.platform.device(`Meter ${this.accessory.displayName} updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
319
339
|
}
|
|
320
|
-
if (
|
|
321
|
-
this.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
);
|
|
340
|
+
if (this.device.meter?.hide_temperature || this.CurrentTemperature === undefined) {
|
|
341
|
+
this.platform.debug(`Meter ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
|
|
342
|
+
} else {
|
|
343
|
+
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
|
|
344
|
+
this.platform.device(`Meter ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
|
|
325
345
|
}
|
|
326
346
|
}
|
|
327
347
|
|
|
328
348
|
public apiError(e: any) {
|
|
329
349
|
this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
330
350
|
this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
331
|
-
if (!this.
|
|
351
|
+
if (!this.device.meter?.hide_humidity) {
|
|
332
352
|
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, e);
|
|
333
353
|
}
|
|
334
|
-
if (!this.
|
|
354
|
+
if (!this.device.meter?.hide_temperature) {
|
|
335
355
|
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
|
|
336
356
|
}
|
|
337
357
|
}
|
package/src/devices/motion.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'hom
|
|
|
2
2
|
import { SwitchBotPlatform } from '../platform';
|
|
3
3
|
import { interval, Subject } from 'rxjs';
|
|
4
4
|
import { skipWhile } from 'rxjs/operators';
|
|
5
|
-
import { DeviceURL, device,
|
|
5
|
+
import { DeviceURL, device, devicesConfig } from '../settings';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Platform Accessory
|
|
@@ -17,7 +17,8 @@ export class Motion {
|
|
|
17
17
|
MotionDetected!: CharacteristicValue;
|
|
18
18
|
|
|
19
19
|
// Others
|
|
20
|
-
deviceStatus!:
|
|
20
|
+
deviceStatus!: any;
|
|
21
|
+
BLEmotion!: boolean;
|
|
21
22
|
switchbot!: {
|
|
22
23
|
discover: (
|
|
23
24
|
arg0:
|
|
@@ -40,22 +41,20 @@ export class Motion {
|
|
|
40
41
|
constructor(
|
|
41
42
|
private readonly platform: SwitchBotPlatform,
|
|
42
43
|
private accessory: PlatformAccessory,
|
|
43
|
-
public device: device,
|
|
44
|
+
public device: device & devicesConfig,
|
|
44
45
|
) {
|
|
45
46
|
// default placeholders
|
|
46
47
|
this.MotionDetected = false;
|
|
47
48
|
|
|
48
49
|
// BLE Connection
|
|
49
|
-
if (
|
|
50
|
+
if (device.ble) {
|
|
50
51
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
51
52
|
const SwitchBot = require('node-switchbot');
|
|
52
53
|
this.switchbot = new SwitchBot();
|
|
53
54
|
const colon = device.deviceId!.match(/.{1,2}/g);
|
|
54
55
|
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
55
56
|
this.device.bleMac = bleMac.toLowerCase();
|
|
56
|
-
|
|
57
|
-
this.platform.log.warn(this.device.bleMac.toLowerCase());
|
|
58
|
-
}
|
|
57
|
+
this.platform.device(this.device.bleMac.toLowerCase());
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
@@ -69,14 +68,14 @@ export class Motion {
|
|
|
69
68
|
accessory
|
|
70
69
|
.getService(this.platform.Service.AccessoryInformation)!
|
|
71
70
|
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
|
|
72
|
-
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-
|
|
73
|
-
.setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId);
|
|
71
|
+
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-WOMOTION-W1101500')
|
|
72
|
+
.setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
|
|
74
73
|
|
|
75
74
|
// get the Battery service if it exists, otherwise create a new Motion service
|
|
76
75
|
// you can create multiple services for each accessory
|
|
77
76
|
(this.service =
|
|
78
77
|
accessory.getService(this.platform.Service.MotionSensor) ||
|
|
79
|
-
accessory.addService(this.platform.Service.MotionSensor)), `${
|
|
78
|
+
accessory.addService(this.platform.Service.MotionSensor)), `${accessory.displayName} Motion Sensor`;
|
|
80
79
|
|
|
81
80
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
82
81
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -106,90 +105,99 @@ export class Motion {
|
|
|
106
105
|
/**
|
|
107
106
|
* Parse the device status from the SwitchBot api
|
|
108
107
|
*/
|
|
109
|
-
parseStatus() {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
this.
|
|
108
|
+
async parseStatus() {
|
|
109
|
+
if (this.device.ble) {
|
|
110
|
+
this.platform.device('BLE');
|
|
111
|
+
await this.BLEparseStatus();
|
|
113
112
|
} else {
|
|
114
|
-
this.
|
|
113
|
+
this.platform.device('OpenAPI');
|
|
114
|
+
await this.openAPIparseStatus();
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
private async BLEparseStatus() {
|
|
119
|
+
this.MotionDetected = Boolean(this.BLEmotion);
|
|
120
|
+
this.platform.debug(`${this.accessory.displayName}, MotionDetected: ${this.MotionDetected}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private async openAPIparseStatus() {
|
|
124
|
+
this.MotionDetected = Boolean(this.deviceStatus.body.moveDetected);
|
|
125
|
+
this.platform.debug(`${this.accessory.displayName}, MotionDetected: ${this.MotionDetected}`);
|
|
126
|
+
}
|
|
127
|
+
|
|
118
128
|
/**
|
|
119
129
|
* Asks the SwitchBot API for the latest device information
|
|
120
130
|
*/
|
|
121
131
|
async refreshStatus() {
|
|
122
|
-
if (this.
|
|
123
|
-
this.platform.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
if (this.device.ble) {
|
|
133
|
+
this.platform.device('BLE');
|
|
134
|
+
await this.BLErefreshStatus();
|
|
135
|
+
} else {
|
|
136
|
+
this.platform.device('OpenAPI');
|
|
137
|
+
await this.openAPIRefreshStatus();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private async BLErefreshStatus() {
|
|
142
|
+
this.platform.debug('Motion BLE Device RefreshStatus');
|
|
143
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
144
|
+
const Switchbot = require('node-switchbot');
|
|
145
|
+
const switchbot = new Switchbot();
|
|
146
|
+
const colon = this.device.deviceId!.match(/.{1,2}/g);
|
|
147
|
+
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
148
|
+
this.device.bleMac = bleMac.toLowerCase();
|
|
149
|
+
this.platform.device(this.device.bleMac!);
|
|
150
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
151
|
+
this.platform.debug(JSON.stringify(ad, null, ' '));
|
|
152
|
+
this.platform.device('ad:', JSON.stringify(ad));
|
|
153
|
+
this.BLEmotion = ad.serviceData.motion;
|
|
154
|
+
};
|
|
155
|
+
switchbot
|
|
156
|
+
.startScan({
|
|
157
|
+
id: this.device.bleMac,
|
|
158
|
+
})
|
|
159
|
+
.then(() => {
|
|
160
|
+
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
161
|
+
})
|
|
162
|
+
.then(() => {
|
|
163
|
+
switchbot.stopScan();
|
|
164
|
+
})
|
|
165
|
+
.catch(async (error: any) => {
|
|
166
|
+
this.platform.log.error(error);
|
|
167
|
+
await this.openAPIRefreshStatus();
|
|
168
|
+
});
|
|
169
|
+
setInterval(() => {
|
|
170
|
+
this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
137
171
|
switchbot
|
|
138
172
|
.startScan({
|
|
139
|
-
|
|
173
|
+
mode: 'S',
|
|
174
|
+
id: bleMac,
|
|
140
175
|
})
|
|
141
176
|
.then(() => {
|
|
142
177
|
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
143
178
|
})
|
|
144
179
|
.then(() => {
|
|
145
180
|
switchbot.stopScan();
|
|
181
|
+
this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
146
182
|
})
|
|
147
183
|
.catch(async (error: any) => {
|
|
148
184
|
this.platform.log.error(error);
|
|
149
185
|
await this.openAPIRefreshStatus();
|
|
150
186
|
});
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
.startScan({
|
|
155
|
-
mode: 'M',
|
|
156
|
-
id: bleMac,
|
|
157
|
-
})
|
|
158
|
-
.then(() => {
|
|
159
|
-
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
160
|
-
})
|
|
161
|
-
.then(() => {
|
|
162
|
-
switchbot.stopScan();
|
|
163
|
-
this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
164
|
-
})
|
|
165
|
-
.catch(async (error: any) => {
|
|
166
|
-
this.platform.log.error(error);
|
|
167
|
-
await this.openAPIRefreshStatus();
|
|
168
|
-
});
|
|
169
|
-
}, this.platform.config.options!.refreshRate! * 60000);
|
|
170
|
-
} else {
|
|
171
|
-
await this.openAPIRefreshStatus();
|
|
172
|
-
}
|
|
187
|
+
this.parseStatus();
|
|
188
|
+
this.updateHomeKitCharacteristics();
|
|
189
|
+
}, this.platform.config.options!.refreshRate! * 60000);
|
|
173
190
|
}
|
|
174
191
|
|
|
175
192
|
private async openAPIRefreshStatus() {
|
|
176
193
|
try {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
this.deviceStatus = deviceStatus;
|
|
182
|
-
this.platform.debug(`Motion ${this.accessory.displayName} refreshStatus - ${JSON.stringify(this.deviceStatus)}`);
|
|
183
|
-
|
|
184
|
-
this.parseStatus();
|
|
185
|
-
this.updateHomeKitCharacteristics();
|
|
186
|
-
}
|
|
194
|
+
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
195
|
+
this.platform.debug(`Motion ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
196
|
+
this.parseStatus();
|
|
197
|
+
this.updateHomeKitCharacteristics();
|
|
187
198
|
} catch (e: any) {
|
|
188
|
-
this.platform.log.error(
|
|
189
|
-
|
|
190
|
-
this.device.deviceName,
|
|
191
|
-
JSON.stringify(e.message),
|
|
192
|
-
this.platform.debug(`Motion ${this.accessory.displayName} - ${JSON.stringify(e)}`));
|
|
199
|
+
this.platform.log.error(`Motion ${this.accessory.displayName} failed to refresh status, Error Message: ${JSON.stringify(e.message)}`);
|
|
200
|
+
this.platform.debug(`Motion ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
|
|
193
201
|
this.apiError(e);
|
|
194
202
|
}
|
|
195
203
|
}
|
|
@@ -198,8 +206,11 @@ export class Motion {
|
|
|
198
206
|
* Updates the status for each of the HomeKit Characteristics
|
|
199
207
|
*/
|
|
200
208
|
updateHomeKitCharacteristics() {
|
|
201
|
-
if (this.MotionDetected
|
|
209
|
+
if (this.MotionDetected === undefined) {
|
|
210
|
+
this.platform.debug(`Motion ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
211
|
+
} else {
|
|
202
212
|
this.service.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
|
|
213
|
+
this.platform.device(`Motion ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
|
|
203
214
|
}
|
|
204
215
|
}
|
|
205
216
|
|