@switchbot/homebridge-switchbot 0.2.0-alpha.2 → 1.0.1-beta.2
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/workflows/nodejs-beta.yml +1 -1
- package/.github/workflows/nodejs.yml +1 -1
- package/.github/workflows/{prerelease.js → prerelease-beta.js} +0 -0
- package/CHANGELOG.md +1 -1
- package/README.md +9 -5
- package/config.schema.json +370 -142
- package/dist/devices/bots.d.ts +18 -34
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +166 -171
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/{bulb.d.ts → colorbulb.d.ts} +12 -19
- package/dist/devices/colorbulb.d.ts.map +1 -0
- package/dist/devices/{bulb.js → colorbulb.js} +34 -32
- package/dist/devices/colorbulb.js.map +1 -0
- package/dist/devices/contact.d.ts +18 -16
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +101 -44
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +17 -51
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +170 -248
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +13 -4
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +81 -8
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/indoorcam.d.ts +6 -13
- package/dist/devices/indoorcam.d.ts.map +1 -1
- package/dist/devices/indoorcam.js.map +1 -1
- package/dist/devices/meters.d.ts +12 -15
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +38 -44
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +17 -15
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +87 -40
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +6 -13
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +10 -10
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +29 -9
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +11 -11
- package/dist/irdevices/airpurifiers.d.ts.map +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.map +1 -1
- package/dist/irdevices/fans.d.ts +6 -6
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +10 -10
- 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.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.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 +7 -5
- 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.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.map +1 -1
- package/dist/platform.d.ts +3 -2
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +136 -46
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +51 -8
- package/dist/settings.d.ts.map +1 -1
- package/package.json +65 -65
- package/src/devices/bots.ts +188 -193
- package/src/devices/{bulb.ts → colorbulb.ts} +46 -51
- package/src/devices/contact.ts +124 -68
- package/src/devices/curtains.ts +192 -300
- package/src/devices/humidifiers.ts +97 -14
- package/src/devices/indoorcam.ts +10 -20
- package/src/devices/meters.ts +57 -69
- package/src/devices/motion.ts +108 -62
- package/src/devices/plugs.ts +8 -19
- package/src/irdevices/airconditioners.ts +43 -20
- package/src/irdevices/airpurifiers.ts +15 -11
- package/src/irdevices/cameras.ts +5 -3
- package/src/irdevices/fans.ts +22 -16
- package/src/irdevices/lights.ts +5 -3
- package/src/irdevices/others.ts +5 -3
- package/src/irdevices/tvs.ts +13 -7
- package/src/irdevices/vacuumcleaners.ts +5 -3
- package/src/irdevices/waterheaters.ts +5 -3
- package/src/platform.ts +148 -49
- package/src/settings.ts +80 -8
- package/dist/devices/bulb.d.ts.map +0 -1
- package/dist/devices/bulb.js.map +0 -1
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { Service, PlatformAccessory, CharacteristicValue
|
|
1
|
+
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
2
2
|
import { SwitchBotPlatform } from '../platform';
|
|
3
3
|
import { interval, Subject } from 'rxjs';
|
|
4
4
|
import { debounceTime, skipWhile, tap } from 'rxjs/operators';
|
|
5
|
-
import { DeviceURL, device, devicesConfig } from '../settings';
|
|
5
|
+
import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse } from '../settings';
|
|
6
|
+
import { AxiosResponse } from 'axios';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Platform Accessory
|
|
9
10
|
* An instance of this class is created for each accessory your platform registers
|
|
10
11
|
* Each accessory may expose multiple services of different service types.
|
|
11
12
|
*/
|
|
12
|
-
export class
|
|
13
|
+
export class ColorBulb {
|
|
13
14
|
// Services
|
|
14
15
|
service!: Service;
|
|
15
16
|
|
|
@@ -18,33 +19,27 @@ export class Bulb {
|
|
|
18
19
|
Brightness!: CharacteristicValue;
|
|
19
20
|
ColorTemperature!: CharacteristicValue;
|
|
20
21
|
|
|
21
|
-
// Others
|
|
22
|
-
deviceStatus
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
quick: boolean;
|
|
30
|
-
id: MacAddress;
|
|
31
|
-
}
|
|
32
|
-
) => Promise<any>;
|
|
33
|
-
wait: (
|
|
34
|
-
arg0: number
|
|
35
|
-
) => any;
|
|
36
|
-
};
|
|
22
|
+
// OpenAPI Others
|
|
23
|
+
deviceStatus!: deviceStatusResponse;
|
|
24
|
+
|
|
25
|
+
// BLE Others
|
|
26
|
+
switchbot!: switchbot;
|
|
27
|
+
|
|
28
|
+
// Config
|
|
29
|
+
set_minStep?: number;
|
|
37
30
|
|
|
38
31
|
// Updates
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
set_minStep: any;
|
|
32
|
+
colorBulbUpdateInProgress!: boolean;
|
|
33
|
+
doColorBulbUpdate!: Subject<void>;
|
|
42
34
|
|
|
43
35
|
constructor(
|
|
44
36
|
private readonly platform: SwitchBotPlatform,
|
|
45
37
|
private accessory: PlatformAccessory,
|
|
46
38
|
public device: device & devicesConfig,
|
|
47
39
|
) {
|
|
40
|
+
// ColorBulb Config
|
|
41
|
+
this.platform.device(`[ColorBulb Config] ble: ${device.ble}, set_minStep: ${device.colorbulb?.set_minStep}`);
|
|
42
|
+
|
|
48
43
|
// default placeholders
|
|
49
44
|
this.On = false;
|
|
50
45
|
this.Brightness = 0;
|
|
@@ -59,8 +54,8 @@ export class Bulb {
|
|
|
59
54
|
}
|
|
60
55
|
|
|
61
56
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
57
|
+
this.doColorBulbUpdate = new Subject();
|
|
58
|
+
this.colorBulbUpdateInProgress = false;
|
|
64
59
|
|
|
65
60
|
|
|
66
61
|
// Retrieve initial values and updateHomekit
|
|
@@ -70,7 +65,7 @@ export class Bulb {
|
|
|
70
65
|
accessory
|
|
71
66
|
.getService(this.platform.Service.AccessoryInformation)!
|
|
72
67
|
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
|
|
73
|
-
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-
|
|
68
|
+
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-COLORBULB-W1401400')
|
|
74
69
|
.setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
|
|
75
70
|
|
|
76
71
|
// get the Television service if it exists, otherwise create a new Television service
|
|
@@ -122,17 +117,17 @@ export class Bulb {
|
|
|
122
117
|
|
|
123
118
|
// Start an update interval
|
|
124
119
|
interval(this.platform.config.options!.refreshRate! * 1000)
|
|
125
|
-
.pipe(skipWhile(() => this.
|
|
120
|
+
.pipe(skipWhile(() => this.colorBulbUpdateInProgress))
|
|
126
121
|
.subscribe(() => {
|
|
127
122
|
this.refreshStatus();
|
|
128
123
|
});
|
|
129
124
|
|
|
130
125
|
// Watch for Bulb change events
|
|
131
126
|
// We put in a debounce of 100ms so we don't make duplicate calls
|
|
132
|
-
this.
|
|
127
|
+
this.doColorBulbUpdate
|
|
133
128
|
.pipe(
|
|
134
129
|
tap(() => {
|
|
135
|
-
this.
|
|
130
|
+
this.colorBulbUpdateInProgress = true;
|
|
136
131
|
}),
|
|
137
132
|
debounceTime(this.platform.config.options!.pushRate! * 1000),
|
|
138
133
|
)
|
|
@@ -141,16 +136,16 @@ export class Bulb {
|
|
|
141
136
|
await this.pushChanges();
|
|
142
137
|
} catch (e: any) {
|
|
143
138
|
this.platform.log.error(JSON.stringify(e.message));
|
|
144
|
-
this.platform.debug(`Bulb ${accessory.displayName} - ${JSON.stringify(e)}`);
|
|
139
|
+
this.platform.debug(`Color Bulb ${accessory.displayName} - ${JSON.stringify(e)}`);
|
|
145
140
|
this.apiError(e);
|
|
146
141
|
}
|
|
147
|
-
this.
|
|
142
|
+
this.colorBulbUpdateInProgress = false;
|
|
148
143
|
});
|
|
149
144
|
}
|
|
150
145
|
|
|
151
146
|
private minStep(): number | undefined {
|
|
152
|
-
if (this.device.
|
|
153
|
-
this.set_minStep = this.device.
|
|
147
|
+
if (this.device.colorbulb?.set_minStep) {
|
|
148
|
+
this.set_minStep = this.device.colorbulb?.set_minStep;
|
|
154
149
|
} else {
|
|
155
150
|
this.set_minStep = 1;
|
|
156
151
|
}
|
|
@@ -165,21 +160,21 @@ export class Bulb {
|
|
|
165
160
|
default:
|
|
166
161
|
this.On = false;
|
|
167
162
|
}
|
|
168
|
-
this.platform.debug(`Bulb ${this.accessory.displayName} On: ${this.On}`);
|
|
163
|
+
this.platform.debug(`Color Bulb ${this.accessory.displayName} On: ${this.On}`);
|
|
169
164
|
this.deviceStatus.body.brightness = Number(this.Brightness);
|
|
170
165
|
this.deviceStatus.body.colorTemperature = Number(this.ColorTemperature);
|
|
171
166
|
}
|
|
172
167
|
|
|
173
168
|
async refreshStatus() {
|
|
174
169
|
try {
|
|
175
|
-
this.platform.debug('Bulb - Reading', `${DeviceURL}/${this.device.deviceId}/status`);
|
|
170
|
+
this.platform.debug('Color Bulb - Reading', `${DeviceURL}/${this.device.deviceId}/status`);
|
|
176
171
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
177
|
-
this.platform.device(`Bulb ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
172
|
+
this.platform.device(`Color Bulb ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
178
173
|
this.parseStatus();
|
|
179
174
|
this.updateHomeKitCharacteristics();
|
|
180
175
|
} catch (e: any) {
|
|
181
|
-
this.platform.log.error(`Bulb ${this.accessory.displayName} failed to refresh status, Error Message ${JSON.stringify(e.message)}`);
|
|
182
|
-
this.platform.debug(`Bulb ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
|
|
176
|
+
this.platform.log.error(`Color Bulb ${this.accessory.displayName} failed to refresh status, Error Message ${JSON.stringify(e.message)}`);
|
|
177
|
+
this.platform.debug(`Color Bulb ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
|
|
183
178
|
this.apiError(e);
|
|
184
179
|
}
|
|
185
180
|
}
|
|
@@ -187,8 +182,8 @@ export class Bulb {
|
|
|
187
182
|
/**
|
|
188
183
|
* Pushes the requested changes to the SwitchBot API
|
|
189
184
|
* deviceType commandType Command command parameter Description
|
|
190
|
-
* Bulb - "command" "turnOff" "default" = set to OFF state
|
|
191
|
-
* Bulb - "command" "turnOn" "default" = set to ON state
|
|
185
|
+
* Color Bulb - "command" "turnOff" "default" = set to OFF state
|
|
186
|
+
* Color Bulb - "command" "turnOn" "default" = set to ON state
|
|
192
187
|
*/
|
|
193
188
|
async pushChanges() {
|
|
194
189
|
const payload = {
|
|
@@ -212,32 +207,32 @@ export class Bulb {
|
|
|
212
207
|
'commandType:',
|
|
213
208
|
payload.commandType,
|
|
214
209
|
);
|
|
215
|
-
this.platform.debug(`Bulb ${this.accessory.displayName} pushchanges: ${JSON.stringify(payload)}`);
|
|
210
|
+
this.platform.debug(`Color Bulb ${this.accessory.displayName} pushchanges: ${JSON.stringify(payload)}`);
|
|
216
211
|
|
|
217
212
|
// Make the API request
|
|
218
213
|
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
219
|
-
this.platform.debug(`Bulb ${this.accessory.displayName} Changes pushed: ${JSON.stringify(push.data)}`);
|
|
214
|
+
this.platform.debug(`Color Bulb ${this.accessory.displayName} Changes pushed: ${JSON.stringify(push.data)}`);
|
|
220
215
|
this.statusCode(push);
|
|
221
216
|
}
|
|
222
217
|
|
|
223
218
|
updateHomeKitCharacteristics() {
|
|
224
219
|
if (this.On === undefined) {
|
|
225
|
-
this.platform.debug(`Bulb ${this.accessory.displayName} On: ${this.On}`);
|
|
220
|
+
this.platform.debug(`Color Bulb ${this.accessory.displayName} On: ${this.On}`);
|
|
226
221
|
} else {
|
|
227
222
|
this.service.updateCharacteristic(this.platform.Characteristic.On, this.On);
|
|
228
|
-
this.platform.device(`Bulb ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
223
|
+
this.platform.device(`Color Bulb ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
229
224
|
}
|
|
230
225
|
if (this.Brightness === undefined) {
|
|
231
|
-
this.platform.debug(`Bulb ${this.accessory.displayName} Brightness: ${this.Brightness}`);
|
|
226
|
+
this.platform.debug(`Color Bulb ${this.accessory.displayName} Brightness: ${this.Brightness}`);
|
|
232
227
|
} else {
|
|
233
228
|
this.service.updateCharacteristic(this.platform.Characteristic.Brightness, this.Brightness);
|
|
234
|
-
this.platform.device(`Bulb ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
|
|
229
|
+
this.platform.device(`Color Bulb ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
|
|
235
230
|
}
|
|
236
231
|
if (this.ColorTemperature === undefined) {
|
|
237
|
-
this.platform.debug(`Bulb ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
|
|
232
|
+
this.platform.debug(`Color Bulb ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
|
|
238
233
|
} else {
|
|
239
234
|
this.service.updateCharacteristic(this.platform.Characteristic.Brightness, this.ColorTemperature);
|
|
240
|
-
this.platform.debug(`Bulb ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
|
|
235
|
+
this.platform.debug(`Color Bulb ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
|
|
241
236
|
}
|
|
242
237
|
}
|
|
243
238
|
|
|
@@ -248,7 +243,7 @@ export class Bulb {
|
|
|
248
243
|
}
|
|
249
244
|
|
|
250
245
|
|
|
251
|
-
private statusCode(push: {
|
|
246
|
+
private statusCode(push: AxiosResponse<{ statusCode: number;}>) {
|
|
252
247
|
switch (push.data.statusCode) {
|
|
253
248
|
case 151:
|
|
254
249
|
this.platform.log.error('Command not supported by this device type.');
|
|
@@ -285,7 +280,7 @@ export class Bulb {
|
|
|
285
280
|
this.platform.debug(`${this.accessory.displayName} - Set On: ${value}`);
|
|
286
281
|
|
|
287
282
|
this.On = value;
|
|
288
|
-
this.
|
|
283
|
+
this.doColorBulbUpdate.next();
|
|
289
284
|
}
|
|
290
285
|
|
|
291
286
|
/**
|
|
@@ -295,7 +290,7 @@ export class Bulb {
|
|
|
295
290
|
this.platform.debug(`${this.accessory.displayName} - Set On: ${value}`);
|
|
296
291
|
|
|
297
292
|
this.Brightness = value;
|
|
298
|
-
this.
|
|
293
|
+
this.doColorBulbUpdate.next();
|
|
299
294
|
}
|
|
300
295
|
|
|
301
296
|
/**
|
|
@@ -305,6 +300,6 @@ export class Bulb {
|
|
|
305
300
|
this.platform.debug(`${this.accessory.displayName} - Set On: ${value}`);
|
|
306
301
|
|
|
307
302
|
this.ColorTemperature = value;
|
|
308
|
-
this.
|
|
303
|
+
this.doColorBulbUpdate.next();
|
|
309
304
|
}
|
|
310
305
|
}
|
package/src/devices/contact.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Service, PlatformAccessory, CharacteristicValue
|
|
1
|
+
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
2
2
|
import { SwitchBotPlatform } from '../platform';
|
|
3
3
|
import { interval, Subject } from 'rxjs';
|
|
4
4
|
import { skipWhile } from 'rxjs/operators';
|
|
5
|
-
import { DeviceURL, device, devicesConfig } from '../settings';
|
|
5
|
+
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Platform Accessory
|
|
@@ -12,34 +12,31 @@ import { DeviceURL, device, devicesConfig } from '../settings';
|
|
|
12
12
|
export class Contact {
|
|
13
13
|
// Services
|
|
14
14
|
private service: Service;
|
|
15
|
-
motionService: Service;
|
|
15
|
+
private motionService: Service;
|
|
16
|
+
private lightSensorService: Service;
|
|
17
|
+
private batteryService?: Service;
|
|
16
18
|
|
|
17
19
|
// Characteristic Values
|
|
18
20
|
ContactSensorState!: CharacteristicValue;
|
|
19
21
|
MotionDetected!: CharacteristicValue;
|
|
22
|
+
CurrentAmbientLightLevel!: CharacteristicValue;
|
|
23
|
+
BatteryLevel!: CharacteristicValue;
|
|
24
|
+
StatusLowBattery!: CharacteristicValue;
|
|
20
25
|
|
|
21
|
-
//
|
|
22
|
-
deviceStatus!:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
switchbot!:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
quick: boolean;
|
|
32
|
-
id: MacAddress;
|
|
33
|
-
}
|
|
34
|
-
) => Promise<any>;
|
|
35
|
-
wait: (
|
|
36
|
-
arg0: number
|
|
37
|
-
) => any;
|
|
38
|
-
};
|
|
26
|
+
// OpenAPI others
|
|
27
|
+
deviceStatus!: deviceStatusResponse;
|
|
28
|
+
|
|
29
|
+
// BLE Others
|
|
30
|
+
switchbot!: switchbot;
|
|
31
|
+
serviceData!: serviceData;
|
|
32
|
+
battery!: serviceData['battery'];
|
|
33
|
+
movement!: serviceData['movement'];
|
|
34
|
+
doorState!: serviceData['doorState'];
|
|
35
|
+
lightLevel!: serviceData['lightLevel'];
|
|
39
36
|
|
|
40
37
|
// Updates
|
|
41
38
|
contactUbpdateInProgress!: boolean;
|
|
42
|
-
doContactUpdate
|
|
39
|
+
doContactUpdate!: Subject<void>;
|
|
43
40
|
|
|
44
41
|
constructor(
|
|
45
42
|
private readonly platform: SwitchBotPlatform,
|
|
@@ -74,7 +71,7 @@ export class Contact {
|
|
|
74
71
|
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-WOCONTACT-W1201500')
|
|
75
72
|
.setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
|
|
76
73
|
|
|
77
|
-
// get the
|
|
74
|
+
// get the Contact service if it exists, otherwise create a new Contact service
|
|
78
75
|
// you can create multiple services for each accessory
|
|
79
76
|
(this.service =
|
|
80
77
|
accessory.getService(this.platform.Service.ContactSensor) ||
|
|
@@ -96,6 +93,20 @@ export class Contact {
|
|
|
96
93
|
|
|
97
94
|
this.motionService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Motion Sensor`);
|
|
98
95
|
|
|
96
|
+
(this.lightSensorService =
|
|
97
|
+
accessory.getService(this.platform.Service.LightSensor) ||
|
|
98
|
+
accessory.addService(this.platform.Service.LightSensor)), `${accessory.displayName} Light Sensor`;
|
|
99
|
+
|
|
100
|
+
this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
|
|
101
|
+
|
|
102
|
+
if (device.ble) {
|
|
103
|
+
(this.batteryService =
|
|
104
|
+
accessory.getService(this.platform.Service.Battery) ||
|
|
105
|
+
accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
106
|
+
|
|
107
|
+
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
108
|
+
}
|
|
109
|
+
|
|
99
110
|
// Retrieve initial values and updateHomekit
|
|
100
111
|
this.updateHomeKitCharacteristics();
|
|
101
112
|
|
|
@@ -121,10 +132,41 @@ export class Contact {
|
|
|
121
132
|
}
|
|
122
133
|
|
|
123
134
|
private async BLEparseStatus() {
|
|
124
|
-
this.
|
|
125
|
-
|
|
126
|
-
this.
|
|
127
|
-
|
|
135
|
+
this.platform.debug('Contact BLE Device parseStatus');
|
|
136
|
+
// Movement
|
|
137
|
+
this.MotionDetected = Boolean(this.movement);
|
|
138
|
+
// Door State
|
|
139
|
+
switch (this.doorState) {
|
|
140
|
+
case 'open':
|
|
141
|
+
case 1:
|
|
142
|
+
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
143
|
+
break;
|
|
144
|
+
case 'close':
|
|
145
|
+
case 0:
|
|
146
|
+
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
147
|
+
break;
|
|
148
|
+
default:
|
|
149
|
+
this.platform.log.error('timeout no closed');
|
|
150
|
+
}
|
|
151
|
+
// Light Level
|
|
152
|
+
switch (this.lightLevel) {
|
|
153
|
+
case 'dark':
|
|
154
|
+
case 0:
|
|
155
|
+
this.CurrentAmbientLightLevel = 0.0001;
|
|
156
|
+
break;
|
|
157
|
+
default:
|
|
158
|
+
this.CurrentAmbientLightLevel = 100000;
|
|
159
|
+
}
|
|
160
|
+
// Battery
|
|
161
|
+
this.BatteryLevel = Number(this.battery);
|
|
162
|
+
if (this.BatteryLevel < 10) {
|
|
163
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
164
|
+
} else {
|
|
165
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
this.platform.debug(`${this.accessory.displayName}, ContactSensorState: ${this.ContactSensorState}, MotionDetected: ${this.MotionDetected}`
|
|
169
|
+
+ `CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}, BatteryLevel: ${this.BatteryLevel}`);
|
|
128
170
|
}
|
|
129
171
|
|
|
130
172
|
private async openAPIparseStatus() {
|
|
@@ -155,8 +197,7 @@ export class Contact {
|
|
|
155
197
|
}
|
|
156
198
|
}
|
|
157
199
|
|
|
158
|
-
private
|
|
159
|
-
this.platform.debug('Contact BLE Device RefreshStatus');
|
|
200
|
+
private connectBLE() {
|
|
160
201
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
161
202
|
const Switchbot = require('node-switchbot');
|
|
162
203
|
const switchbot = new Switchbot();
|
|
@@ -164,47 +205,41 @@ export class Contact {
|
|
|
164
205
|
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
165
206
|
this.device.bleMac = bleMac.toLowerCase();
|
|
166
207
|
this.platform.device(this.device.bleMac!);
|
|
167
|
-
switchbot
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
switchbot
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
this.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
196
|
-
})
|
|
197
|
-
.then(() => {
|
|
198
|
-
switchbot.stopScan();
|
|
199
|
-
this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
200
|
-
})
|
|
201
|
-
.catch(async (error: any) => {
|
|
202
|
-
this.platform.log.error(error);
|
|
203
|
-
await this.openAPIRefreshStatus();
|
|
204
|
-
});
|
|
208
|
+
return switchbot;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private async BLERefreshStatus() {
|
|
212
|
+
this.platform.debug('Contact BLE Device RefreshStatus');
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
214
|
+
const switchbot = this.connectBLE();
|
|
215
|
+
// Start to monitor advertisement packets
|
|
216
|
+
switchbot.startScan({
|
|
217
|
+
model: 'd',
|
|
218
|
+
id: this.device.bleMac,
|
|
219
|
+
}).then(() => {
|
|
220
|
+
// Set an event hander
|
|
221
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
222
|
+
this.serviceData = ad.serviceData;
|
|
223
|
+
this.platform.device(`${this.device.bleMac}: ${JSON.stringify(ad.serviceData)}`);
|
|
224
|
+
this.movement = ad.serviceData.movement;
|
|
225
|
+
this.doorState = ad.serviceData.doorState;
|
|
226
|
+
this.lightLevel = ad.serviceData.lightLevel;
|
|
227
|
+
this.battery = ad.serviceData.battery;
|
|
228
|
+
this.platform.device(`${this.accessory.displayName}, Movement: ${ad.serviceData.movement}, Door State: ${ad.serviceData.doorState},`
|
|
229
|
+
+ ` Light Level: ${ad.serviceData.lightLevel}, Battery: ${ad.serviceData.battery}`);
|
|
230
|
+
};
|
|
231
|
+
// Wait 10 seconds
|
|
232
|
+
return switchbot.wait(10000);
|
|
233
|
+
}).then(() => {
|
|
234
|
+
// Stop to monitor
|
|
235
|
+
switchbot.stopScan();
|
|
205
236
|
this.parseStatus();
|
|
206
237
|
this.updateHomeKitCharacteristics();
|
|
207
|
-
}
|
|
238
|
+
}).catch(async (e: any) => {
|
|
239
|
+
this.platform.log.error(`BLE Connection Failed: ${e.message}`);
|
|
240
|
+
this.platform.log.warn('Using OpenAPI Connection');
|
|
241
|
+
await this.openAPIRefreshStatus();
|
|
242
|
+
});
|
|
208
243
|
}
|
|
209
244
|
|
|
210
245
|
private async openAPIRefreshStatus() {
|
|
@@ -236,10 +271,31 @@ export class Contact {
|
|
|
236
271
|
this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
|
|
237
272
|
this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
|
|
238
273
|
}
|
|
274
|
+
if (this.CurrentAmbientLightLevel === undefined) {
|
|
275
|
+
this.platform.debug(`Contact ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
276
|
+
} else {
|
|
277
|
+
this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
278
|
+
this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
279
|
+
}
|
|
280
|
+
if (this.BatteryLevel === undefined) {
|
|
281
|
+
this.platform.debug(`Contact ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
282
|
+
} else {
|
|
283
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
284
|
+
this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
285
|
+
}
|
|
286
|
+
if (this.StatusLowBattery === undefined) {
|
|
287
|
+
this.platform.debug(`Contact ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
288
|
+
} else {
|
|
289
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
290
|
+
this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
291
|
+
}
|
|
239
292
|
}
|
|
240
293
|
|
|
241
294
|
public apiError(e: any) {
|
|
242
295
|
this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e);
|
|
243
296
|
this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
|
|
297
|
+
this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
|
|
298
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
299
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
244
300
|
}
|
|
245
301
|
}
|