@switchbot/homebridge-switchbot 1.15.1-beta.0 → 1.15.1-beta.10
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 -0
- package/.github/ISSUE_TEMPLATE/feature-request.yml +1 -0
- package/.github/ISSUE_TEMPLATE/support-request.yml +1 -0
- package/.prettierrc +1 -1
- package/CHANGELOG.md +9 -0
- package/config.schema.json +11 -4
- package/dist/device/bot.d.ts +8 -7
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +104 -28
- package/dist/device/bot.js.map +1 -1
- package/dist/device/colorbulb.d.ts +8 -7
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +223 -58
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +3 -3
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +54 -11
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +9 -8
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +102 -28
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/humidifier.d.ts +8 -7
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +187 -66
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/lock.d.ts +8 -7
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +98 -22
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +4 -4
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +55 -12
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +3 -3
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +53 -10
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +3 -3
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +53 -13
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +8 -7
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +100 -24
- package/dist/device/plug.js.map +1 -1
- package/dist/device/striplight.d.ts +8 -7
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +186 -47
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +7 -6
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +40 -6
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +7 -6
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +46 -11
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +7 -6
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +40 -6
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +8 -7
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +40 -6
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +7 -6
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +40 -6
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +7 -6
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +40 -6
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +8 -7
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +40 -6
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +7 -6
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +40 -6
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +7 -6
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +40 -6
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +10 -6
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +211 -93
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +4 -21
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +3 -3
- package/dist/settings.js.map +1 -1
- package/package.json +12 -12
- package/src/device/bot.ts +104 -37
- package/src/device/colorbulb.ts +227 -95
- package/src/device/contact.ts +53 -14
- package/src/device/curtain.ts +105 -38
- package/src/device/humidifier.ts +189 -84
- package/src/device/lock.ts +97 -30
- package/src/device/meter.ts +55 -16
- package/src/device/meterplus.ts +52 -13
- package/src/device/motion.ts +52 -16
- package/src/device/plug.ts +101 -33
- package/src/device/striplight.ts +189 -68
- package/src/irdevice/airconditioner.ts +44 -9
- package/src/irdevice/airpurifier.ts +52 -17
- package/src/irdevice/camera.ts +46 -11
- package/src/irdevice/fan.ts +50 -15
- package/src/irdevice/light.ts +48 -13
- package/src/irdevice/other.ts +46 -11
- package/src/irdevice/tv.ts +56 -21
- package/src/irdevice/vacuumcleaner.ts +46 -11
- package/src/irdevice/waterheater.ts +46 -11
- package/src/platform.ts +232 -107
- package/src/settings.ts +4 -25
package/src/device/meterplus.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { Context } from 'vm';
|
|
1
4
|
import { interval, Subject } from 'rxjs';
|
|
2
5
|
import { skipWhile } from 'rxjs/operators';
|
|
3
6
|
import { SwitchBotPlatform } from '../platform';
|
|
4
7
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import {
|
|
6
|
-
import { Context } from 'vm';
|
|
8
|
+
import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, HostDomain, DevicePath } from '../settings';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Platform Accessory
|
|
@@ -30,7 +32,7 @@ export class MeterPlus {
|
|
|
30
32
|
// OpenAPI Others
|
|
31
33
|
Temperature: deviceStatus['temperature'];
|
|
32
34
|
Humidity: deviceStatus['humidity'];
|
|
33
|
-
deviceStatus!: deviceStatusResponse;
|
|
35
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
34
36
|
|
|
35
37
|
// BLE Others
|
|
36
38
|
connected?: boolean;
|
|
@@ -208,7 +210,7 @@ export class MeterPlus {
|
|
|
208
210
|
if (this.device.ble) {
|
|
209
211
|
this.SwitchToOpenAPI = false;
|
|
210
212
|
}
|
|
211
|
-
if (this.platform.config.credentials?.
|
|
213
|
+
if (this.platform.config.credentials?.token) {
|
|
212
214
|
this.debugLog(`Meter Plus: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
213
215
|
// Current Relative Humidity
|
|
214
216
|
if (!this.device.meter?.hide_humidity) {
|
|
@@ -301,7 +303,7 @@ export class MeterPlus {
|
|
|
301
303
|
`Meter Plus: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
302
304
|
);
|
|
303
305
|
}
|
|
304
|
-
if (this.platform.config.credentials?.
|
|
306
|
+
if (this.platform.config.credentials?.token) {
|
|
305
307
|
this.warnLog(`Meter Plus: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
306
308
|
this.SwitchToOpenAPI = true;
|
|
307
309
|
this.openAPIRefreshStatus();
|
|
@@ -333,7 +335,7 @@ export class MeterPlus {
|
|
|
333
335
|
|
|
334
336
|
async BLEconnection(switchbot: any): Promise<void> {
|
|
335
337
|
this.errorLog(`Meter Plus: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
336
|
-
if (this.platform.config.credentials?.
|
|
338
|
+
if (this.platform.config.credentials?.token) {
|
|
337
339
|
this.warnLog(`Meter Plus: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
338
340
|
this.SwitchToOpenAPI = true;
|
|
339
341
|
await this.openAPIRefreshStatus();
|
|
@@ -341,15 +343,52 @@ export class MeterPlus {
|
|
|
341
343
|
}
|
|
342
344
|
|
|
343
345
|
async openAPIRefreshStatus(): Promise<void> {
|
|
344
|
-
if (this.platform.config.credentials?.
|
|
346
|
+
if (this.platform.config.credentials?.token) {
|
|
345
347
|
this.debugLog(`Meter Plus: ${this.accessory.displayName} OpenAPI RefreshStatus`);
|
|
346
348
|
try {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
this.
|
|
349
|
+
const t = Date.now();
|
|
350
|
+
const nonce = 'requestID';
|
|
351
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
352
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
353
|
+
const sign = signTerm.toString('base64');
|
|
354
|
+
this.debugLog(`Meter Plus: ${this.accessory.displayName} sign: ${sign}`);
|
|
355
|
+
const options = {
|
|
356
|
+
hostname: HostDomain,
|
|
357
|
+
port: 443,
|
|
358
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
359
|
+
method: 'GET',
|
|
360
|
+
headers: {
|
|
361
|
+
Authorization: this.platform.config.credentials?.token,
|
|
362
|
+
sign: sign,
|
|
363
|
+
nonce: nonce,
|
|
364
|
+
t: t,
|
|
365
|
+
'Content-Type': 'application/json',
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
const req = https.request(options, (res) => {
|
|
369
|
+
this.debugLog(`Meter Plus: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
370
|
+
let rawData = '';
|
|
371
|
+
res.on('data', (d) => {
|
|
372
|
+
rawData += d;
|
|
373
|
+
this.debugLog(`Meter Plus: ${this.accessory.displayName} d: ${d}`);
|
|
374
|
+
});
|
|
375
|
+
res.on('end', () => {
|
|
376
|
+
try {
|
|
377
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
378
|
+
this.debugLog(`Meter Plus: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
379
|
+
this.Humidity = this.deviceStatus.body.humidity!;
|
|
380
|
+
this.Temperature = this.deviceStatus.body.temperature!;
|
|
381
|
+
this.parseStatus();
|
|
382
|
+
this.updateHomeKitCharacteristics();
|
|
383
|
+
} catch (e: any) {
|
|
384
|
+
this.errorLog(`Meter Plus: ${this.accessory.displayName} error message: ${e.message}`);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
req.on('error', (e: any) => {
|
|
389
|
+
this.errorLog(`Meter Plus: ${this.accessory.displayName} error message: ${e.message}`);
|
|
390
|
+
});
|
|
391
|
+
req.end();
|
|
353
392
|
} catch (e: any) {
|
|
354
393
|
this.errorLog(`Meter Plus: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
355
394
|
if (this.deviceLogging.includes('debug')) {
|
package/src/device/motion.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { Context } from 'vm';
|
|
1
4
|
import { interval, Subject } from 'rxjs';
|
|
2
5
|
import { skipWhile } from 'rxjs/operators';
|
|
3
6
|
import { SwitchBotPlatform } from '../platform';
|
|
4
7
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import {
|
|
6
|
-
import { Context } from 'vm';
|
|
8
|
+
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Platform Accessory
|
|
@@ -23,7 +25,7 @@ export class Motion {
|
|
|
23
25
|
StatusLowBattery?: CharacteristicValue;
|
|
24
26
|
|
|
25
27
|
// OpenAPI Others
|
|
26
|
-
deviceStatus!: deviceStatusResponse;
|
|
28
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
27
29
|
moveDetected: deviceStatus['moveDetected'];
|
|
28
30
|
brightness: deviceStatus['brightness'];
|
|
29
31
|
|
|
@@ -181,7 +183,7 @@ export class Motion {
|
|
|
181
183
|
if (this.device.ble) {
|
|
182
184
|
this.SwitchToOpenAPI = false;
|
|
183
185
|
}
|
|
184
|
-
if (this.platform.config.credentials?.
|
|
186
|
+
if (this.platform.config.credentials?.token) {
|
|
185
187
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
186
188
|
// Motion State
|
|
187
189
|
this.MotionDetected = this.moveDetected!;
|
|
@@ -283,7 +285,7 @@ export class Motion {
|
|
|
283
285
|
` Error Message: ${JSON.stringify(e.message)}`,
|
|
284
286
|
);
|
|
285
287
|
}
|
|
286
|
-
if (this.platform.config.credentials?.
|
|
288
|
+
if (this.platform.config.credentials?.token) {
|
|
287
289
|
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
288
290
|
this.SwitchToOpenAPI = true;
|
|
289
291
|
await this.openAPIRefreshStatus();
|
|
@@ -315,7 +317,7 @@ export class Motion {
|
|
|
315
317
|
|
|
316
318
|
async BLEconnection(switchbot: any): Promise<void> {
|
|
317
319
|
this.errorLog(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
318
|
-
if (this.platform.config.credentials?.
|
|
320
|
+
if (this.platform.config.credentials?.token) {
|
|
319
321
|
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
320
322
|
this.SwitchToOpenAPI = true;
|
|
321
323
|
await this.openAPIRefreshStatus();
|
|
@@ -323,18 +325,52 @@ export class Motion {
|
|
|
323
325
|
}
|
|
324
326
|
|
|
325
327
|
async openAPIRefreshStatus(): Promise<void> {
|
|
326
|
-
if (this.platform.config.credentials?.
|
|
328
|
+
if (this.platform.config.credentials?.token) {
|
|
327
329
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI RefreshStatus`);
|
|
328
330
|
try {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
this.
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
331
|
+
const t = Date.now();
|
|
332
|
+
const nonce = 'requestID';
|
|
333
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
334
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
335
|
+
const sign = signTerm.toString('base64');
|
|
336
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} sign: ${sign}`);
|
|
337
|
+
const options = {
|
|
338
|
+
hostname: HostDomain,
|
|
339
|
+
port: 443,
|
|
340
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
341
|
+
method: 'GET',
|
|
342
|
+
headers: {
|
|
343
|
+
Authorization: this.platform.config.credentials?.token,
|
|
344
|
+
sign: sign,
|
|
345
|
+
nonce: nonce,
|
|
346
|
+
t: t,
|
|
347
|
+
'Content-Type': 'application/json',
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
const req = https.request(options, (res) => {
|
|
351
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
352
|
+
let rawData = '';
|
|
353
|
+
res.on('data', (d) => {
|
|
354
|
+
rawData += d;
|
|
355
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} d: ${d}`);
|
|
356
|
+
});
|
|
357
|
+
res.on('end', () => {
|
|
358
|
+
try {
|
|
359
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
360
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
361
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
362
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
363
|
+
this.parseStatus();
|
|
364
|
+
this.updateHomeKitCharacteristics();
|
|
365
|
+
} catch (e: any) {
|
|
366
|
+
this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
req.on('error', (e: any) => {
|
|
371
|
+
this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
|
|
372
|
+
});
|
|
373
|
+
req.end();
|
|
338
374
|
} catch (e: any) {
|
|
339
375
|
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
340
376
|
if (this.deviceLogging.includes('debug')) {
|
package/src/device/plug.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { Context } from 'vm';
|
|
4
|
+
import { IncomingMessage } from 'http';
|
|
2
5
|
import { interval, Subject } from 'rxjs';
|
|
3
6
|
import { SwitchBotPlatform } from '../platform';
|
|
4
7
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
5
8
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
6
|
-
import {
|
|
7
|
-
import { Context } from 'vm';
|
|
9
|
+
import { device, devicesConfig, deviceStatus, ad, serviceData, switchbot, HostDomain, DevicePath } from '../settings';
|
|
8
10
|
|
|
9
11
|
export class Plug {
|
|
10
12
|
// Services
|
|
@@ -16,7 +18,7 @@ export class Plug {
|
|
|
16
18
|
|
|
17
19
|
// OpenAPI Others
|
|
18
20
|
power: deviceStatus['power'];
|
|
19
|
-
deviceStatus!: deviceStatusResponse;
|
|
21
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
20
22
|
|
|
21
23
|
// BLE Others
|
|
22
24
|
connected?: boolean;
|
|
@@ -232,7 +234,7 @@ export class Plug {
|
|
|
232
234
|
`Plug: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
233
235
|
);
|
|
234
236
|
}
|
|
235
|
-
if (this.platform.config.credentials?.
|
|
237
|
+
if (this.platform.config.credentials?.token) {
|
|
236
238
|
this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
237
239
|
this.SwitchToOpenAPI = true;
|
|
238
240
|
await this.openAPIRefreshStatus();
|
|
@@ -272,7 +274,7 @@ export class Plug {
|
|
|
272
274
|
|
|
273
275
|
async BLEconnection(switchbot: any): Promise<void> {
|
|
274
276
|
this.errorLog(`Plug: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
275
|
-
if (this.platform.config.credentials?.
|
|
277
|
+
if (this.platform.config.credentials?.token) {
|
|
276
278
|
this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
277
279
|
this.SwitchToOpenAPI = true;
|
|
278
280
|
await this.openAPIRefreshStatus();
|
|
@@ -281,11 +283,48 @@ export class Plug {
|
|
|
281
283
|
|
|
282
284
|
async openAPIRefreshStatus() {
|
|
283
285
|
try {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
this.
|
|
288
|
-
|
|
286
|
+
const t = Date.now();
|
|
287
|
+
const nonce = 'requestID';
|
|
288
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
289
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
290
|
+
const sign = signTerm.toString('base64');
|
|
291
|
+
this.debugLog(`Plug: ${this.accessory.displayName} sign: ${sign}`);
|
|
292
|
+
const options = {
|
|
293
|
+
hostname: HostDomain,
|
|
294
|
+
port: 443,
|
|
295
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
296
|
+
method: 'GET',
|
|
297
|
+
headers: {
|
|
298
|
+
Authorization: this.platform.config.credentials?.token,
|
|
299
|
+
sign: sign,
|
|
300
|
+
nonce: nonce,
|
|
301
|
+
t: t,
|
|
302
|
+
'Content-Type': 'application/json',
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
const req = https.request(options, (res) => {
|
|
306
|
+
this.debugLog(`Plug: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
307
|
+
let rawData = '';
|
|
308
|
+
res.on('data', (d) => {
|
|
309
|
+
rawData += d;
|
|
310
|
+
this.debugLog(`Plug: ${this.accessory.displayName} d: ${d}`);
|
|
311
|
+
});
|
|
312
|
+
res.on('end', () => {
|
|
313
|
+
try {
|
|
314
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
315
|
+
this.debugLog(`Plug: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
316
|
+
this.power = this.deviceStatus.body.power;
|
|
317
|
+
this.parseStatus();
|
|
318
|
+
this.updateHomeKitCharacteristics();
|
|
319
|
+
} catch (e: any) {
|
|
320
|
+
this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
req.on('error', (e: any) => {
|
|
325
|
+
this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
|
|
326
|
+
});
|
|
327
|
+
req.end();
|
|
289
328
|
} catch (e: any) {
|
|
290
329
|
this.errorLog(`Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
291
330
|
if (this.deviceLogging.includes('debug')) {
|
|
@@ -350,7 +389,7 @@ export class Plug {
|
|
|
350
389
|
if (this.platform.debugMode) {
|
|
351
390
|
this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error: ${JSON.stringify(e)}`);
|
|
352
391
|
}
|
|
353
|
-
if (this.platform.config.credentials?.
|
|
392
|
+
if (this.platform.config.credentials?.token) {
|
|
354
393
|
this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
355
394
|
await this.openAPIpushChanges();
|
|
356
395
|
}
|
|
@@ -374,29 +413,58 @@ export class Plug {
|
|
|
374
413
|
}
|
|
375
414
|
|
|
376
415
|
async openAPIpushChanges() {
|
|
377
|
-
if (this.platform.config.credentials?.
|
|
416
|
+
if (this.platform.config.credentials?.token) {
|
|
378
417
|
if (this.On !== this.OnCached) {
|
|
418
|
+
// Make Push On request to the API
|
|
379
419
|
this.debugLog(`Plug: ${this.accessory.displayName} OpenAPI pushChanges`);
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
420
|
+
const t = Date.now();
|
|
421
|
+
const nonce = 'requestID';
|
|
422
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
423
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
|
|
424
|
+
.update(Buffer.from(data, 'utf-8'))
|
|
425
|
+
.digest();
|
|
426
|
+
const sign = signTerm.toString('base64');
|
|
427
|
+
this.debugLog(`Plug: ${this.accessory.displayName} sign: ${sign}`);
|
|
428
|
+
|
|
429
|
+
let command = '';
|
|
385
430
|
if (this.On) {
|
|
386
|
-
|
|
431
|
+
command = 'turnOn';
|
|
387
432
|
} else {
|
|
388
|
-
|
|
433
|
+
command = 'turnOff';
|
|
389
434
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
);
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
435
|
+
const body = JSON.stringify({
|
|
436
|
+
'command': `${command}`,
|
|
437
|
+
'parameter': 'default',
|
|
438
|
+
'commandType': 'command',
|
|
439
|
+
});
|
|
440
|
+
this.infoLog(`Plug: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
441
|
+
const options = {
|
|
442
|
+
hostname: HostDomain,
|
|
443
|
+
port: 443,
|
|
444
|
+
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
445
|
+
method: 'POST',
|
|
446
|
+
headers: {
|
|
447
|
+
'Authorization': this.platform.config.credentials?.token,
|
|
448
|
+
'sign': sign,
|
|
449
|
+
'nonce': nonce,
|
|
450
|
+
't': t,
|
|
451
|
+
'Content-Type': 'application/json',
|
|
452
|
+
'Content-Length': body.length,
|
|
453
|
+
},
|
|
454
|
+
};
|
|
455
|
+
const req = https.request(options, res => {
|
|
456
|
+
this.debugLog(`Plug: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
457
|
+
this.statusCode({ res });
|
|
458
|
+
res.on('data', d => {
|
|
459
|
+
this.debugLog(`Plug: ${this.accessory.displayName} d: ${d}`);
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
req.on('error', (e: any) => {
|
|
463
|
+
this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
|
|
464
|
+
});
|
|
465
|
+
req.write(body);
|
|
466
|
+
req.end();
|
|
467
|
+
this.debugLog(`Plug: ${this.accessory.displayName} openAPIpushChanges: ${JSON.stringify(req)}`);
|
|
400
468
|
this.OnCached = this.On;
|
|
401
469
|
this.accessory.context.On = this.OnCached;
|
|
402
470
|
}
|
|
@@ -422,8 +490,8 @@ export class Plug {
|
|
|
422
490
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
423
491
|
}
|
|
424
492
|
|
|
425
|
-
async statusCode(
|
|
426
|
-
switch (
|
|
493
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
494
|
+
switch (res.statusCode) {
|
|
427
495
|
case 151:
|
|
428
496
|
this.errorLog(`Plug: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
429
497
|
break;
|
|
@@ -444,7 +512,7 @@ export class Plug {
|
|
|
444
512
|
case 190:
|
|
445
513
|
this.errorLog(
|
|
446
514
|
`Plug: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
447
|
-
` Or command: ${JSON.stringify(
|
|
515
|
+
` Or command: ${JSON.stringify(res)} format is invalid`,
|
|
448
516
|
);
|
|
449
517
|
break;
|
|
450
518
|
case 100:
|