@switchbot/homebridge-switchbot 1.15.1-beta.7 → 1.15.1-beta.8
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/.prettierrc +1 -1
- package/dist/device/bot.d.ts +8 -7
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +83 -11
- 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 +182 -23
- 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 +50 -7
- 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 +86 -14
- 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 +152 -27
- 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 +84 -12
- 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 +51 -8
- 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 +49 -6
- 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 +49 -9
- 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 +83 -11
- 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 +149 -19
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +5 -4
- 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 +5 -4
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +40 -6
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +5 -4
- 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 +7 -6
- 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 +5 -4
- 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 +5 -4
- 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 +7 -6
- 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 +5 -4
- 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 +5 -4
- 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 +3 -5
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +141 -95
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +2 -16
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +3 -3
- package/dist/settings.js.map +1 -1
- package/package.json +6 -7
- package/src/device/bot.ts +87 -15
- package/src/device/colorbulb.ts +186 -41
- package/src/device/contact.ts +49 -10
- package/src/device/curtain.ts +92 -19
- package/src/device/humidifier.ts +164 -30
- package/src/device/lock.ts +88 -16
- package/src/device/meter.ts +51 -12
- package/src/device/meterplus.ts +48 -9
- package/src/device/motion.ts +48 -12
- package/src/device/plug.ts +87 -15
- package/src/device/striplight.ts +161 -24
- package/src/irdevice/airconditioner.ts +43 -8
- package/src/irdevice/airpurifier.ts +43 -8
- package/src/irdevice/camera.ts +43 -8
- package/src/irdevice/fan.ts +44 -9
- package/src/irdevice/light.ts +43 -8
- package/src/irdevice/other.ts +43 -8
- package/src/irdevice/tv.ts +44 -9
- package/src/irdevice/vacuumcleaner.ts +43 -8
- package/src/irdevice/waterheater.ts +43 -8
- package/src/platform.ts +154 -108
- package/src/settings.ts +6 -10
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, payload, 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;
|
|
@@ -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')) {
|
|
@@ -394,9 +433,42 @@ export class Plug {
|
|
|
394
433
|
);
|
|
395
434
|
|
|
396
435
|
// Make the API request
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
this.
|
|
436
|
+
const t = Date.now();
|
|
437
|
+
const nonce = 'requestID';
|
|
438
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
439
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
440
|
+
const sign = signTerm.toString('base64');
|
|
441
|
+
this.debugLog(`Plug: ${this.accessory.displayName} sign: ${sign}`);
|
|
442
|
+
const options = {
|
|
443
|
+
hostname: 'api.switch-bot.com',
|
|
444
|
+
port: 443,
|
|
445
|
+
path: `/v1.1/devices/${this.device.deviceId}/commands`,
|
|
446
|
+
method: 'POST',
|
|
447
|
+
headers: {
|
|
448
|
+
Authorization: this.platform.config.credentials?.token,
|
|
449
|
+
sign: sign,
|
|
450
|
+
nonce: nonce,
|
|
451
|
+
t: t,
|
|
452
|
+
'Content-Type': 'application/json',
|
|
453
|
+
},
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
const req = https.request(options, (res) => {
|
|
457
|
+
this.debugLog(`Plug: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
458
|
+
this.statusCode({ res });
|
|
459
|
+
res.on('data', (d) => {
|
|
460
|
+
this.debugLog(`Plug: ${this.accessory.displayName} d: ${d}`);
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
req.on('error', (error) => {
|
|
465
|
+
this.errorLog(`Plug: ${this.accessory.displayName} error: ${error}`);
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
req.write(payload);
|
|
469
|
+
req.end();
|
|
470
|
+
|
|
471
|
+
this.debugLog(`Plug: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
400
472
|
this.OnCached = this.On;
|
|
401
473
|
this.accessory.context.On = this.OnCached;
|
|
402
474
|
}
|
|
@@ -422,8 +494,8 @@ export class Plug {
|
|
|
422
494
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
423
495
|
}
|
|
424
496
|
|
|
425
|
-
async statusCode(
|
|
426
|
-
switch (
|
|
497
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
498
|
+
switch (res.statusCode) {
|
|
427
499
|
case 151:
|
|
428
500
|
this.errorLog(`Plug: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
429
501
|
break;
|
|
@@ -444,7 +516,7 @@ export class Plug {
|
|
|
444
516
|
case 190:
|
|
445
517
|
this.errorLog(
|
|
446
518
|
`Plug: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
447
|
-
` Or command: ${JSON.stringify(
|
|
519
|
+
` Or command: ${JSON.stringify(res)} format is invalid`,
|
|
448
520
|
);
|
|
449
521
|
break;
|
|
450
522
|
case 100:
|
package/src/device/striplight.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, tap } from 'rxjs/operators';
|
|
5
8
|
import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
|
|
6
|
-
import {
|
|
7
|
-
import { Context } from 'vm';
|
|
9
|
+
import { device, devicesConfig, switchbot, payload, hs2rgb, rgb2hs, deviceStatus, HostDomain, DevicePath } from '../settings';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Platform Accessory
|
|
@@ -29,7 +31,7 @@ export class StripLight {
|
|
|
29
31
|
power: deviceStatus['power'];
|
|
30
32
|
color: deviceStatus['color'];
|
|
31
33
|
brightness: deviceStatus['brightness'];
|
|
32
|
-
deviceStatus!: deviceStatusResponse;
|
|
34
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
33
35
|
|
|
34
36
|
// BLE Others
|
|
35
37
|
switchbot!: switchbot;
|
|
@@ -210,14 +212,50 @@ export class StripLight {
|
|
|
210
212
|
|
|
211
213
|
async refreshStatus(): Promise<void> {
|
|
212
214
|
try {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
215
|
+
const t = Date.now();
|
|
216
|
+
const nonce = 'requestID';
|
|
217
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
218
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
219
|
+
const sign = signTerm.toString('base64');
|
|
220
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
|
|
221
|
+
const options = {
|
|
222
|
+
hostname: HostDomain,
|
|
223
|
+
port: 443,
|
|
224
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
225
|
+
method: 'GET',
|
|
226
|
+
headers: {
|
|
227
|
+
Authorization: this.platform.config.credentials?.token,
|
|
228
|
+
sign: sign,
|
|
229
|
+
nonce: nonce,
|
|
230
|
+
t: t,
|
|
231
|
+
'Content-Type': 'application/json',
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
const req = https.request(options, (res) => {
|
|
235
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
236
|
+
let rawData = '';
|
|
237
|
+
res.on('data', (d) => {
|
|
238
|
+
rawData += d;
|
|
239
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} d: ${d}`);
|
|
240
|
+
});
|
|
241
|
+
res.on('end', () => {
|
|
242
|
+
try {
|
|
243
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
244
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
245
|
+
this.power = this.deviceStatus.body.power;
|
|
246
|
+
this.color = this.deviceStatus.body.color;
|
|
247
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
248
|
+
this.parseStatus();
|
|
249
|
+
this.updateHomeKitCharacteristics();
|
|
250
|
+
} catch (e: any) {
|
|
251
|
+
this.errorLog(`Strip Light: ${this.accessory.displayName} error message: ${e.message}`);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
req.on('error', (e: any) => {
|
|
256
|
+
this.errorLog(`Strip Light: ${this.accessory.displayName} error message: ${e.message}`);
|
|
257
|
+
});
|
|
258
|
+
req.end();
|
|
221
259
|
} catch (e: any) {
|
|
222
260
|
this.errorLog(`Strip Light: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
223
261
|
if (this.deviceLogging.includes('debug')) {
|
|
@@ -260,9 +298,42 @@ export class StripLight {
|
|
|
260
298
|
);
|
|
261
299
|
|
|
262
300
|
// Make the API request
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
this.
|
|
301
|
+
const t = Date.now();
|
|
302
|
+
const nonce = 'requestID';
|
|
303
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
304
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
305
|
+
const sign = signTerm.toString('base64');
|
|
306
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
|
|
307
|
+
const options = {
|
|
308
|
+
hostname: 'api.switch-bot.com',
|
|
309
|
+
port: 443,
|
|
310
|
+
path: `/v1.1/devices/${this.device.deviceId}/commands`,
|
|
311
|
+
method: 'POST',
|
|
312
|
+
headers: {
|
|
313
|
+
Authorization: this.platform.config.credentials?.token,
|
|
314
|
+
sign: sign,
|
|
315
|
+
nonce: nonce,
|
|
316
|
+
t: t,
|
|
317
|
+
'Content-Type': 'application/json',
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const req = https.request(options, (res) => {
|
|
322
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
323
|
+
this.statusCode({ res });
|
|
324
|
+
res.on('data', (d) => {
|
|
325
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} d: ${d}`);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
req.on('error', (error) => {
|
|
330
|
+
this.errorLog(`Strip Light: ${this.accessory.displayName} error: ${error}`);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
req.write(payload);
|
|
334
|
+
req.end();
|
|
335
|
+
|
|
336
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
266
337
|
this.OnCached = this.On;
|
|
267
338
|
this.accessory.context.On = this.OnCached;
|
|
268
339
|
}
|
|
@@ -307,9 +378,42 @@ export class StripLight {
|
|
|
307
378
|
);
|
|
308
379
|
|
|
309
380
|
// Make the API request
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
this.
|
|
381
|
+
const t = Date.now();
|
|
382
|
+
const nonce = 'requestID';
|
|
383
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
384
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
385
|
+
const sign = signTerm.toString('base64');
|
|
386
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
|
|
387
|
+
const options = {
|
|
388
|
+
hostname: 'api.switch-bot.com',
|
|
389
|
+
port: 443,
|
|
390
|
+
path: `/v1.1/devices/${this.device.deviceId}/commands`,
|
|
391
|
+
method: 'POST',
|
|
392
|
+
headers: {
|
|
393
|
+
Authorization: this.platform.config.credentials?.token,
|
|
394
|
+
sign: sign,
|
|
395
|
+
nonce: nonce,
|
|
396
|
+
t: t,
|
|
397
|
+
'Content-Type': 'application/json',
|
|
398
|
+
},
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const req = https.request(options, (res) => {
|
|
402
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
403
|
+
this.statusCode({ res });
|
|
404
|
+
res.on('data', (d) => {
|
|
405
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} d: ${d}`);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
req.on('error', (error) => {
|
|
410
|
+
this.errorLog(`Strip Light: ${this.accessory.displayName} error: ${error}`);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
req.write(payload);
|
|
414
|
+
req.end();
|
|
415
|
+
|
|
416
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
313
417
|
this.HueCached = this.Hue;
|
|
314
418
|
this.SaturationCached = this.Saturation;
|
|
315
419
|
} else {
|
|
@@ -344,9 +448,42 @@ export class StripLight {
|
|
|
344
448
|
);
|
|
345
449
|
|
|
346
450
|
// Make the API request
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
this.
|
|
451
|
+
const t = Date.now();
|
|
452
|
+
const nonce = 'requestID';
|
|
453
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
454
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
455
|
+
const sign = signTerm.toString('base64');
|
|
456
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} sign: ${sign}`);
|
|
457
|
+
const options = {
|
|
458
|
+
hostname: 'api.switch-bot.com',
|
|
459
|
+
port: 443,
|
|
460
|
+
path: `/v1.1/devices/${this.device.deviceId}/commands`,
|
|
461
|
+
method: 'POST',
|
|
462
|
+
headers: {
|
|
463
|
+
Authorization: this.platform.config.credentials?.token,
|
|
464
|
+
sign: sign,
|
|
465
|
+
nonce: nonce,
|
|
466
|
+
t: t,
|
|
467
|
+
'Content-Type': 'application/json',
|
|
468
|
+
},
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
const req = https.request(options, (res) => {
|
|
472
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
473
|
+
this.statusCode({ res });
|
|
474
|
+
res.on('data', (d) => {
|
|
475
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} d: ${d}`);
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
req.on('error', (error) => {
|
|
480
|
+
this.errorLog(`Strip Light: ${this.accessory.displayName} error: ${error}`);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
req.write(payload);
|
|
484
|
+
req.end();
|
|
485
|
+
|
|
486
|
+
this.debugLog(`Strip Light: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
350
487
|
this.BrightnessCached = this.Brightness;
|
|
351
488
|
} else {
|
|
352
489
|
this.debugLog(
|
|
@@ -399,8 +536,8 @@ export class StripLight {
|
|
|
399
536
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
400
537
|
}
|
|
401
538
|
|
|
402
|
-
statusCode(
|
|
403
|
-
switch (
|
|
539
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
540
|
+
switch (res.statusCode) {
|
|
404
541
|
case 151:
|
|
405
542
|
this.errorLog(`Strip Light: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
406
543
|
break;
|
|
@@ -421,7 +558,7 @@ export class StripLight {
|
|
|
421
558
|
case 190:
|
|
422
559
|
this.errorLog(
|
|
423
560
|
`Strip Light: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
424
|
-
` Or command: ${JSON.stringify(
|
|
561
|
+
` Or command: ${JSON.stringify(res)} format is invalid`,
|
|
425
562
|
);
|
|
426
563
|
break;
|
|
427
564
|
case 100:
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { IncomingMessage } from 'http';
|
|
2
4
|
import { SwitchBotPlatform } from '../platform';
|
|
3
|
-
import { irDevicesConfig,
|
|
5
|
+
import { irDevicesConfig, irdevice, payload, HostDomain, DevicePath } from '../settings';
|
|
4
6
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -258,9 +260,42 @@ export class AirConditioner {
|
|
|
258
260
|
);
|
|
259
261
|
|
|
260
262
|
// Make the API request
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
this.
|
|
263
|
+
const t = Date.now();
|
|
264
|
+
const nonce = 'requestID';
|
|
265
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
266
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
267
|
+
const sign = signTerm.toString('base64');
|
|
268
|
+
this.debugLog(`Air Conditioner: ${this.accessory.displayName} sign: ${sign}`);
|
|
269
|
+
const options = {
|
|
270
|
+
hostname: HostDomain,
|
|
271
|
+
port: 443,
|
|
272
|
+
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
273
|
+
method: 'POST',
|
|
274
|
+
headers: {
|
|
275
|
+
Authorization: this.platform.config.credentials?.token,
|
|
276
|
+
sign: sign,
|
|
277
|
+
nonce: nonce,
|
|
278
|
+
t: t,
|
|
279
|
+
'Content-Type': 'application/json',
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const req = https.request(options, (res) => {
|
|
284
|
+
this.debugLog(`Air Conditioner: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
285
|
+
this.statusCode({ res });
|
|
286
|
+
res.on('data', (d) => {
|
|
287
|
+
this.debugLog(`Air Conditioner: ${this.accessory.displayName} d: ${d}`);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
req.on('error', (error) => {
|
|
292
|
+
this.errorLog(`Air Conditioner: ${this.accessory.displayName} error: ${error}`);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
req.write(payload);
|
|
296
|
+
req.end();
|
|
297
|
+
|
|
298
|
+
this.debugLog(`Air Conditioner: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
264
299
|
this.CurrentTemperatureCached = this.CurrentTemperature;
|
|
265
300
|
this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
|
|
266
301
|
this.HeatingThresholdTemperature = this.CurrentTemperatureCached;
|
|
@@ -279,8 +314,8 @@ export class AirConditioner {
|
|
|
279
314
|
}
|
|
280
315
|
}
|
|
281
316
|
|
|
282
|
-
async statusCode(
|
|
283
|
-
switch (
|
|
317
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
318
|
+
switch (res.statusCode) {
|
|
284
319
|
case 151:
|
|
285
320
|
this.errorLog(`Air Conditioner: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
286
321
|
break;
|
|
@@ -299,7 +334,7 @@ export class AirConditioner {
|
|
|
299
334
|
case 190:
|
|
300
335
|
this.errorLog(
|
|
301
336
|
`Air Conditioner: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
|
|
302
|
-
` with server, Or command: ${JSON.stringify(
|
|
337
|
+
` with server, Or command: ${JSON.stringify(res)} format is invalid`,
|
|
303
338
|
);
|
|
304
339
|
break;
|
|
305
340
|
case 100:
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { IncomingMessage } from 'http';
|
|
2
4
|
import { SwitchBotPlatform } from '../platform';
|
|
3
|
-
import { irDevicesConfig,
|
|
5
|
+
import { irDevicesConfig, irdevice, payload, HostDomain, DevicePath } from '../settings';
|
|
4
6
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -220,9 +222,42 @@ export class AirPurifier {
|
|
|
220
222
|
);
|
|
221
223
|
|
|
222
224
|
// Make the API request
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
this.
|
|
225
|
+
const t = Date.now();
|
|
226
|
+
const nonce = 'requestID';
|
|
227
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
228
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
229
|
+
const sign = signTerm.toString('base64');
|
|
230
|
+
this.debugLog(`Air Purifier: ${this.accessory.displayName} sign: ${sign}`);
|
|
231
|
+
const options = {
|
|
232
|
+
hostname: HostDomain,
|
|
233
|
+
port: 443,
|
|
234
|
+
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
235
|
+
method: 'POST',
|
|
236
|
+
headers: {
|
|
237
|
+
Authorization: this.platform.config.credentials?.token,
|
|
238
|
+
sign: sign,
|
|
239
|
+
nonce: nonce,
|
|
240
|
+
t: t,
|
|
241
|
+
'Content-Type': 'application/json',
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const req = https.request(options, (res) => {
|
|
246
|
+
this.debugLog(`Air Purifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
247
|
+
this.statusCode({ res });
|
|
248
|
+
res.on('data', (d) => {
|
|
249
|
+
this.debugLog(`Air Purifier: ${this.accessory.displayName} d: ${d}`);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
req.on('error', (error) => {
|
|
254
|
+
this.errorLog(`Air Purifier: ${this.accessory.displayName} error: ${error}`);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
req.write(payload);
|
|
258
|
+
req.end();
|
|
259
|
+
|
|
260
|
+
this.debugLog(`Air Purifier: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
226
261
|
this.updateHomeKitCharacteristics();
|
|
227
262
|
this.CurrentTemperatureCached = this.CurrentTemperature;
|
|
228
263
|
this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
|
|
@@ -237,8 +272,8 @@ export class AirPurifier {
|
|
|
237
272
|
}
|
|
238
273
|
}
|
|
239
274
|
|
|
240
|
-
async statusCode(
|
|
241
|
-
switch (
|
|
275
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
276
|
+
switch (res.statusCode) {
|
|
242
277
|
case 151:
|
|
243
278
|
this.errorLog(`Air Purifier: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
244
279
|
break;
|
|
@@ -257,7 +292,7 @@ export class AirPurifier {
|
|
|
257
292
|
case 190:
|
|
258
293
|
this.errorLog(
|
|
259
294
|
`Air Purifier: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
|
|
260
|
-
` with server, Or command: ${JSON.stringify(
|
|
295
|
+
` with server, Or command: ${JSON.stringify(res)} format is invalid`,
|
|
261
296
|
);
|
|
262
297
|
break;
|
|
263
298
|
case 100:
|
package/src/irdevice/camera.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { IncomingMessage } from 'http';
|
|
2
4
|
import { SwitchBotPlatform } from '../platform';
|
|
3
|
-
import { irDevicesConfig,
|
|
5
|
+
import { irDevicesConfig, irdevice, payload, HostDomain, DevicePath } from '../settings';
|
|
4
6
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -112,9 +114,42 @@ export class Camera {
|
|
|
112
114
|
);
|
|
113
115
|
|
|
114
116
|
// Make the API request
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
this.
|
|
117
|
+
const t = Date.now();
|
|
118
|
+
const nonce = 'requestID';
|
|
119
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
120
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
121
|
+
const sign = signTerm.toString('base64');
|
|
122
|
+
this.debugLog(`Camera: ${this.accessory.displayName} sign: ${sign}`);
|
|
123
|
+
const options = {
|
|
124
|
+
hostname: HostDomain,
|
|
125
|
+
port: 443,
|
|
126
|
+
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: {
|
|
129
|
+
Authorization: this.platform.config.credentials?.token,
|
|
130
|
+
sign: sign,
|
|
131
|
+
nonce: nonce,
|
|
132
|
+
t: t,
|
|
133
|
+
'Content-Type': 'application/json',
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const req = https.request(options, (res) => {
|
|
138
|
+
this.debugLog(`Camera: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
139
|
+
this.statusCode({ res });
|
|
140
|
+
res.on('data', (d) => {
|
|
141
|
+
this.debugLog(`Camera: ${this.accessory.displayName} d: ${d}`);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
req.on('error', (error) => {
|
|
146
|
+
this.errorLog(`Camera: ${this.accessory.displayName} error: ${error}`);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
req.write(payload);
|
|
150
|
+
req.end();
|
|
151
|
+
|
|
152
|
+
this.debugLog(`Camera: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
118
153
|
this.updateHomeKitCharacteristics();
|
|
119
154
|
this.OnCached = this.On;
|
|
120
155
|
this.accessory.context.On = this.OnCached;
|
|
@@ -129,8 +164,8 @@ export class Camera {
|
|
|
129
164
|
}
|
|
130
165
|
}
|
|
131
166
|
|
|
132
|
-
async statusCode(
|
|
133
|
-
switch (
|
|
167
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
168
|
+
switch (res.statusCode) {
|
|
134
169
|
case 151:
|
|
135
170
|
this.errorLog(`Camera: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
136
171
|
break;
|
|
@@ -149,7 +184,7 @@ export class Camera {
|
|
|
149
184
|
case 190:
|
|
150
185
|
this.errorLog(
|
|
151
186
|
`Camera: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
|
|
152
|
-
` with server, Or command: ${JSON.stringify(
|
|
187
|
+
` with server, Or command: ${JSON.stringify(res)} format is invalid`,
|
|
153
188
|
);
|
|
154
189
|
break;
|
|
155
190
|
case 100:
|