homey-api 3.0.22 → 3.0.23
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/HomeyAPI.js +4 -1
- package/lib/HomeyAPI/HomeyAPIV2/ManagerFlow/FlowCardAction.js +5 -4
- package/lib/HomeyAPI/HomeyAPIV2/ManagerFlow/FlowCardCondition.js +5 -4
- package/lib/HomeyAPI/HomeyAPIV2/ManagerFlow/FlowCardTrigger.js +5 -4
- package/lib/HomeyAPI/HomeyAPIV3/Manager.js +2 -2
- package/lib/HomeyAPI/HomeyAPIV3.js +61 -71
- package/lib/Util.js +12 -4
- package/package.json +1 -1
package/lib/HomeyAPI/HomeyAPI.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const Util = require('../Util');
|
|
4
|
+
const EventEmitter = require('../EventEmitter');
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* An authenticated Homey API. Do not construct this class manually.
|
|
7
8
|
* @class
|
|
8
9
|
* @hideconstructor
|
|
9
10
|
*/
|
|
10
|
-
class HomeyAPI {
|
|
11
|
+
class HomeyAPI extends EventEmitter {
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Platforms
|
|
@@ -46,6 +47,8 @@ class HomeyAPI {
|
|
|
46
47
|
properties = {},
|
|
47
48
|
debug = () => { },
|
|
48
49
|
}) {
|
|
50
|
+
super();
|
|
51
|
+
|
|
49
52
|
// Set Debug Enabled
|
|
50
53
|
Object.defineProperty(this, '__debugFunction', {
|
|
51
54
|
value: debug,
|
|
@@ -9,10 +9,11 @@ class FlowCardAction extends FlowCardActionV3 {
|
|
|
9
9
|
|
|
10
10
|
item.id = `${item.uri}:${item.id}`;
|
|
11
11
|
item.ownerUri = item.uri;
|
|
12
|
-
|
|
13
|
-
item.
|
|
14
|
-
item.
|
|
15
|
-
item.
|
|
12
|
+
// I dont know how uriObj can be null but it is possible.
|
|
13
|
+
item.ownerId = item.uriObj != null ? item.uriObj.id : null;
|
|
14
|
+
item.ownerName = item.uriObj != null ? item.uriObj.name : null;
|
|
15
|
+
item.color = item.uriObj != null ? item.uriObj.color : null;
|
|
16
|
+
item.iconObj = item.uriObj != null ? item.uriObj.iconObj : null;
|
|
16
17
|
|
|
17
18
|
delete item.uri;
|
|
18
19
|
delete item.uriObj;
|
|
@@ -9,10 +9,11 @@ class FlowCardCondition extends FlowCardConditionV3 {
|
|
|
9
9
|
|
|
10
10
|
item.id = `${item.uri}:${item.id}`;
|
|
11
11
|
item.ownerUri = item.uri;
|
|
12
|
-
|
|
13
|
-
item.
|
|
14
|
-
item.
|
|
15
|
-
item.
|
|
12
|
+
// I dont know how uriObj can be null but it is possible.
|
|
13
|
+
item.ownerId = item.uriObj != null ? item.uriObj.id : null;
|
|
14
|
+
item.ownerName = item.uriObj != null ? item.uriObj.name : null;
|
|
15
|
+
item.color = item.uriObj != null ? item.uriObj.color : null;
|
|
16
|
+
item.iconObj = item.uriObj != null ? item.uriObj.iconObj : null;
|
|
16
17
|
|
|
17
18
|
delete item.uri;
|
|
18
19
|
delete item.uriObj;
|
|
@@ -9,10 +9,11 @@ class FlowCardTrigger extends FlowCardTriggerV3 {
|
|
|
9
9
|
|
|
10
10
|
item.id = `${item.uri}:${item.id}`;
|
|
11
11
|
item.ownerUri = item.uri;
|
|
12
|
-
|
|
13
|
-
item.
|
|
14
|
-
item.
|
|
15
|
-
item.
|
|
12
|
+
// I dont know how uriObj can be null but it is possible.
|
|
13
|
+
item.ownerId = item.uriObj != null ? item.uriObj.id : null;
|
|
14
|
+
item.ownerName = item.uriObj != null ? item.uriObj.name : null;
|
|
15
|
+
item.color = item.uriObj != null ? item.uriObj.color : null;
|
|
16
|
+
item.iconObj = item.uriObj != null ? item.uriObj.iconObj : null;
|
|
16
17
|
|
|
17
18
|
delete item.uri;
|
|
18
19
|
delete item.uriObj;
|
|
@@ -275,7 +275,7 @@ class Manager extends EventEmitter {
|
|
|
275
275
|
if (this.homey.isConnected() && $socket === true) {
|
|
276
276
|
result = await Util.timeout(new Promise((resolve, reject) => {
|
|
277
277
|
this.__debug(`IO ${operationId}`);
|
|
278
|
-
this.homey.
|
|
278
|
+
this.homey.__homeySocket.emit('api', {
|
|
279
279
|
args,
|
|
280
280
|
operation: operationId,
|
|
281
281
|
uri: this.uri,
|
|
@@ -561,7 +561,7 @@ class Manager extends EventEmitter {
|
|
|
561
561
|
}
|
|
562
562
|
|
|
563
563
|
/**
|
|
564
|
-
*
|
|
564
|
+
* Disconnect from this manager's Socket.io namespace.
|
|
565
565
|
* @returns {Promise<void>}
|
|
566
566
|
*/
|
|
567
567
|
async disconnect() {
|
|
@@ -102,12 +102,6 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
102
102
|
writable: true,
|
|
103
103
|
});
|
|
104
104
|
|
|
105
|
-
Object.defineProperty(this, '__connected', {
|
|
106
|
-
value: false,
|
|
107
|
-
enumerable: false,
|
|
108
|
-
writable: true,
|
|
109
|
-
});
|
|
110
|
-
|
|
111
105
|
this.generateManagersFromSpecification();
|
|
112
106
|
}
|
|
113
107
|
|
|
@@ -559,7 +553,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
559
553
|
* @returns {Boolean}
|
|
560
554
|
*/
|
|
561
555
|
isConnected() {
|
|
562
|
-
return this.
|
|
556
|
+
return this.__homeySocket && this.__homeySocket.connected;
|
|
563
557
|
}
|
|
564
558
|
|
|
565
559
|
async subscribe(uri, {
|
|
@@ -573,11 +567,11 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
573
567
|
|
|
574
568
|
await this.connect();
|
|
575
569
|
await new Promise((resolve, reject) => {
|
|
576
|
-
this.
|
|
570
|
+
this.__homeySocket.once('disconnect', (reason) => {
|
|
577
571
|
reject(new Error(reason));
|
|
578
572
|
});
|
|
579
573
|
this.__debug('subscribing', uri);
|
|
580
|
-
this.
|
|
574
|
+
this.__homeySocket.emit('subscribe', uri, err => {
|
|
581
575
|
if (err) {
|
|
582
576
|
this.__debug('Failed to subscribe', uri, err);
|
|
583
577
|
return reject(err)
|
|
@@ -592,7 +586,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
592
586
|
const __onEvent = (event, data) => {
|
|
593
587
|
onEvent(event, data);
|
|
594
588
|
};
|
|
595
|
-
this.
|
|
589
|
+
this.__homeySocket.on(uri, __onEvent);
|
|
596
590
|
|
|
597
591
|
onConnect();
|
|
598
592
|
|
|
@@ -600,14 +594,14 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
600
594
|
const __onDisconnect = reason => {
|
|
601
595
|
onDisconnect(reason);
|
|
602
596
|
};
|
|
603
|
-
this.
|
|
597
|
+
this.__socket.on('disconnect', __onDisconnect);
|
|
604
598
|
|
|
605
599
|
// On Reconnect
|
|
606
600
|
const __onReconnect = () => {
|
|
607
601
|
Promise.resolve().then(async () => {
|
|
608
602
|
await this.connect();
|
|
609
603
|
await new Promise((resolve, reject) => {
|
|
610
|
-
this.
|
|
604
|
+
this.__homeySocket.emit('subscribe', uri, err => {
|
|
611
605
|
if (err) {
|
|
612
606
|
this.__debug('Failed to subscribe', uri, err);
|
|
613
607
|
return reject(err)
|
|
@@ -617,26 +611,26 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
617
611
|
});
|
|
618
612
|
});
|
|
619
613
|
|
|
620
|
-
this.
|
|
614
|
+
this.__homeySocket.on(uri, __onEvent);
|
|
621
615
|
|
|
622
616
|
onReconnect();
|
|
623
617
|
}).catch(err => onReconnectError(err));
|
|
624
618
|
};
|
|
625
|
-
this.
|
|
619
|
+
this.__socket.on('reconnect', __onReconnect);
|
|
626
620
|
|
|
627
621
|
return {
|
|
628
622
|
unsubscribe: () => {
|
|
629
|
-
this.
|
|
630
|
-
this.
|
|
631
|
-
this.
|
|
632
|
-
this.
|
|
623
|
+
this.__homeySocket.emit('unsubscribe', uri);
|
|
624
|
+
this.__homeySocket.removeListener(uri, __onEvent);
|
|
625
|
+
this.__socket.removeListener('disconnect', __onDisconnect);
|
|
626
|
+
this.__socket.removeListener('reconnect', __onReconnect);
|
|
633
627
|
},
|
|
634
628
|
};
|
|
635
629
|
}
|
|
636
630
|
|
|
637
631
|
async connect() {
|
|
638
|
-
if (!this.
|
|
639
|
-
this.
|
|
632
|
+
if (!this.__connectPromise) {
|
|
633
|
+
this.__connectPromise = Promise.resolve().then(async () => {
|
|
640
634
|
// Ensure Base URL
|
|
641
635
|
const baseUrl = await this.baseUrl;
|
|
642
636
|
|
|
@@ -645,8 +639,9 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
645
639
|
|
|
646
640
|
return new Promise((resolve, reject) => {
|
|
647
641
|
this.__debug(`SocketIOClient ${baseUrl}`);
|
|
648
|
-
|
|
649
|
-
|
|
642
|
+
|
|
643
|
+
this.__socket = SocketIOClient(baseUrl, {
|
|
644
|
+
autoConnect: false,
|
|
650
645
|
transports: ['websocket'],
|
|
651
646
|
transportOptions: {
|
|
652
647
|
pingTimeout: 8000,
|
|
@@ -655,34 +650,36 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
655
650
|
reconnection: true,
|
|
656
651
|
});
|
|
657
652
|
|
|
658
|
-
this.
|
|
653
|
+
this.__socket.on('disconnect', reason => {
|
|
659
654
|
this.__debug('SocketIOClient.onDisconnect', reason);
|
|
660
|
-
this.
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
655
|
+
// this.emit('state', {
|
|
656
|
+
// socketConnected: this.__socket.connected,
|
|
657
|
+
// homeySocketConnected: this.__homeySocket && this.__homeySocket.connected
|
|
658
|
+
// });
|
|
659
|
+
|
|
660
|
+
if (this.__homeySocket) {
|
|
661
|
+
this.__homeySocket.disconnect();
|
|
662
|
+
this.__homeySocket.destroy();
|
|
663
|
+
this.__homeySocket.removeAllListeners();
|
|
666
664
|
}
|
|
667
665
|
|
|
668
666
|
if (reason === 'io server disconnect') {
|
|
669
667
|
// The disconnect was initiated by the server.
|
|
670
|
-
this.
|
|
668
|
+
// this.__socket.open();
|
|
671
669
|
}
|
|
672
670
|
|
|
673
671
|
reject(new Error('Disconnected'));
|
|
674
672
|
});
|
|
675
673
|
|
|
676
|
-
this.
|
|
674
|
+
this.__socket.on('error', err => {
|
|
677
675
|
this.__debug('SocketIOClient.onError', err.message);
|
|
678
676
|
});
|
|
679
677
|
|
|
680
|
-
this.
|
|
678
|
+
this.__socket.on('reconnect', () => {
|
|
681
679
|
this.__debug('SocketIOClient.onReconnect');
|
|
682
680
|
this.__handshakeClient()
|
|
683
681
|
.then(() => {
|
|
684
682
|
this.__debug('SocketIOClient.onReconnect.onHandshakeClientSuccess');
|
|
685
|
-
this.__connected = true;
|
|
686
683
|
resolve();
|
|
687
684
|
})
|
|
688
685
|
.catch(err => {
|
|
@@ -691,29 +688,29 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
691
688
|
});
|
|
692
689
|
});
|
|
693
690
|
|
|
694
|
-
this.
|
|
691
|
+
this.__socket.on('reconnect_attempt', () => {
|
|
695
692
|
this.__debug(`SocketIOClient.onReconnectAttempt`);
|
|
696
693
|
});
|
|
697
694
|
|
|
698
|
-
this.
|
|
695
|
+
this.__socket.on('reconnecting', attempt => {
|
|
699
696
|
this.__debug(`SocketIOClient.onReconnecting (Attempt #${attempt})`);
|
|
700
697
|
});
|
|
701
698
|
|
|
702
|
-
this.
|
|
699
|
+
this.__socket.on('reconnect_error', err => {
|
|
703
700
|
this.__debug('SocketIOClient.onReconnectError', err.message);
|
|
704
701
|
});
|
|
705
702
|
|
|
706
|
-
this.
|
|
703
|
+
this.__socket.on('connect_error', err => {
|
|
707
704
|
this.__debug('SocketIOClient.onConnectError', err.message);
|
|
708
705
|
reject(err);
|
|
709
706
|
});
|
|
710
707
|
|
|
711
|
-
this.
|
|
708
|
+
this.__socket.on('connect', () => {
|
|
709
|
+
// this.emit('state', { connected: this.__homeySocket?.connected });
|
|
712
710
|
this.__debug('SocketIOClient.onConnect');
|
|
713
711
|
this.__handshakeClient()
|
|
714
712
|
.then(() => {
|
|
715
713
|
this.__debug('SocketIOClient.onConnect.onHandshakeClientSuccess');
|
|
716
|
-
this.__connected = true;
|
|
717
714
|
resolve();
|
|
718
715
|
})
|
|
719
716
|
.catch(err => {
|
|
@@ -721,34 +718,35 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
721
718
|
reject(err);
|
|
722
719
|
});
|
|
723
720
|
});
|
|
724
|
-
|
|
721
|
+
|
|
722
|
+
this.__socket.open();
|
|
725
723
|
});
|
|
726
724
|
});
|
|
727
725
|
|
|
728
|
-
this.
|
|
726
|
+
this.__connectPromise.catch(err => {
|
|
729
727
|
this.__debug('SocketIOClient Error', err.message);
|
|
730
728
|
});
|
|
731
729
|
}
|
|
732
730
|
|
|
733
|
-
return this.
|
|
731
|
+
return this.__connectPromise;
|
|
734
732
|
}
|
|
735
733
|
|
|
736
734
|
async disconnect() {
|
|
737
|
-
if (this.
|
|
735
|
+
if (this.__socket) {
|
|
738
736
|
await new Promise(resolve => {
|
|
739
|
-
this.
|
|
740
|
-
this.
|
|
741
|
-
this.
|
|
742
|
-
this.
|
|
737
|
+
this.__socket.once('disconnect', resolve());
|
|
738
|
+
this.__socket.disconnect();
|
|
739
|
+
this.__socket.removeAllListeners();
|
|
740
|
+
this.__socket = null;
|
|
743
741
|
});
|
|
744
742
|
}
|
|
745
743
|
// TODO todo what?
|
|
746
744
|
}
|
|
747
745
|
|
|
748
746
|
destroy() {
|
|
749
|
-
if (this.
|
|
750
|
-
this.
|
|
751
|
-
this.
|
|
747
|
+
if (this.__socket) {
|
|
748
|
+
this.__socket.removeAllListeners();
|
|
749
|
+
this.__socket.close();
|
|
752
750
|
}
|
|
753
751
|
}
|
|
754
752
|
|
|
@@ -756,7 +754,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
756
754
|
this.__debug('__handshakeClient');
|
|
757
755
|
|
|
758
756
|
return new Promise((resolve, reject) => {
|
|
759
|
-
this.
|
|
757
|
+
this.__socket.emit('handshakeClient', {
|
|
760
758
|
token: this.__token,
|
|
761
759
|
homeyId: this.id,
|
|
762
760
|
}, (err, result) => {
|
|
@@ -772,7 +770,7 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
772
770
|
await this.login();
|
|
773
771
|
|
|
774
772
|
return new Promise((resolve, reject) => {
|
|
775
|
-
this.
|
|
773
|
+
this.__socket.emit('handshakeClient', {
|
|
776
774
|
token: this.__token,
|
|
777
775
|
homeyId: this.id,
|
|
778
776
|
}, (err, result) => {
|
|
@@ -788,43 +786,35 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
788
786
|
this.__debug('SocketIOClient.onHandshakeClientSuccess', `Namespace: ${namespace}`);
|
|
789
787
|
|
|
790
788
|
return new Promise((resolve, reject) => {
|
|
791
|
-
this.
|
|
792
|
-
|
|
793
|
-
this.__debug(this.__ioNamespace);
|
|
789
|
+
this.__homeySocket = this.__socket.io.socket(namespace);
|
|
794
790
|
|
|
795
|
-
|
|
796
|
-
if (this.__ioNamespace.connected) {
|
|
797
|
-
this.__debug(`SocketIOClient.Namespace[${namespace}].connected`);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
this.__ioNamespace.once('connect', () => {
|
|
791
|
+
this.__homeySocket.once('connect', () => {
|
|
801
792
|
this.__debug(`SocketIOClient.Namespace[${namespace}].onConnect`);
|
|
802
793
|
resolve();
|
|
803
794
|
});
|
|
804
795
|
|
|
805
|
-
this.
|
|
796
|
+
this.__homeySocket.once('connect_error', err => {
|
|
806
797
|
this.__debug(`SocketIOClient.Namespace[${namespace}].onConnectError`, err.message);
|
|
807
798
|
reject(err);
|
|
808
799
|
});
|
|
809
800
|
|
|
810
|
-
this.
|
|
801
|
+
this.__homeySocket.on('disconnect', reason => {
|
|
802
|
+
this.__debug(`SocketIOClient.Namespace[${namespace}].onDisconnect`, reason);
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
this.__homeySocket.on('reconnecting', attempt => {
|
|
811
806
|
this.__debug(`SocketIOClient.Namespace[${namespace}].onReconnecting (Attempt #${attempt})`);
|
|
812
807
|
});
|
|
813
808
|
|
|
814
|
-
this.
|
|
809
|
+
this.__homeySocket.on('reconnect', () => {
|
|
815
810
|
this.__debug(`SocketIOClient.Namespace[${namespace}].onReconnect`);
|
|
816
811
|
});
|
|
817
812
|
|
|
818
|
-
this.
|
|
813
|
+
this.__homeySocket.on('reconnect_error', err => {
|
|
819
814
|
this.__debug(`SocketIOClient.Namespace[${namespace}].onReconnectError`, err.message);
|
|
820
815
|
});
|
|
821
816
|
|
|
822
|
-
this.
|
|
823
|
-
this.__debug(`SocketIOClient.Namespace[${namespace}].onDisconnect`, reason);
|
|
824
|
-
});
|
|
825
|
-
|
|
826
|
-
this.__debug(`SocketIOClient.Namespace[${namespace}].disconnected`, this.__ioNamespace.disconnected);
|
|
827
|
-
this.__debug(`SocketIOClient.Namespace[${namespace}].connected`, this.__ioNamespace.connected);
|
|
817
|
+
this.__homeySocket.open();
|
|
828
818
|
});
|
|
829
819
|
});
|
|
830
820
|
}
|
package/lib/Util.js
CHANGED
|
@@ -56,16 +56,24 @@ class Util {
|
|
|
56
56
|
static async timeout(promise, timeoutMillis = 5000, message = `Timeout after ${timeoutMillis}ms`) {
|
|
57
57
|
const timeoutError = new APIErrorTimeout(message);
|
|
58
58
|
let timeoutRef;
|
|
59
|
-
|
|
59
|
+
|
|
60
|
+
const returnPromise = Promise.race([
|
|
60
61
|
promise,
|
|
61
62
|
new Promise((_, reject) => {
|
|
62
63
|
timeoutRef = setTimeout(() => {
|
|
63
64
|
reject(timeoutError);
|
|
64
65
|
}, timeoutMillis);
|
|
65
66
|
}),
|
|
66
|
-
])
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
returnPromise
|
|
70
|
+
// eslint-disable-next-line no-unused-vars
|
|
71
|
+
.catch(err => { })
|
|
72
|
+
.finally(() => {
|
|
73
|
+
clearTimeout(timeoutRef);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return returnPromise;
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
/**
|