@switchbot/homebridge-switchbot 0.1.2-beta.0 → 0.1.2-beta.12
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/bug-report.yml +1 -1
- package/.github/ISSUE_TEMPLATE/config.yml +6 -6
- package/.github/ISSUE_TEMPLATE/support-request.yml +1 -1
- package/.github/PULL_REQUEST_TEMPLATE/pull_requests.md +26 -6
- package/.github/dependabot.yml +2 -0
- package/.github/workflows/codeql-analysis.yml +71 -0
- package/.github/workflows/issue-validate.yml +3 -3
- package/.github/workflows/nodejs-beta.yml +4 -4
- package/.github/workflows/nodejs.yml +4 -4
- package/CHANGELOG.md +5 -1
- package/config.schema.json +18 -15
- package/dist/devices/bots.d.ts +1 -0
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +72 -24
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/bulb.d.ts +10 -1
- package/dist/devices/bulb.d.ts.map +1 -1
- package/dist/devices/bulb.js +13 -2
- package/dist/devices/bulb.js.map +1 -1
- package/dist/devices/contact.d.ts +13 -3
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +78 -3
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +19 -8
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +98 -21
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +4 -4
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/indoorcam.d.ts +42 -0
- package/dist/devices/indoorcam.d.ts.map +1 -0
- package/dist/devices/indoorcam.js +235 -0
- package/dist/devices/indoorcam.js.map +1 -0
- package/dist/devices/meters.d.ts +13 -4
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +36 -17
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +11 -3
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +70 -8
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +11 -1
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +67 -1
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.js +2 -2
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.js +2 -2
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.js +1 -1
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.js +1 -1
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.js +3 -3
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.js +1 -1
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +2 -3
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +1 -1
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/platform.d.ts +1 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +104 -93
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +1 -2
- package/dist/settings.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/devices/bots.ts +87 -37
- package/src/devices/bulb.ts +33 -3
- package/src/devices/contact.ts +102 -10
- package/src/devices/curtains.ts +137 -37
- package/src/devices/humidifiers.ts +9 -4
- package/src/devices/indoorcam.ts +304 -0
- package/src/devices/meters.ts +58 -22
- package/src/devices/motion.ts +93 -13
- package/src/devices/plugs.ts +89 -4
- package/src/irdevices/airconditioners.ts +2 -2
- package/src/irdevices/airpurifiers.ts +2 -2
- package/src/irdevices/cameras.ts +1 -1
- package/src/irdevices/fans.ts +1 -1
- package/src/irdevices/lights.ts +3 -3
- package/src/irdevices/others.ts +1 -1
- package/src/irdevices/tvs.ts +2 -4
- package/src/irdevices/vacuumcleaners.ts +1 -1
- package/src/platform.ts +120 -95
- package/src/settings.ts +1 -2
- package/.github/ISSUE_TEMPLATE.md +0 -48
package/src/devices/contact.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
1
|
+
import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'homebridge';
|
|
2
2
|
import { SwitchBotPlatform } from '../platform';
|
|
3
3
|
import { interval, Subject } from 'rxjs';
|
|
4
4
|
import { skipWhile } from 'rxjs/operators';
|
|
@@ -10,13 +10,32 @@ import { DeviceURL, device, deviceStatusResponse } from '../settings';
|
|
|
10
10
|
* Each accessory may expose multiple services of different service types.
|
|
11
11
|
*/
|
|
12
12
|
export class Contact {
|
|
13
|
+
// Services
|
|
13
14
|
private service: Service;
|
|
14
|
-
|
|
15
|
-
humidityservice?: Service;
|
|
15
|
+
motionService: Service;
|
|
16
16
|
|
|
17
|
+
// Characteristic Values
|
|
17
18
|
ContactSensorState!: CharacteristicValue;
|
|
18
|
-
|
|
19
|
+
MotionDetected!: CharacteristicValue;
|
|
19
20
|
|
|
21
|
+
// Others
|
|
22
|
+
deviceStatus!: deviceStatusResponse;
|
|
23
|
+
switchbot!: {
|
|
24
|
+
discover: (
|
|
25
|
+
arg0:
|
|
26
|
+
{
|
|
27
|
+
duration: any;
|
|
28
|
+
model: string;
|
|
29
|
+
quick: boolean;
|
|
30
|
+
id: MacAddress;
|
|
31
|
+
}
|
|
32
|
+
) => Promise<any>;
|
|
33
|
+
wait: (
|
|
34
|
+
arg0: number
|
|
35
|
+
) => any;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Updates
|
|
20
39
|
contactUbpdateInProgress!: boolean;
|
|
21
40
|
doContactUpdate;
|
|
22
41
|
|
|
@@ -27,7 +46,17 @@ export class Contact {
|
|
|
27
46
|
) {
|
|
28
47
|
// default placeholders
|
|
29
48
|
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
30
|
-
|
|
49
|
+
if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
51
|
+
const SwitchBot = require('node-switchbot');
|
|
52
|
+
this.switchbot = new SwitchBot();
|
|
53
|
+
const colon = device.deviceId!.match(/.{1,2}/g);
|
|
54
|
+
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
55
|
+
this.device.bleMac = bleMac.toLowerCase();
|
|
56
|
+
if (this.platform.config.options.debug === 'device') {
|
|
57
|
+
this.platform.debug(this.device.bleMac.toLowerCase());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
31
60
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
32
61
|
this.doContactUpdate = new Subject();
|
|
33
62
|
this.contactUbpdateInProgress = false;
|
|
@@ -39,14 +68,14 @@ export class Contact {
|
|
|
39
68
|
accessory
|
|
40
69
|
.getService(this.platform.Service.AccessoryInformation)!
|
|
41
70
|
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
|
|
42
|
-
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-CONTACT-')
|
|
71
|
+
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-CONTACT-W1201500')
|
|
43
72
|
.setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId);
|
|
44
73
|
|
|
45
74
|
// get the Battery service if it exists, otherwise create a new Contact service
|
|
46
75
|
// you can create multiple services for each accessory
|
|
47
76
|
(this.service =
|
|
48
77
|
accessory.getService(this.platform.Service.ContactSensor) ||
|
|
49
|
-
accessory.addService(this.platform.Service.ContactSensor)),
|
|
78
|
+
accessory.addService(this.platform.Service.ContactSensor)), `${device.deviceName} ${device.deviceType}`;
|
|
50
79
|
|
|
51
80
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
52
81
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -57,7 +86,10 @@ export class Contact {
|
|
|
57
86
|
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
|
|
58
87
|
|
|
59
88
|
// each service must implement at-minimum the "required characteristics" for the given service type
|
|
60
|
-
// see https://developers.homebridge.io/#/service/
|
|
89
|
+
// see https://developers.homebridge.io/#/service/MotionSensor
|
|
90
|
+
(this.motionService =
|
|
91
|
+
accessory.getService(this.platform.Service.MotionSensor) ||
|
|
92
|
+
accessory.addService(this.platform.Service.MotionSensor)), `${device.deviceName} ${device.deviceType}`;
|
|
61
93
|
|
|
62
94
|
// create handlers for required characteristics
|
|
63
95
|
//this.service.setCharacteristic(this.platform.Characteristic.ChargingState, 2);
|
|
@@ -83,12 +115,69 @@ export class Contact {
|
|
|
83
115
|
} else {
|
|
84
116
|
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
85
117
|
}
|
|
118
|
+
this.MotionDetected = Boolean(this.deviceStatus.body.moveDetected);
|
|
119
|
+
this.platform.debug(`${this.accessory.displayName}
|
|
120
|
+
, ContactSensorState: ${this.ContactSensorState}, MotionDetected: ${this.MotionDetected}`);
|
|
86
121
|
}
|
|
87
122
|
|
|
88
123
|
/**
|
|
89
124
|
* Asks the SwitchBot API for the latest device information
|
|
90
125
|
*/
|
|
91
126
|
async refreshStatus() {
|
|
127
|
+
if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
|
|
128
|
+
this.platform.debug('Contact BLE Device RefreshStatus');
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
130
|
+
const Switchbot = require('node-switchbot');
|
|
131
|
+
const switchbot = new Switchbot();
|
|
132
|
+
const colon = this.device.deviceId!.match(/.{1,2}/g);
|
|
133
|
+
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
134
|
+
this.device.bleMac = bleMac.toLowerCase();
|
|
135
|
+
if (this.platform.config.options.debug === 'device') {
|
|
136
|
+
this.platform.debug(this.device.bleMac!);
|
|
137
|
+
}
|
|
138
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
139
|
+
this.platform.log.info(JSON.stringify(ad, null, ' '));
|
|
140
|
+
this.platform.log.warn('ad:', JSON.stringify(ad));
|
|
141
|
+
};
|
|
142
|
+
switchbot
|
|
143
|
+
.startScan({
|
|
144
|
+
id: this.device.bleMac,
|
|
145
|
+
})
|
|
146
|
+
.then(() => {
|
|
147
|
+
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
148
|
+
})
|
|
149
|
+
.then(() => {
|
|
150
|
+
switchbot.stopScan();
|
|
151
|
+
})
|
|
152
|
+
.catch(async (error: any) => {
|
|
153
|
+
this.platform.log.error(error);
|
|
154
|
+
await this.openAPIRefreshStatus();
|
|
155
|
+
});
|
|
156
|
+
setInterval(() => {
|
|
157
|
+
this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
158
|
+
switchbot
|
|
159
|
+
.startScan({
|
|
160
|
+
mode: 'D',
|
|
161
|
+
id: bleMac,
|
|
162
|
+
})
|
|
163
|
+
.then(() => {
|
|
164
|
+
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
165
|
+
})
|
|
166
|
+
.then(() => {
|
|
167
|
+
switchbot.stopScan();
|
|
168
|
+
this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
169
|
+
})
|
|
170
|
+
.catch(async (error: any) => {
|
|
171
|
+
this.platform.log.error(error);
|
|
172
|
+
await this.openAPIRefreshStatus();
|
|
173
|
+
});
|
|
174
|
+
}, this.platform.config.options!.refreshRate! * 60000);
|
|
175
|
+
} else {
|
|
176
|
+
await this.openAPIRefreshStatus();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private async openAPIRefreshStatus() {
|
|
92
181
|
try {
|
|
93
182
|
const deviceStatus: deviceStatusResponse = (
|
|
94
183
|
await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)
|
|
@@ -105,8 +194,7 @@ export class Contact {
|
|
|
105
194
|
'Contact - Failed to update status of',
|
|
106
195
|
this.device.deviceName,
|
|
107
196
|
JSON.stringify(e.message),
|
|
108
|
-
this.platform.debug(`Contact ${this.accessory.displayName} - ${JSON.stringify(e)}`)
|
|
109
|
-
);
|
|
197
|
+
this.platform.debug(`Contact ${this.accessory.displayName} - ${JSON.stringify(e)}`));
|
|
110
198
|
this.apiError(e);
|
|
111
199
|
}
|
|
112
200
|
}
|
|
@@ -118,9 +206,13 @@ export class Contact {
|
|
|
118
206
|
if (this.ContactSensorState !== undefined) {
|
|
119
207
|
this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, this.ContactSensorState);
|
|
120
208
|
}
|
|
209
|
+
if (this.MotionDetected !== undefined) {
|
|
210
|
+
this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
|
|
211
|
+
}
|
|
121
212
|
}
|
|
122
213
|
|
|
123
214
|
public apiError(e: any) {
|
|
124
215
|
this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e);
|
|
216
|
+
this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
|
|
125
217
|
}
|
|
126
218
|
}
|
package/src/devices/curtains.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
-
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
2
|
+
import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'homebridge';
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { interval, Subject } from 'rxjs';
|
|
5
5
|
import { debounceTime, skipWhile, tap } from 'rxjs/operators';
|
|
@@ -7,31 +7,51 @@ import { DeviceURL, device, deviceStatusResponse } from '../settings';
|
|
|
7
7
|
import { AxiosResponse } from 'axios';
|
|
8
8
|
|
|
9
9
|
export class Curtain {
|
|
10
|
+
// Services
|
|
10
11
|
private service: Service;
|
|
12
|
+
private lightSensorService: Service;
|
|
11
13
|
|
|
14
|
+
// Characteristic Values
|
|
12
15
|
CurrentPosition!: CharacteristicValue;
|
|
13
16
|
PositionState!: CharacteristicValue;
|
|
14
17
|
TargetPosition!: CharacteristicValue;
|
|
15
|
-
|
|
16
|
-
setNewTarget!: boolean;
|
|
17
|
-
setNewTargetTimer!: NodeJS.Timeout;
|
|
18
|
+
CurrentAmbientLightLevel!: CharacteristicValue;
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
switchbot;
|
|
20
|
+
// Others
|
|
21
|
+
deviceStatus!: deviceStatusResponse;
|
|
22
22
|
moveTimer!: NodeJS.Timeout;
|
|
23
|
+
ScanIntervalId!: NodeJS.Timeout;
|
|
24
|
+
setNewTargetTimer!: NodeJS.Timeout;
|
|
25
|
+
AutoDisableFastScanTimeoutId!: NodeJS.Timeout;
|
|
26
|
+
setNewTarget!: boolean;
|
|
23
27
|
moveTime!: number;
|
|
24
28
|
ScanDuration: any;
|
|
25
29
|
ReverseDir: any;
|
|
26
30
|
FastScanEnabled!: boolean;
|
|
27
|
-
ScanIntervalId!: NodeJS.Timeout;
|
|
28
31
|
FastScanInterval!: number;
|
|
29
32
|
SlowScanInterval!: number;
|
|
30
33
|
OpenCloseThreshold: any;
|
|
31
34
|
PreviousPosition: any;
|
|
32
35
|
Position: any;
|
|
33
|
-
AutoDisableFastScanTimeoutId;
|
|
34
36
|
FastScanDuration: number | undefined;
|
|
37
|
+
switchbot!: {
|
|
38
|
+
discover: (
|
|
39
|
+
arg0:
|
|
40
|
+
{
|
|
41
|
+
duration: any;
|
|
42
|
+
model: string;
|
|
43
|
+
quick: boolean;
|
|
44
|
+
id: MacAddress;
|
|
45
|
+
}
|
|
46
|
+
) => Promise<any>;
|
|
47
|
+
wait: (
|
|
48
|
+
arg0: number
|
|
49
|
+
) => any;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Updates
|
|
53
|
+
curtainUpdateInProgress!: boolean;
|
|
54
|
+
doCurtainUpdate;
|
|
35
55
|
|
|
36
56
|
constructor(
|
|
37
57
|
private readonly platform: SwitchBotPlatform,
|
|
@@ -51,8 +71,8 @@ export class Curtain {
|
|
|
51
71
|
const colon = device.deviceId!.match(/.{1,2}/g);
|
|
52
72
|
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
53
73
|
this.device.bleMac = bleMac.toLowerCase();
|
|
54
|
-
if (this.platform.config.options.debug) {
|
|
55
|
-
this.platform.
|
|
74
|
+
if (this.platform.config.options.debug === 'device') {
|
|
75
|
+
this.platform.debug(this.device.bleMac.toLowerCase());
|
|
56
76
|
}
|
|
57
77
|
}
|
|
58
78
|
|
|
@@ -75,7 +95,7 @@ export class Curtain {
|
|
|
75
95
|
// you can create multiple services for each accessory
|
|
76
96
|
(this.service =
|
|
77
97
|
accessory.getService(this.platform.Service.WindowCovering) ||
|
|
78
|
-
accessory.addService(this.platform.Service.WindowCovering)),
|
|
98
|
+
accessory.addService(this.platform.Service.WindowCovering)), `${device.deviceName} ${device.deviceType}`;
|
|
79
99
|
|
|
80
100
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
81
101
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -111,6 +131,21 @@ export class Curtain {
|
|
|
111
131
|
})
|
|
112
132
|
.onSet(this.TargetPositionSet.bind(this));
|
|
113
133
|
|
|
134
|
+
//set up brightness level from the builtin sensor as light sensor accessory
|
|
135
|
+
(this.lightSensorService =
|
|
136
|
+
accessory.getService(this.platform.Service.LightSensor) ||
|
|
137
|
+
accessory.addService(this.platform.Service.LightSensor)), 'Builtin Lightsensor of %s %s', device.deviceName, device.deviceType;
|
|
138
|
+
this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
|
|
139
|
+
// handle on / off events using the On characteristic
|
|
140
|
+
this.lightSensorService.getCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel).onGet(() => {
|
|
141
|
+
if (this.CurrentAmbientLightLevel === 'bright') {
|
|
142
|
+
return 100000;
|
|
143
|
+
} else {
|
|
144
|
+
return 0.0001;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
|
|
114
149
|
// Update Homekit
|
|
115
150
|
this.updateHomeKitCharacteristics();
|
|
116
151
|
|
|
@@ -187,35 +222,94 @@ export class Curtain {
|
|
|
187
222
|
}
|
|
188
223
|
}
|
|
189
224
|
}
|
|
225
|
+
// Brightness
|
|
226
|
+
switch (this.deviceStatus.body.brightness) {
|
|
227
|
+
case 'dim':
|
|
228
|
+
this.CurrentAmbientLightLevel = 0.0001;
|
|
229
|
+
break;
|
|
230
|
+
default:
|
|
231
|
+
this.CurrentAmbientLightLevel = 100000;
|
|
232
|
+
}
|
|
190
233
|
this.platform.debug(
|
|
191
|
-
`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}
|
|
192
|
-
TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState}
|
|
234
|
+
`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}
|
|
235
|
+
, TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState}
|
|
236
|
+
, CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
193
237
|
}
|
|
194
238
|
|
|
195
239
|
async refreshStatus() {
|
|
196
240
|
if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
|
|
197
|
-
this.platform.log.warn('BLE DEVICE-1');
|
|
241
|
+
this.platform.log.warn('BLE DEVICE-REFRESH-1');
|
|
242
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
243
|
+
const Switchbot = require('node-switchbot');
|
|
244
|
+
const switchbot = new Switchbot();
|
|
245
|
+
const colon = this.device.deviceId!.match(/.{1,2}/g);
|
|
246
|
+
const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
|
|
247
|
+
this.device.bleMac = bleMac.toLowerCase();
|
|
248
|
+
if (this.platform.config.options.debug === 'device') {
|
|
249
|
+
this.platform.debug(this.device.bleMac!);
|
|
250
|
+
}
|
|
251
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
252
|
+
this.platform.log.info(JSON.stringify(ad, null, ' '));
|
|
253
|
+
this.platform.log.warn('ad:', JSON.stringify(ad));
|
|
254
|
+
};
|
|
255
|
+
switchbot
|
|
256
|
+
.startScan({
|
|
257
|
+
id: this.device.bleMac,
|
|
258
|
+
})
|
|
259
|
+
.then(() => {
|
|
260
|
+
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
261
|
+
})
|
|
262
|
+
.then(() => {
|
|
263
|
+
switchbot.stopScan();
|
|
264
|
+
})
|
|
265
|
+
.catch(async (error: any) => {
|
|
266
|
+
this.platform.log.error(error);
|
|
267
|
+
await this.openAPIRefreshStatus();
|
|
268
|
+
});
|
|
269
|
+
setInterval(() => {
|
|
270
|
+
this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
271
|
+
switchbot
|
|
272
|
+
.startScan({
|
|
273
|
+
mode: 'T',
|
|
274
|
+
id: bleMac,
|
|
275
|
+
})
|
|
276
|
+
.then(() => {
|
|
277
|
+
return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
|
|
278
|
+
})
|
|
279
|
+
.then(() => {
|
|
280
|
+
switchbot.stopScan();
|
|
281
|
+
this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
|
|
282
|
+
})
|
|
283
|
+
.catch(async (error: any) => {
|
|
284
|
+
this.platform.log.error(error);
|
|
285
|
+
await this.openAPIRefreshStatus();
|
|
286
|
+
});
|
|
287
|
+
}, this.platform.config.options!.refreshRate! * 60000);
|
|
198
288
|
} else {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
this.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
this.platform.debug(`Curtain ${this.accessory.displayName} - ${JSON.stringify(e)}`),
|
|
216
|
-
);
|
|
217
|
-
this.apiError(e);
|
|
289
|
+
await this.openAPIRefreshStatus();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private async openAPIRefreshStatus() {
|
|
294
|
+
try {
|
|
295
|
+
this.platform.debug('Curtain - Reading', `${DeviceURL}/${this.device.deviceId}/status`);
|
|
296
|
+
const deviceStatus: deviceStatusResponse = (
|
|
297
|
+
await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)
|
|
298
|
+
).data;
|
|
299
|
+
if (deviceStatus.message === 'success') {
|
|
300
|
+
this.deviceStatus = deviceStatus;
|
|
301
|
+
this.platform.debug(`Curtain ${this.accessory.displayName} refreshStatus - ${JSON.stringify(this.deviceStatus)}`);
|
|
302
|
+
this.setMinMax();
|
|
303
|
+
this.parseStatus();
|
|
304
|
+
this.updateHomeKitCharacteristics();
|
|
218
305
|
}
|
|
306
|
+
} catch (e: any) {
|
|
307
|
+
this.platform.log.error(
|
|
308
|
+
`Curtain - Failed to refresh status of ${this.device.deviceName}`,
|
|
309
|
+
JSON.stringify(e.message),
|
|
310
|
+
this.platform.debug(`Curtain ${this.accessory.displayName} - ${JSON.stringify(e)}`),
|
|
311
|
+
);
|
|
312
|
+
this.apiError(e);
|
|
219
313
|
}
|
|
220
314
|
}
|
|
221
315
|
|
|
@@ -258,7 +352,9 @@ export class Curtain {
|
|
|
258
352
|
CurrentPosition: this.CurrentPosition,
|
|
259
353
|
PositionState: this.PositionState,
|
|
260
354
|
TargetPosition: this.TargetPosition,
|
|
261
|
-
|
|
355
|
+
CurrentAmbientLightLevel: this.CurrentAmbientLightLevel,
|
|
356
|
+
})}`,
|
|
357
|
+
);
|
|
262
358
|
this.setMinMax();
|
|
263
359
|
if (this.CurrentPosition !== undefined) {
|
|
264
360
|
this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, this.CurrentPosition);
|
|
@@ -269,12 +365,16 @@ export class Curtain {
|
|
|
269
365
|
if (this.TargetPosition !== undefined) {
|
|
270
366
|
this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, this.TargetPosition);
|
|
271
367
|
}
|
|
368
|
+
if (this.CurrentAmbientLightLevel !== undefined) {
|
|
369
|
+
this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
370
|
+
}
|
|
272
371
|
}
|
|
273
372
|
|
|
274
373
|
public apiError(e: any) {
|
|
275
374
|
this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
|
|
276
375
|
this.service.updateCharacteristic(this.platform.Characteristic.PositionState, e);
|
|
277
376
|
this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
|
|
377
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
|
|
278
378
|
}
|
|
279
379
|
|
|
280
380
|
|
|
@@ -406,7 +506,7 @@ export class Curtain {
|
|
|
406
506
|
* Ask the device to start moving to the given position (which must be a device value and not an HomeKit value).
|
|
407
507
|
* Returns a Promise that's resolved as soon as the command was sent to the device.
|
|
408
508
|
*/
|
|
409
|
-
public runToPosition(pos: number): Promise<void> {
|
|
509
|
+
public async runToPosition(pos: number): Promise<void> {
|
|
410
510
|
const SwitchBot = require('node-switchbot');
|
|
411
511
|
const switchbot = new SwitchBot();
|
|
412
512
|
|
|
@@ -533,4 +633,4 @@ export class Curtain {
|
|
|
533
633
|
}
|
|
534
634
|
}
|
|
535
635
|
}
|
|
536
|
-
}
|
|
636
|
+
}
|
|
@@ -11,9 +11,11 @@ import { AxiosResponse } from 'axios';
|
|
|
11
11
|
* Each accessory may expose multiple services of different service types.
|
|
12
12
|
*/
|
|
13
13
|
export class Humidifier {
|
|
14
|
+
// Services
|
|
14
15
|
private service: Service;
|
|
15
16
|
temperatureservice?: Service;
|
|
16
17
|
|
|
18
|
+
// Characteristic Values
|
|
17
19
|
CurrentRelativeHumidity!: CharacteristicValue;
|
|
18
20
|
CurrentTemperature!: CharacteristicValue;
|
|
19
21
|
TargetHumidifierDehumidifierState!: CharacteristicValue;
|
|
@@ -21,8 +23,11 @@ export class Humidifier {
|
|
|
21
23
|
RelativeHumidityHumidifierThreshold!: CharacteristicValue;
|
|
22
24
|
Active!: CharacteristicValue;
|
|
23
25
|
WaterLevel!: CharacteristicValue;
|
|
26
|
+
|
|
27
|
+
// Others
|
|
24
28
|
deviceStatus!: deviceStatusResponse;
|
|
25
29
|
|
|
30
|
+
// Updates
|
|
26
31
|
humidifierUpdateInProgress!: boolean;
|
|
27
32
|
doHumidifierUpdate;
|
|
28
33
|
|
|
@@ -58,7 +63,7 @@ export class Humidifier {
|
|
|
58
63
|
// you can create multiple services for each accessory
|
|
59
64
|
(this.service =
|
|
60
65
|
accessory.getService(this.platform.Service.HumidifierDehumidifier) ||
|
|
61
|
-
accessory.addService(this.platform.Service.HumidifierDehumidifier)),
|
|
66
|
+
accessory.addService(this.platform.Service.HumidifierDehumidifier)), `${device.deviceName} ${device.deviceType}`;
|
|
62
67
|
|
|
63
68
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
64
69
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -102,18 +107,18 @@ export class Humidifier {
|
|
|
102
107
|
// create a new Temperature Sensor service
|
|
103
108
|
// Temperature Sensor Service
|
|
104
109
|
if (this.platform.config.options?.humidifier?.hide_temperature) {
|
|
105
|
-
if (this.platform.config.options.debug) {
|
|
110
|
+
if (this.platform.config.options.debug === 'device') {
|
|
106
111
|
this.platform.log.error('Removing service');
|
|
107
112
|
}
|
|
108
113
|
this.temperatureservice = this.accessory.getService(this.platform.Service.TemperatureSensor);
|
|
109
114
|
accessory.removeService(this.temperatureservice!);
|
|
110
115
|
} else if (!this.temperatureservice) {
|
|
111
|
-
if (this.platform.config.options?.debug) {
|
|
116
|
+
if (this.platform.config.options?.debug === 'device') {
|
|
112
117
|
this.platform.log.warn('Adding service');
|
|
113
118
|
}
|
|
114
119
|
(this.temperatureservice =
|
|
115
120
|
this.accessory.getService(this.platform.Service.TemperatureSensor) ||
|
|
116
|
-
this.accessory.addService(this.platform.Service.TemperatureSensor)),
|
|
121
|
+
this.accessory.addService(this.platform.Service.TemperatureSensor)), `${device.deviceName} ${device.deviceType} TemperatureSensor`;
|
|
117
122
|
|
|
118
123
|
this.temperatureservice
|
|
119
124
|
.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|