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.
@@ -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
- item.ownerId = item.uriObj.id;
13
- item.ownerName = item.uriObj.name;
14
- item.color = item.uriObj.color;
15
- item.iconObj = item.uriObj.iconObj;
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
- item.ownerId = item.uriObj.id;
13
- item.ownerName = item.uriObj.name;
14
- item.color = item.uriObj.color;
15
- item.iconObj = item.uriObj.iconObj;
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
- item.ownerId = item.uriObj.id;
13
- item.ownerName = item.uriObj.name;
14
- item.color = item.uriObj.color;
15
- item.iconObj = item.uriObj.iconObj;
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.__ioNamespace.emit('api', {
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
- * Discconnect from this manager's Socket.io namespace.
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.__connected === true;
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.__ioNamespace.once('disconnect', (reason) => {
570
+ this.__homeySocket.once('disconnect', (reason) => {
577
571
  reject(new Error(reason));
578
572
  });
579
573
  this.__debug('subscribing', uri);
580
- this.__ioNamespace.emit('subscribe', uri, err => {
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.__ioNamespace.on(uri, __onEvent);
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.__io.on('disconnect', __onDisconnect);
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.__ioNamespace.emit('subscribe', uri, err => {
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.__ioNamespace.on(uri, __onEvent);
614
+ this.__homeySocket.on(uri, __onEvent);
621
615
 
622
616
  onReconnect();
623
617
  }).catch(err => onReconnectError(err));
624
618
  };
625
- this.__io.on('reconnect', __onReconnect);
619
+ this.__socket.on('reconnect', __onReconnect);
626
620
 
627
621
  return {
628
622
  unsubscribe: () => {
629
- this.__ioNamespace.emit('unsubscribe', uri);
630
- this.__ioNamespace.removeListener(uri, __onEvent);
631
- this.__io.removeListener('disconnect', __onDisconnect);
632
- this.__io.removeListener('reconnect', __onReconnect);
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.io) {
639
- this.io = Promise.resolve().then(async () => {
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
- this.__io = SocketIOClient(baseUrl, {
649
- autoConnect: true,
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.__io.on('disconnect', reason => {
653
+ this.__socket.on('disconnect', reason => {
659
654
  this.__debug('SocketIOClient.onDisconnect', reason);
660
- this.__connected = false;
661
-
662
- if (this.__ioNamespace) {
663
- this.__ioNamespace.disconnect();
664
- this.__ioNamespace.destroy();
665
- this.__ioNamespace.removeAllListeners();
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.__io.connect();
668
+ // this.__socket.open();
671
669
  }
672
670
 
673
671
  reject(new Error('Disconnected'));
674
672
  });
675
673
 
676
- this.__io.on('error', err => {
674
+ this.__socket.on('error', err => {
677
675
  this.__debug('SocketIOClient.onError', err.message);
678
676
  });
679
677
 
680
- this.__io.on('reconnect', () => {
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.__io.on('reconnect_attempt', () => {
691
+ this.__socket.on('reconnect_attempt', () => {
695
692
  this.__debug(`SocketIOClient.onReconnectAttempt`);
696
693
  });
697
694
 
698
- this.__io.on('reconnecting', attempt => {
695
+ this.__socket.on('reconnecting', attempt => {
699
696
  this.__debug(`SocketIOClient.onReconnecting (Attempt #${attempt})`);
700
697
  });
701
698
 
702
- this.__io.on('reconnect_error', err => {
699
+ this.__socket.on('reconnect_error', err => {
703
700
  this.__debug('SocketIOClient.onReconnectError', err.message);
704
701
  });
705
702
 
706
- this.__io.on('connect_error', err => {
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.__io.on('connect', () => {
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
- // this.__io.connect();
721
+
722
+ this.__socket.open();
725
723
  });
726
724
  });
727
725
 
728
- this.io.catch(err => {
726
+ this.__connectPromise.catch(err => {
729
727
  this.__debug('SocketIOClient Error', err.message);
730
728
  });
731
729
  }
732
730
 
733
- return this.io;
731
+ return this.__connectPromise;
734
732
  }
735
733
 
736
734
  async disconnect() {
737
- if (this.__io) {
735
+ if (this.__socket) {
738
736
  await new Promise(resolve => {
739
- this.__io.once('disconnect', resolve());
740
- this.__io.disconnect();
741
- this.__io.removeAllListeners();
742
- this.__io = null;
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.__io) {
750
- this.__io.removeAllListeners();
751
- this.__io.close();
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.__io.emit('handshakeClient', {
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.__io.emit('handshakeClient', {
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.__ioNamespace = this.__io.io.socket(namespace);
792
-
793
- this.__debug(this.__ioNamespace);
789
+ this.__homeySocket = this.__socket.io.socket(namespace);
794
790
 
795
- // Assuming this.__ioNamespace is your namespace object
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.__ioNamespace.once('connect_error', err => {
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.__ioNamespace.on('reconnecting', attempt => {
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.__ioNamespace.on('reconnect', () => {
809
+ this.__homeySocket.on('reconnect', () => {
815
810
  this.__debug(`SocketIOClient.Namespace[${namespace}].onReconnect`);
816
811
  });
817
812
 
818
- this.__ioNamespace.on('reconnect_error', err => {
813
+ this.__homeySocket.on('reconnect_error', err => {
819
814
  this.__debug(`SocketIOClient.Namespace[${namespace}].onReconnectError`, err.message);
820
815
  });
821
816
 
822
- this.__ioNamespace.on('disconnect', reason => {
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
- return Promise.race([
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
- ]).finally(() => {
67
- clearTimeout(timeoutRef);
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homey-api",
3
- "version": "3.0.22",
3
+ "version": "3.0.23",
4
4
  "description": "Homey API",
5
5
  "main": "index.js",
6
6
  "files": [