@switchbot/homebridge-switchbot 2.0.0-beta.19 → 2.0.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -1
- package/README.md +1 -2
- package/config.schema.json +51 -32
- package/dist/device/bot.d.ts +32 -29
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +549 -575
- package/dist/device/bot.js.map +1 -1
- package/dist/device/colorbulb.d.ts +33 -15
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +426 -341
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +16 -9
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +246 -208
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +21 -18
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +449 -449
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/humidifier.d.ts +22 -20
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +346 -324
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/lock.d.ts +22 -10
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +257 -178
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +21 -14
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +287 -239
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +23 -10
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +308 -190
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +17 -10
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +225 -193
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +24 -17
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +270 -267
- package/dist/device/plug.js.map +1 -1
- package/dist/device/striplight.d.ts +36 -14
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +447 -299
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +7 -14
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +177 -169
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +3 -5
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +72 -57
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +3 -4
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +47 -33
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +3 -4
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +66 -48
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +3 -4
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +48 -47
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +3 -4
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +47 -33
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +10 -11
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +64 -48
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +7 -12
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +52 -41
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +6 -11
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +52 -42
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +0 -4
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +44 -66
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +3 -3
- package/dist/settings.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/device/bot.ts +551 -589
- package/src/device/colorbulb.ts +441 -375
- package/src/device/contact.ts +249 -213
- package/src/device/curtain.ts +452 -461
- package/src/device/humidifier.ts +358 -365
- package/src/device/lock.ts +263 -179
- package/src/device/meter.ts +302 -253
- package/src/device/meterplus.ts +319 -194
- package/src/device/motion.ts +230 -199
- package/src/device/plug.ts +273 -274
- package/src/device/striplight.ts +460 -316
- package/src/irdevice/airconditioner.ts +181 -183
- package/src/irdevice/airpurifier.ts +70 -60
- package/src/irdevice/camera.ts +46 -36
- package/src/irdevice/fan.ts +64 -49
- package/src/irdevice/light.ts +47 -51
- package/src/irdevice/other.ts +46 -36
- package/src/irdevice/tv.ts +64 -51
- package/src/irdevice/vacuumcleaner.ts +52 -45
- package/src/irdevice/waterheater.ts +50 -45
- package/src/platform.ts +44 -68
- package/src/settings.ts +3 -3
package/src/device/contact.ts
CHANGED
|
@@ -7,6 +7,7 @@ import superStringify from 'super-stringify';
|
|
|
7
7
|
import { SwitchBotPlatform } from '../platform';
|
|
8
8
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
9
9
|
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
|
|
10
|
+
import { IncomingMessage } from 'http';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Platform Accessory
|
|
@@ -45,7 +46,6 @@ export class Contact {
|
|
|
45
46
|
lightLevel!: serviceData['lightLevel'];
|
|
46
47
|
|
|
47
48
|
// Config
|
|
48
|
-
OpenAPI?: boolean;
|
|
49
49
|
set_minLux!: number;
|
|
50
50
|
set_maxLux!: number;
|
|
51
51
|
scanDuration!: number;
|
|
@@ -56,14 +56,17 @@ export class Contact {
|
|
|
56
56
|
contactUbpdateInProgress!: boolean;
|
|
57
57
|
doContactUpdate!: Subject<void>;
|
|
58
58
|
|
|
59
|
+
// Connection
|
|
60
|
+
private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'Both');
|
|
61
|
+
private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'Both');
|
|
62
|
+
|
|
59
63
|
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
60
64
|
// default placeholders
|
|
61
65
|
this.logs(device);
|
|
62
|
-
this.openAPI();
|
|
63
66
|
this.scan(device);
|
|
64
67
|
this.refreshRate(device);
|
|
65
68
|
this.config(device);
|
|
66
|
-
this.
|
|
69
|
+
this.context();
|
|
67
70
|
|
|
68
71
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
69
72
|
this.doContactUpdate = new Subject();
|
|
@@ -132,11 +135,11 @@ export class Contact {
|
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
// Battery Service
|
|
135
|
-
if (!
|
|
138
|
+
if (!this.BLE) {
|
|
136
139
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Battery Service`);
|
|
137
140
|
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
138
141
|
accessory.removeService(this.batteryService!);
|
|
139
|
-
} else if (
|
|
142
|
+
} else if (this.BLE && !this.batteryService) {
|
|
140
143
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Battery Service`);
|
|
141
144
|
(this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
|
|
142
145
|
`${accessory.displayName} Battery`;
|
|
@@ -161,15 +164,19 @@ export class Contact {
|
|
|
161
164
|
* Parse the device status from the SwitchBot api
|
|
162
165
|
*/
|
|
163
166
|
async parseStatus(): Promise<void> {
|
|
164
|
-
if (this.
|
|
167
|
+
if (this.BLE && !this.SwitchToOpenAPI) {
|
|
168
|
+
await this.BLEparseStatus();
|
|
169
|
+
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
170
|
+
this.SwitchToOpenAPI = false;
|
|
165
171
|
await this.openAPIparseStatus();
|
|
166
172
|
} else {
|
|
167
|
-
|
|
173
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
174
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
168
175
|
}
|
|
169
176
|
}
|
|
170
177
|
|
|
171
178
|
async BLEparseStatus(): Promise<void> {
|
|
172
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
179
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
173
180
|
// Door State
|
|
174
181
|
switch (this.doorState) {
|
|
175
182
|
case 'open':
|
|
@@ -220,40 +227,35 @@ export class Contact {
|
|
|
220
227
|
}
|
|
221
228
|
|
|
222
229
|
async openAPIparseStatus(): Promise<void> {
|
|
223
|
-
|
|
224
|
-
|
|
230
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
231
|
+
// Contact State
|
|
232
|
+
if (this.openState === 'open') {
|
|
233
|
+
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
234
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
235
|
+
} else if (this.openState === 'close') {
|
|
236
|
+
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
237
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
238
|
+
} else {
|
|
239
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openState: ${this.openState}`);
|
|
225
240
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
// Light Level
|
|
244
|
-
if (!this.device.contact?.hide_lightsensor) {
|
|
245
|
-
this.set_minLux = this.minLux();
|
|
246
|
-
this.set_maxLux = this.maxLux();
|
|
247
|
-
switch (this.brightness) {
|
|
248
|
-
case 'dim':
|
|
249
|
-
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
250
|
-
break;
|
|
251
|
-
case 'bright':
|
|
252
|
-
default:
|
|
253
|
-
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
254
|
-
}
|
|
255
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
241
|
+
// Motion State
|
|
242
|
+
if (!this.device.contact?.hide_motionsensor) {
|
|
243
|
+
this.MotionDetected = this.moveDetected!;
|
|
244
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
245
|
+
}
|
|
246
|
+
// Light Level
|
|
247
|
+
if (!this.device.contact?.hide_lightsensor) {
|
|
248
|
+
this.set_minLux = this.minLux();
|
|
249
|
+
this.set_maxLux = this.maxLux();
|
|
250
|
+
switch (this.brightness) {
|
|
251
|
+
case 'dim':
|
|
252
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
253
|
+
break;
|
|
254
|
+
case 'bright':
|
|
255
|
+
default:
|
|
256
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
256
257
|
}
|
|
258
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
257
259
|
}
|
|
258
260
|
}
|
|
259
261
|
|
|
@@ -261,15 +263,18 @@ export class Contact {
|
|
|
261
263
|
* Asks the SwitchBot API for the latest device information
|
|
262
264
|
*/
|
|
263
265
|
async refreshStatus(): Promise<void> {
|
|
264
|
-
if (this.
|
|
266
|
+
if (this.BLE) {
|
|
265
267
|
await this.BLERefreshStatus();
|
|
266
|
-
} else {
|
|
268
|
+
} else if (this.OpenAPI) {
|
|
267
269
|
await this.openAPIRefreshStatus();
|
|
270
|
+
} else {
|
|
271
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
272
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
268
273
|
}
|
|
269
274
|
}
|
|
270
275
|
|
|
271
276
|
async BLERefreshStatus(): Promise<void> {
|
|
272
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
277
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
273
278
|
const switchbot = await this.platform.connectBLE();
|
|
274
279
|
// Convert to BLE Address
|
|
275
280
|
this.device.bleMac =
|
|
@@ -330,112 +335,67 @@ export class Contact {
|
|
|
330
335
|
}
|
|
331
336
|
})
|
|
332
337
|
.catch(async (e: any) => {
|
|
333
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
334
|
-
if (this.deviceLogging.includes('debug')) {
|
|
335
|
-
this.errorLog(
|
|
336
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` +
|
|
337
|
-
` Error Message: ${superStringify(e.message)}`,
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
if (this.platform.config.credentials?.token) {
|
|
341
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
342
|
-
this.SwitchToOpenAPI = true;
|
|
343
|
-
await this.openAPIRefreshStatus();
|
|
344
|
-
}
|
|
345
338
|
this.apiError(e);
|
|
339
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
340
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
341
|
+
await this.BLEconnection(switchbot);
|
|
346
342
|
});
|
|
347
343
|
} else {
|
|
348
344
|
await this.BLEconnection(switchbot);
|
|
349
345
|
}
|
|
350
346
|
}
|
|
351
347
|
|
|
352
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
353
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
354
|
-
(async () => {
|
|
355
|
-
// Start to monitor advertisement packets
|
|
356
|
-
await switchbot.startScan({
|
|
357
|
-
model: 'd',
|
|
358
|
-
});
|
|
359
|
-
// Set an event handler
|
|
360
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
361
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
|
|
362
|
-
};
|
|
363
|
-
await switchbot.wait(10000);
|
|
364
|
-
// Stop to monitor
|
|
365
|
-
switchbot.stopScan();
|
|
366
|
-
})();
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
async BLEconnection(switchbot: any): Promise<void> {
|
|
371
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
372
|
-
if (this.platform.config.credentials?.token) {
|
|
373
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
374
|
-
this.SwitchToOpenAPI = true;
|
|
375
|
-
await this.openAPIRefreshStatus();
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
348
|
async openAPIRefreshStatus(): Promise<void> {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
408
|
-
});
|
|
409
|
-
res.on('end', () => {
|
|
410
|
-
try {
|
|
411
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
412
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
413
|
-
this.openState = this.deviceStatus.body.openState;
|
|
414
|
-
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
415
|
-
this.brightness = this.deviceStatus.body.brightness;
|
|
416
|
-
this.parseStatus();
|
|
417
|
-
this.updateHomeKitCharacteristics();
|
|
418
|
-
} catch (e: any) {
|
|
419
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
420
|
-
}
|
|
421
|
-
});
|
|
349
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
350
|
+
try {
|
|
351
|
+
const t = Date.now();
|
|
352
|
+
const nonce = 'requestID';
|
|
353
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
354
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
355
|
+
const sign = signTerm.toString('base64');
|
|
356
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
357
|
+
const options = {
|
|
358
|
+
hostname: HostDomain,
|
|
359
|
+
port: 443,
|
|
360
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
361
|
+
method: 'GET',
|
|
362
|
+
headers: {
|
|
363
|
+
Authorization: this.platform.config.credentials?.token,
|
|
364
|
+
sign: sign,
|
|
365
|
+
nonce: nonce,
|
|
366
|
+
t: t,
|
|
367
|
+
'Content-Type': 'application/json',
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
const req = https.request(options, (res) => {
|
|
371
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
372
|
+
let rawData = '';
|
|
373
|
+
res.on('data', (d) => {
|
|
374
|
+
rawData += d;
|
|
375
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
422
376
|
});
|
|
423
|
-
|
|
424
|
-
|
|
377
|
+
res.on('end', () => {
|
|
378
|
+
try {
|
|
379
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
380
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
381
|
+
this.openState = this.deviceStatus.body.openState;
|
|
382
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
383
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
384
|
+
this.parseStatus();
|
|
385
|
+
this.updateHomeKitCharacteristics();
|
|
386
|
+
} catch (e: any) {
|
|
387
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
388
|
+
}
|
|
425
389
|
});
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
this.apiError(e);
|
|
436
|
-
}
|
|
437
|
-
} else {
|
|
438
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI is disabled, commands will not be sent.`);
|
|
390
|
+
});
|
|
391
|
+
req.on('error', (e: any) => {
|
|
392
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
393
|
+
});
|
|
394
|
+
req.end();
|
|
395
|
+
} catch (e: any) {
|
|
396
|
+
this.apiError(e);
|
|
397
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
398
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
439
399
|
}
|
|
440
400
|
}
|
|
441
401
|
|
|
@@ -446,6 +406,7 @@ export class Contact {
|
|
|
446
406
|
if (this.ContactSensorState === undefined) {
|
|
447
407
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
448
408
|
} else {
|
|
409
|
+
this.accessory.context.ContactSensorState = this.ContactSensorState;
|
|
449
410
|
this.contactSensorservice.updateCharacteristic(this.platform.Characteristic.ContactSensorState, this.ContactSensorState);
|
|
450
411
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic ContactSensorState: ${this.ContactSensorState}`);
|
|
451
412
|
}
|
|
@@ -453,6 +414,7 @@ export class Contact {
|
|
|
453
414
|
if (this.MotionDetected === undefined) {
|
|
454
415
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
455
416
|
} else {
|
|
417
|
+
this.accessory.context.MotionDetected = this.MotionDetected;
|
|
456
418
|
this.motionService?.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
|
|
457
419
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
|
|
458
420
|
}
|
|
@@ -461,115 +423,146 @@ export class Contact {
|
|
|
461
423
|
if (this.CurrentAmbientLightLevel === undefined) {
|
|
462
424
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
463
425
|
} else {
|
|
426
|
+
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
464
427
|
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
465
|
-
this.debugLog(
|
|
466
|
-
`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
428
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
467
429
|
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
468
430
|
);
|
|
469
431
|
}
|
|
470
432
|
}
|
|
471
|
-
if (this.
|
|
433
|
+
if (this.BLE) {
|
|
472
434
|
if (this.BatteryLevel === undefined) {
|
|
473
435
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
474
436
|
} else {
|
|
437
|
+
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
475
438
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
476
439
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
477
440
|
}
|
|
478
441
|
if (this.StatusLowBattery === undefined) {
|
|
479
442
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
480
443
|
} else {
|
|
444
|
+
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
481
445
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
482
446
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
483
447
|
}
|
|
484
448
|
}
|
|
485
449
|
}
|
|
486
450
|
|
|
487
|
-
async
|
|
488
|
-
this.
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
451
|
+
async getCustomBLEAddress(switchbot: any) {
|
|
452
|
+
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
453
|
+
(async () => {
|
|
454
|
+
// Start to monitor advertisement packets
|
|
455
|
+
await switchbot.startScan({
|
|
456
|
+
model: 'd',
|
|
457
|
+
});
|
|
458
|
+
// Set an event handler
|
|
459
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
460
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
|
|
461
|
+
};
|
|
462
|
+
await switchbot.wait(10000);
|
|
463
|
+
// Stop to monitor
|
|
464
|
+
switchbot.stopScan();
|
|
465
|
+
})();
|
|
498
466
|
}
|
|
499
|
-
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
500
467
|
}
|
|
501
468
|
|
|
502
|
-
async
|
|
503
|
-
|
|
504
|
-
if (device.
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
config['ble'] = device.ble;
|
|
509
|
-
}
|
|
510
|
-
if (device.openAPI !== undefined) {
|
|
511
|
-
config['openAPI'] = device.openAPI;
|
|
512
|
-
}
|
|
513
|
-
if (device.logging !== undefined) {
|
|
514
|
-
config['logging'] = device.logging;
|
|
515
|
-
}
|
|
516
|
-
if (device.refreshRate !== undefined) {
|
|
517
|
-
config['refreshRate'] = device.refreshRate;
|
|
518
|
-
}
|
|
519
|
-
if (device.scanDuration !== undefined) {
|
|
520
|
-
config['scanDuration'] = device.scanDuration;
|
|
521
|
-
}
|
|
522
|
-
if (Object.entries(config).length !== 0) {
|
|
523
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
|
|
469
|
+
async BLEconnection(switchbot: any): Promise<void> {
|
|
470
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
471
|
+
if (this.platform.config.credentials?.token && this.device.connectionType !== 'Both') {
|
|
472
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
473
|
+
this.SwitchToOpenAPI = true;
|
|
474
|
+
await this.openAPIRefreshStatus();
|
|
524
475
|
}
|
|
525
476
|
}
|
|
526
477
|
|
|
527
|
-
|
|
528
|
-
if (device.
|
|
529
|
-
this.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
533
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
478
|
+
minLux(): number {
|
|
479
|
+
if (this.device.contact?.set_minLux) {
|
|
480
|
+
this.set_minLux = this.device.contact!.set_minLux!;
|
|
481
|
+
} else {
|
|
482
|
+
this.set_minLux = 1;
|
|
534
483
|
}
|
|
484
|
+
return this.set_minLux;
|
|
535
485
|
}
|
|
536
486
|
|
|
537
|
-
|
|
538
|
-
if (
|
|
539
|
-
this.
|
|
487
|
+
maxLux(): number {
|
|
488
|
+
if (this.device.contact?.set_maxLux) {
|
|
489
|
+
this.set_maxLux = this.device.contact!.set_maxLux!;
|
|
540
490
|
} else {
|
|
541
|
-
this.
|
|
491
|
+
this.set_maxLux = 6001;
|
|
542
492
|
}
|
|
543
|
-
|
|
493
|
+
return this.set_maxLux;
|
|
544
494
|
}
|
|
545
495
|
|
|
546
496
|
async scan(device: device & devicesConfig): Promise<void> {
|
|
547
497
|
if (device.scanDuration) {
|
|
548
498
|
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
549
|
-
if (
|
|
499
|
+
if (this.BLE) {
|
|
550
500
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
551
501
|
}
|
|
552
502
|
} else {
|
|
553
503
|
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
554
|
-
if (this.
|
|
504
|
+
if (this.BLE) {
|
|
555
505
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
556
506
|
}
|
|
557
507
|
}
|
|
558
508
|
}
|
|
559
509
|
|
|
560
|
-
async
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
510
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
511
|
+
switch (res.statusCode) {
|
|
512
|
+
case 151:
|
|
513
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
514
|
+
break;
|
|
515
|
+
case 152:
|
|
516
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
|
|
517
|
+
break;
|
|
518
|
+
case 160:
|
|
519
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
|
|
520
|
+
break;
|
|
521
|
+
case 161:
|
|
522
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
|
|
523
|
+
this.offlineOff();
|
|
524
|
+
break;
|
|
525
|
+
case 171:
|
|
526
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
|
|
527
|
+
this.offlineOff();
|
|
528
|
+
break;
|
|
529
|
+
case 190:
|
|
530
|
+
this.errorLog(
|
|
531
|
+
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
532
|
+
` Or command: ${superStringify(res)} format is invalid`,
|
|
533
|
+
);
|
|
534
|
+
break;
|
|
535
|
+
case 100:
|
|
536
|
+
if (this.platform.debugMode) {
|
|
537
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
|
|
538
|
+
}
|
|
539
|
+
break;
|
|
540
|
+
default:
|
|
541
|
+
if (this.platform.debugMode) {
|
|
542
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
async offlineOff(): Promise<void> {
|
|
548
|
+
if (this.device.offline) {
|
|
549
|
+
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
550
|
+
this.contactSensorservice.getCharacteristic(this.platform.Characteristic.ContactSensorState).updateValue(this.ContactSensorState);
|
|
551
|
+
await this.updateHomeKitCharacteristics();
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
async apiError(e: any): Promise<void> {
|
|
556
|
+
this.contactSensorservice.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e);
|
|
557
|
+
if (!this.device.contact?.hide_motionsensor) {
|
|
558
|
+
this.motionService?.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
|
|
559
|
+
}
|
|
560
|
+
if (!this.device.contact?.hide_lightsensor) {
|
|
561
|
+
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
|
|
562
|
+
}
|
|
563
|
+
if (this.BLE) {
|
|
564
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
565
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
573
566
|
}
|
|
574
567
|
}
|
|
575
568
|
|
|
@@ -589,22 +582,65 @@ export class Contact {
|
|
|
589
582
|
return FirmwareRevision;
|
|
590
583
|
}
|
|
591
584
|
|
|
592
|
-
|
|
593
|
-
if (this.
|
|
594
|
-
this.
|
|
585
|
+
async context() {
|
|
586
|
+
if (this.MotionDetected === undefined) {
|
|
587
|
+
this.MotionDetected = false;
|
|
595
588
|
} else {
|
|
596
|
-
this.
|
|
589
|
+
this.MotionDetected = this.accessory.context.MotionDetected;
|
|
590
|
+
}
|
|
591
|
+
if (this.ContactSensorState === undefined) {
|
|
592
|
+
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
593
|
+
} else {
|
|
594
|
+
this.ContactSensorState = this.accessory.context.ContactSensorState;
|
|
597
595
|
}
|
|
598
|
-
return this.set_minLux;
|
|
599
596
|
}
|
|
600
597
|
|
|
601
|
-
|
|
602
|
-
if (
|
|
603
|
-
this.
|
|
598
|
+
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
599
|
+
if (device.refreshRate) {
|
|
600
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
601
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
602
|
+
} else if (this.platform.config.options!.refreshRate) {
|
|
603
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
604
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
async config(device: device & devicesConfig): Promise<void> {
|
|
609
|
+
let config = {};
|
|
610
|
+
if (device.contact) {
|
|
611
|
+
config = device.contact;
|
|
612
|
+
}
|
|
613
|
+
if (device.connectionType !== undefined) {
|
|
614
|
+
config['connectionType'] = device.connectionType;
|
|
615
|
+
}
|
|
616
|
+
if (device.logging !== undefined) {
|
|
617
|
+
config['logging'] = device.logging;
|
|
618
|
+
}
|
|
619
|
+
if (device.refreshRate !== undefined) {
|
|
620
|
+
config['refreshRate'] = device.refreshRate;
|
|
621
|
+
}
|
|
622
|
+
if (device.scanDuration !== undefined) {
|
|
623
|
+
config['scanDuration'] = device.scanDuration;
|
|
624
|
+
}
|
|
625
|
+
if (Object.entries(config).length !== 0) {
|
|
626
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
async logs(device: device & devicesConfig): Promise<void> {
|
|
631
|
+
if (this.platform.debugMode) {
|
|
632
|
+
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
633
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
634
|
+
} else if (device.logging) {
|
|
635
|
+
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
636
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
637
|
+
} else if (this.platform.config.options?.logging) {
|
|
638
|
+
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
639
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
604
640
|
} else {
|
|
605
|
-
this.
|
|
641
|
+
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
642
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
606
643
|
}
|
|
607
|
-
return this.set_maxLux;
|
|
608
644
|
}
|
|
609
645
|
|
|
610
646
|
/**
|