homey-api 3.4.17 → 3.4.18
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/lib/HomeyAPI/HomeyAPIV3.js +148 -119
- package/package.json +1 -1
|
@@ -26,7 +26,6 @@ const versionCache = {};
|
|
|
26
26
|
* @extends HomeyAPI
|
|
27
27
|
*/
|
|
28
28
|
class HomeyAPIV3 extends HomeyAPI {
|
|
29
|
-
|
|
30
29
|
static MANAGERS = {
|
|
31
30
|
ManagerApps,
|
|
32
31
|
ManagerDrivers,
|
|
@@ -91,9 +90,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
91
90
|
});
|
|
92
91
|
|
|
93
92
|
Object.defineProperty(this, '__strategies', {
|
|
94
|
-
value: Array.isArray(strategy)
|
|
95
|
-
? strategy
|
|
96
|
-
: [strategy],
|
|
93
|
+
value: Array.isArray(strategy) ? strategy : [strategy],
|
|
97
94
|
enumerable: false,
|
|
98
95
|
writable: false,
|
|
99
96
|
});
|
|
@@ -105,9 +102,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
105
102
|
});
|
|
106
103
|
|
|
107
104
|
Object.defineProperty(this, '__baseUrlPromise', {
|
|
108
|
-
value: typeof baseUrl === 'string'
|
|
109
|
-
? Promise.resolve(baseUrl)
|
|
110
|
-
: null,
|
|
105
|
+
value: typeof baseUrl === 'string' ? Promise.resolve(baseUrl) : null,
|
|
111
106
|
enumerable: false,
|
|
112
107
|
writable: true,
|
|
113
108
|
});
|
|
@@ -130,7 +125,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
130
125
|
this.__baseUrlPromise = this.discoverBaseUrl().then(({ baseUrl }) => {
|
|
131
126
|
return baseUrl;
|
|
132
127
|
});
|
|
133
|
-
this.__baseUrlPromise.catch(() => {
|
|
128
|
+
this.__baseUrlPromise.catch(() => {});
|
|
134
129
|
}
|
|
135
130
|
|
|
136
131
|
return this.__baseUrlPromise;
|
|
@@ -173,8 +168,8 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
173
168
|
const ManagerClass = this.constructor.MANAGERS[managerName]
|
|
174
169
|
? this.constructor.MANAGERS[managerName]
|
|
175
170
|
: (() => {
|
|
176
|
-
|
|
177
|
-
|
|
171
|
+
return class extends Manager {};
|
|
172
|
+
})();
|
|
178
173
|
|
|
179
174
|
ManagerClass.ID = manager.id;
|
|
180
175
|
|
|
@@ -260,7 +255,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
260
255
|
this.__baseUrl = baseUrl;
|
|
261
256
|
this.__strategyId = strategyId;
|
|
262
257
|
})
|
|
263
|
-
.catch(() => {
|
|
258
|
+
.catch(() => {});
|
|
264
259
|
|
|
265
260
|
// Ping method
|
|
266
261
|
const ping = async (strategyId, timeout) => {
|
|
@@ -305,7 +300,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
305
300
|
if (urls[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE]) {
|
|
306
301
|
pings[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE] = ping(HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE, 5000);
|
|
307
302
|
pings[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE].catch(err => {
|
|
308
|
-
this.__debug(`Ping ${HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE} Error:`, err && err.message)
|
|
303
|
+
this.__debug(`Ping ${HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE} Error:`, err && err.message);
|
|
309
304
|
this.__debug(urls[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE]);
|
|
310
305
|
});
|
|
311
306
|
}
|
|
@@ -313,25 +308,36 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
313
308
|
// Ping local (http://xxx-xxx-xxx-xxx)
|
|
314
309
|
if (urls[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL]) {
|
|
315
310
|
pings[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL] = ping(HomeyAPI.DISCOVERY_STRATEGIES.LOCAL, 1000);
|
|
316
|
-
pings[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL].catch(err =>
|
|
311
|
+
pings[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL].catch(err =>
|
|
312
|
+
this.__debug(`Ping ${HomeyAPI.DISCOVERY_STRATEGIES.LOCAL} Error:`, err && err.message)
|
|
313
|
+
);
|
|
317
314
|
}
|
|
318
315
|
|
|
319
316
|
// Ping mdns (http://homey-<homeyId>.local)
|
|
320
317
|
if (urls[HomeyAPI.DISCOVERY_STRATEGIES.MDNS]) {
|
|
321
318
|
pings[HomeyAPI.DISCOVERY_STRATEGIES.MDNS] = ping(HomeyAPI.DISCOVERY_STRATEGIES.MDNS, 3000);
|
|
322
|
-
pings[HomeyAPI.DISCOVERY_STRATEGIES.MDNS].catch(err =>
|
|
319
|
+
pings[HomeyAPI.DISCOVERY_STRATEGIES.MDNS].catch(err =>
|
|
320
|
+
this.__debug(`Ping ${HomeyAPI.DISCOVERY_STRATEGIES.MDNS} Error:`, err && err.message)
|
|
321
|
+
);
|
|
323
322
|
}
|
|
324
323
|
|
|
325
324
|
// Ping cloud (https://<homeyId>.connect.athom.com)
|
|
326
325
|
if (urls[HomeyAPI.DISCOVERY_STRATEGIES.CLOUD]) {
|
|
327
326
|
pings[HomeyAPI.DISCOVERY_STRATEGIES.CLOUD] = ping(HomeyAPI.DISCOVERY_STRATEGIES.CLOUD, 5000);
|
|
328
|
-
pings[HomeyAPI.DISCOVERY_STRATEGIES.CLOUD].catch(err =>
|
|
327
|
+
pings[HomeyAPI.DISCOVERY_STRATEGIES.CLOUD].catch(err =>
|
|
328
|
+
this.__debug(`Ping ${HomeyAPI.DISCOVERY_STRATEGIES.CLOUD} Error:`, err && err.message)
|
|
329
|
+
);
|
|
329
330
|
}
|
|
330
331
|
|
|
331
332
|
// Ping Direct (https://xxx-xxx-xxx-xx.homey.homeylocal.com:12345)
|
|
332
333
|
if (urls[HomeyAPI.DISCOVERY_STRATEGIES.REMOTE_FORWARDED]) {
|
|
333
|
-
pings[HomeyAPI.DISCOVERY_STRATEGIES.REMOTE_FORWARDED] = ping(
|
|
334
|
-
|
|
334
|
+
pings[HomeyAPI.DISCOVERY_STRATEGIES.REMOTE_FORWARDED] = ping(
|
|
335
|
+
HomeyAPI.DISCOVERY_STRATEGIES.REMOTE_FORWARDED,
|
|
336
|
+
2000
|
|
337
|
+
);
|
|
338
|
+
pings[HomeyAPI.DISCOVERY_STRATEGIES.REMOTE_FORWARDED].catch(err =>
|
|
339
|
+
this.__debug(`Ping ${HomeyAPI.DISCOVERY_STRATEGIES.REMOTE_FORWARDED} Error:`, err && err.message)
|
|
340
|
+
);
|
|
335
341
|
}
|
|
336
342
|
|
|
337
343
|
// Select the best route
|
|
@@ -406,15 +412,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
406
412
|
return promise;
|
|
407
413
|
}
|
|
408
414
|
|
|
409
|
-
async call({
|
|
410
|
-
$timeout = 10000,
|
|
411
|
-
method,
|
|
412
|
-
headers,
|
|
413
|
-
path,
|
|
414
|
-
body,
|
|
415
|
-
json = true,
|
|
416
|
-
retryAfterRefresh = false,
|
|
417
|
-
}) {
|
|
415
|
+
async call({ $timeout = 10000, method, headers, path, body, json = true, retryAfterRefresh = false }) {
|
|
418
416
|
const baseUrl = await this.baseUrl;
|
|
419
417
|
|
|
420
418
|
method = String(method).toUpperCase();
|
|
@@ -439,11 +437,14 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
439
437
|
}
|
|
440
438
|
|
|
441
439
|
this.__debug(method, `${baseUrl}${path}`);
|
|
442
|
-
const res = await Util.timeout(
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
440
|
+
const res = await Util.timeout(
|
|
441
|
+
Util.fetch(`${baseUrl}${path}`, {
|
|
442
|
+
method,
|
|
443
|
+
headers,
|
|
444
|
+
body,
|
|
445
|
+
}),
|
|
446
|
+
$timeout
|
|
447
|
+
);
|
|
447
448
|
|
|
448
449
|
const resStatusCode = res.status;
|
|
449
450
|
if (resStatusCode === 204) return undefined;
|
|
@@ -464,10 +465,8 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
464
465
|
if (resHeadersContentType && resHeadersContentType.startsWith('application/json')) {
|
|
465
466
|
try {
|
|
466
467
|
resBodyJson = JSON.parse(resBodyText);
|
|
467
|
-
|
|
468
|
-
} catch (err) {
|
|
469
|
-
|
|
470
|
-
}
|
|
468
|
+
// eslint-disable-next-line no-empty
|
|
469
|
+
} catch (err) {}
|
|
471
470
|
}
|
|
472
471
|
|
|
473
472
|
if (!res.ok) {
|
|
@@ -491,22 +490,31 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
491
490
|
});
|
|
492
491
|
}
|
|
493
492
|
|
|
494
|
-
throw new HomeyAPIError(
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
493
|
+
throw new HomeyAPIError(
|
|
494
|
+
{
|
|
495
|
+
error: resBodyJson.error,
|
|
496
|
+
error_description: resBodyJson.error_description,
|
|
497
|
+
stack: resBodyJson.stack,
|
|
498
|
+
},
|
|
499
|
+
resStatusCode
|
|
500
|
+
);
|
|
499
501
|
}
|
|
500
502
|
|
|
501
503
|
if (resBodyText) {
|
|
502
|
-
throw new HomeyAPIError(
|
|
503
|
-
|
|
504
|
-
|
|
504
|
+
throw new HomeyAPIError(
|
|
505
|
+
{
|
|
506
|
+
error: resBodyText,
|
|
507
|
+
},
|
|
508
|
+
resStatusCode
|
|
509
|
+
);
|
|
505
510
|
}
|
|
506
511
|
|
|
507
|
-
throw new HomeyAPIError(
|
|
508
|
-
|
|
509
|
-
|
|
512
|
+
throw new HomeyAPIError(
|
|
513
|
+
{
|
|
514
|
+
error: resStatusText,
|
|
515
|
+
},
|
|
516
|
+
resStatusCode
|
|
517
|
+
);
|
|
510
518
|
}
|
|
511
519
|
|
|
512
520
|
if (typeof resBodyJson !== 'undefined') {
|
|
@@ -556,7 +564,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
556
564
|
});
|
|
557
565
|
|
|
558
566
|
this.__loginPromise
|
|
559
|
-
.then(() => {
|
|
567
|
+
.then(() => {})
|
|
560
568
|
.catch(err => {
|
|
561
569
|
this.__debug('Error Logging In:', err);
|
|
562
570
|
this.__token = null;
|
|
@@ -586,36 +594,43 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
586
594
|
return this.__homeySocket && this.__homeySocket.connected;
|
|
587
595
|
}
|
|
588
596
|
|
|
589
|
-
async subscribe(
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
597
|
+
async subscribe(
|
|
598
|
+
uri,
|
|
599
|
+
{
|
|
600
|
+
onConnect = () => {},
|
|
601
|
+
onReconnect = () => {},
|
|
602
|
+
onReconnectError = () => {},
|
|
603
|
+
onDisconnect = () => {},
|
|
604
|
+
onEvent = () => {},
|
|
605
|
+
}
|
|
606
|
+
) {
|
|
596
607
|
this.__debug('subscribe', uri);
|
|
597
608
|
|
|
598
609
|
await this.connect();
|
|
599
|
-
await Util.timeout(
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
this.__homeySocket.once('disconnect', (reason) => {
|
|
606
|
-
reject(new Error(reason));
|
|
607
|
-
});
|
|
608
|
-
this.__debug('subscribing', uri);
|
|
609
|
-
this.__homeySocket.emit('subscribe', uri, err => {
|
|
610
|
-
if (err) {
|
|
611
|
-
this.__debug('Failed to subscribe', uri, err);
|
|
612
|
-
return reject(err)
|
|
610
|
+
await Util.timeout(
|
|
611
|
+
new Promise((resolve, reject) => {
|
|
612
|
+
if (this.isConnected() !== true) {
|
|
613
|
+
reject(new Error('Not connected after connect.'));
|
|
614
|
+
return;
|
|
613
615
|
}
|
|
614
|
-
|
|
615
|
-
this.
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
616
|
+
|
|
617
|
+
this.__homeySocket.once('disconnect', reason => {
|
|
618
|
+
reject(new Error(reason));
|
|
619
|
+
});
|
|
620
|
+
this.__debug('subscribing', uri);
|
|
621
|
+
this.__homeySocket.emit('subscribe', uri, err => {
|
|
622
|
+
if (err) {
|
|
623
|
+
this.__debug('Failed to subscribe', uri, err);
|
|
624
|
+
return reject(err);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
this.__debug('subscribed', uri);
|
|
628
|
+
return resolve();
|
|
629
|
+
});
|
|
630
|
+
}),
|
|
631
|
+
10000,
|
|
632
|
+
`Failed to subscribe to ${uri} (Timeout after 10000ms).`
|
|
633
|
+
);
|
|
619
634
|
|
|
620
635
|
// On Connect
|
|
621
636
|
const __onEvent = (event, data) => {
|
|
@@ -633,33 +648,39 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
633
648
|
|
|
634
649
|
// On Reconnect
|
|
635
650
|
const __onReconnect = () => {
|
|
636
|
-
Promise.resolve()
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
this.
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
651
|
+
Promise.resolve()
|
|
652
|
+
.then(async () => {
|
|
653
|
+
await this.connect();
|
|
654
|
+
await Util.timeout(
|
|
655
|
+
new Promise((resolve, reject) => {
|
|
656
|
+
if (this.isConnected() !== true) {
|
|
657
|
+
reject(new Error('Not connected after connect. (Reconnect)'));
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
this.__homeySocket.once('disconnect', reason => {
|
|
662
|
+
reject(new Error(reason));
|
|
663
|
+
});
|
|
664
|
+
this.__debug('subscribing', uri);
|
|
665
|
+
this.__homeySocket.emit('subscribe', uri, err => {
|
|
666
|
+
if (err) {
|
|
667
|
+
this.__debug('Failed to subscribe', uri, err);
|
|
668
|
+
return reject(err);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
this.__debug('subscribed', uri);
|
|
672
|
+
return resolve();
|
|
673
|
+
});
|
|
674
|
+
}),
|
|
675
|
+
10000,
|
|
676
|
+
`Failed to subscribe to ${uri} (Timeout after 10000ms).`
|
|
677
|
+
);
|
|
658
678
|
|
|
659
|
-
|
|
679
|
+
this.__homeySocket.on(uri, __onEvent);
|
|
660
680
|
|
|
661
|
-
|
|
662
|
-
|
|
681
|
+
onReconnect();
|
|
682
|
+
})
|
|
683
|
+
.catch(err => onReconnectError(err));
|
|
663
684
|
};
|
|
664
685
|
this.__socket.on('reconnect', __onReconnect);
|
|
665
686
|
|
|
@@ -714,7 +735,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
714
735
|
this.__debug('SocketIOClient.onReconnect');
|
|
715
736
|
this.emit('reconnect');
|
|
716
737
|
});
|
|
717
|
-
|
|
738
|
+
|
|
718
739
|
this.__socket.on('reconnect_attempt', () => {
|
|
719
740
|
this.__debug(`SocketIOClient.onReconnectAttempt`);
|
|
720
741
|
this.emit('reconnect_attempt');
|
|
@@ -780,7 +801,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
780
801
|
this.__socket = null;
|
|
781
802
|
});
|
|
782
803
|
}
|
|
783
|
-
|
|
804
|
+
|
|
784
805
|
// TODO todo what?
|
|
785
806
|
}
|
|
786
807
|
|
|
@@ -843,30 +864,35 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
843
864
|
|
|
844
865
|
this.__homeySocket.open();
|
|
845
866
|
});
|
|
846
|
-
}
|
|
867
|
+
};
|
|
847
868
|
|
|
848
869
|
const handshakeClient = async () => {
|
|
849
870
|
return new Promise((resolve, reject) => {
|
|
850
|
-
this.__socket.emit(
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
871
|
+
this.__socket.emit(
|
|
872
|
+
'handshakeClient',
|
|
873
|
+
{
|
|
874
|
+
token: this.__token,
|
|
875
|
+
homeyId: this.id,
|
|
876
|
+
},
|
|
877
|
+
(err, result) => {
|
|
878
|
+
if (err) {
|
|
879
|
+
if (err instanceof Error) {
|
|
880
|
+
return reject(err);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// .statusCode for homey-core .code for homey-client.
|
|
884
|
+
if (typeof err === 'object') {
|
|
885
|
+
return reject(new HomeyAPIError({ error_description: err.message }, err.statusCode || err.code));
|
|
886
|
+
}
|
|
858
887
|
|
|
859
|
-
|
|
860
|
-
return reject(new Error(err.message));
|
|
888
|
+
return reject(new Error(String(err)));
|
|
861
889
|
}
|
|
862
890
|
|
|
863
|
-
return
|
|
891
|
+
return resolve(result);
|
|
864
892
|
}
|
|
865
|
-
|
|
866
|
-
return resolve(result);
|
|
867
|
-
});
|
|
893
|
+
);
|
|
868
894
|
});
|
|
869
|
-
}
|
|
895
|
+
};
|
|
870
896
|
|
|
871
897
|
try {
|
|
872
898
|
const result = await Util.timeout(handshakeClient(), 5000, `Failed to handshake client (Timeout after 5000ms).`);
|
|
@@ -878,7 +904,11 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
878
904
|
await this.logout();
|
|
879
905
|
await this.login();
|
|
880
906
|
|
|
881
|
-
const result = await Util.timeout(
|
|
907
|
+
const result = await Util.timeout(
|
|
908
|
+
handshakeClient(),
|
|
909
|
+
5000,
|
|
910
|
+
`Failed to handshake client (Timeout after 5000ms).`
|
|
911
|
+
);
|
|
882
912
|
|
|
883
913
|
return onResult(result);
|
|
884
914
|
}
|
|
@@ -893,7 +923,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
893
923
|
return true;
|
|
894
924
|
}
|
|
895
925
|
|
|
896
|
-
return this.__session.intersectedScopes.some(
|
|
926
|
+
return this.__session.intersectedScopes.some(availableScope => {
|
|
897
927
|
return this.constructor.instanceOfScope(scope, availableScope);
|
|
898
928
|
});
|
|
899
929
|
}
|
|
@@ -910,7 +940,6 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
910
940
|
|
|
911
941
|
return scopeOne.indexOf(partsTwo[0]) === 0 && suffixIsEqual;
|
|
912
942
|
}
|
|
913
|
-
|
|
914
943
|
}
|
|
915
944
|
|
|
916
945
|
module.exports = HomeyAPIV3;
|