homey-api 3.4.33 → 3.4.34

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.
@@ -176,6 +176,36 @@
176
176
  }
177
177
  }
178
178
  },
179
+ "searchMatterDriver": {
180
+ "path": "/app/search-matter-driver",
181
+ "method": "post",
182
+ "parameters": {
183
+ "language": {
184
+ "in": "query",
185
+ "type": "string"
186
+ },
187
+ "homeyVersion": {
188
+ "type": "string",
189
+ "in": "body"
190
+ },
191
+ "homeyPlatform": {
192
+ "type": "string",
193
+ "in": "body"
194
+ },
195
+ "homeyMinimumSdkVersion": {
196
+ "type": "number",
197
+ "in": "body"
198
+ },
199
+ "productId": {
200
+ "type": "number",
201
+ "in": "body"
202
+ },
203
+ "vendorId": {
204
+ "type": "number",
205
+ "in": "body"
206
+ }
207
+ }
208
+ },
179
209
  "browseApps": {
180
210
  "path": "/app/browse",
181
211
  "method": "get",
@@ -1623,6 +1623,20 @@ export class AthomAppsAPI {
1623
1623
  manufacturerId?: number;
1624
1624
  }): Promise<any>;
1625
1625
 
1626
+ searchMatterDriver(opts: {
1627
+ language?: string;
1628
+
1629
+ homeyVersion?: string;
1630
+
1631
+ homeyPlatform?: string;
1632
+
1633
+ homeyMinimumSdkVersion?: number;
1634
+
1635
+ productId?: number;
1636
+
1637
+ vendorId?: number;
1638
+ }): Promise<any>;
1639
+
1626
1640
  browseApps(opts: {
1627
1641
  query?: string;
1628
1642
 
@@ -1913,6 +1927,20 @@ export class AthomAppsAPI {
1913
1927
  manufacturerId?: number;
1914
1928
  }): Promise<any>;
1915
1929
 
1930
+ searchMatterDriver(opts: {
1931
+ language?: string;
1932
+
1933
+ homeyVersion?: string;
1934
+
1935
+ homeyPlatform?: string;
1936
+
1937
+ homeyMinimumSdkVersion?: number;
1938
+
1939
+ productId?: number;
1940
+
1941
+ vendorId?: number;
1942
+ }): Promise<any>;
1943
+
1916
1944
  browseApps(opts: {
1917
1945
  query?: string;
1918
1946
 
@@ -4819,6 +4847,20 @@ export class AthomAppsAPI {
4819
4847
  manufacturerId?: number;
4820
4848
  }): Promise<any>;
4821
4849
 
4850
+ searchMatterDriver(opts: {
4851
+ language?: string;
4852
+
4853
+ homeyVersion?: string;
4854
+
4855
+ homeyPlatform?: string;
4856
+
4857
+ homeyMinimumSdkVersion?: number;
4858
+
4859
+ productId?: number;
4860
+
4861
+ vendorId?: number;
4862
+ }): Promise<any>;
4863
+
4822
4864
  browseApps(opts: {
4823
4865
  query?: string;
4824
4866
 
@@ -5109,6 +5151,20 @@ export class AthomAppsAPI {
5109
5151
  manufacturerId?: number;
5110
5152
  }): Promise<any>;
5111
5153
 
5154
+ searchMatterDriver(opts: {
5155
+ language?: string;
5156
+
5157
+ homeyVersion?: string;
5158
+
5159
+ homeyPlatform?: string;
5160
+
5161
+ homeyMinimumSdkVersion?: number;
5162
+
5163
+ productId?: number;
5164
+
5165
+ vendorId?: number;
5166
+ }): Promise<any>;
5167
+
5112
5168
  browseApps(opts: {
5113
5169
  query?: string;
5114
5170
 
package/index.browser.js CHANGED
@@ -1,6 +1,3 @@
1
- /* eslint-disable no-undef */
2
- /* eslint-disable global-require */
3
-
4
1
  'use strict';
5
2
 
6
3
  global.AthomAppsAPI = require('./lib/AthomAppsAPI');
package/index.js CHANGED
@@ -1,5 +1,3 @@
1
- /* eslint-disable global-require */
2
-
3
1
  'use strict';
4
2
 
5
3
  module.exports = {};
package/lib/API.js CHANGED
@@ -172,7 +172,6 @@ class API {
172
172
 
173
173
  __debug(...props) {
174
174
  if (!this.__debugEnabled) return;
175
- // eslint-disable-next-line no-console
176
175
  console.log('[homey-api]', `[${this.constructor.name}]`, ...props);
177
176
  }
178
177
 
@@ -1,5 +1,3 @@
1
- /* eslint-disable camelcase */
2
-
3
1
  'use strict';
4
2
 
5
3
  const APIError = require('./APIError');
@@ -1,5 +1,3 @@
1
- /* eslint-disable camelcase */
2
-
3
1
  'use strict';
4
2
 
5
3
  const APIError = require('./APIError');
@@ -17,7 +17,6 @@ class StorageAdapterBrowser extends StorageAdapter {
17
17
  */
18
18
  async get() {
19
19
  try {
20
- // eslint-disable-next-line no-undef
21
20
  return JSON.parse(window.localStorage.getItem(this.constructor.LOCAL_STORAGE_KEY) || '{}');
22
21
  } catch (err) {
23
22
  return {};
@@ -29,7 +28,6 @@ class StorageAdapterBrowser extends StorageAdapter {
29
28
  * @returns {Promise<void>}
30
29
  */
31
30
  async set(value) {
32
- // eslint-disable-next-line no-undef
33
31
  window.localStorage.setItem(this.constructor.LOCAL_STORAGE_KEY, JSON.stringify(value));
34
32
  }
35
33
 
@@ -1,5 +1,3 @@
1
- /* eslint-disable camelcase */
2
-
3
1
  'use strict';
4
2
 
5
3
  /**
@@ -476,11 +476,9 @@ for(const {@link HomeyAPIV2.ManagerDevices.Device device} of Object.values(devic
476
476
 
477
477
  // Remove ?code=... from URL
478
478
  if (Util.isBrowser() && removeCodeFromHistory) {
479
- // eslint-disable-next-line no-undef
480
479
  const url = new URL(window.location.href);
481
480
  url.searchParams.delete('code');
482
481
 
483
- // eslint-disable-next-line no-undef
484
482
  window.history.pushState(undefined, undefined, url.toString());
485
483
  }
486
484
 
@@ -1,5 +1,3 @@
1
- /* eslint-disable camelcase */
2
-
3
1
  'use strict';
4
2
 
5
3
  const APIError = require('../APIError');
@@ -1,5 +1,3 @@
1
- /* eslint-disable camelcase */
2
-
3
1
  'use strict';
4
2
 
5
3
  const HomeyAPIError = require('./HomeyAPIError');
@@ -11,8 +11,8 @@ const HomeyAPI = require('./HomeyAPI');
11
11
  */
12
12
  class HomeyAPIV1 extends HomeyAPI {
13
13
 
14
- constructor({ properties, ...props }) {
15
- super({ properties, ...props });
14
+ constructor({ properties, api, debug }) {
15
+ super({ properties, api, debug });
16
16
 
17
17
  // TODO: Bearer token
18
18
  const { token } = this.__properties;
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-multi-assign */
2
-
3
1
  'use strict';
4
2
 
5
3
  const HomeyAPIV3Manager = require('../HomeyAPIV3/Manager');
@@ -1,12 +1,8 @@
1
- /* eslint-disable no-multi-assign */
2
-
3
1
  'use strict';
4
2
 
5
3
  const EventEmitter = require('../../EventEmitter');
6
4
  const Util = require('../../Util');
7
5
  const HomeyAPIError = require('../HomeyAPIError');
8
-
9
- // eslint-disable-next-line no-unused-vars
10
6
  const Item = require('./Item');
11
7
 
12
8
  /**
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-unused-vars */
2
-
3
1
  'use strict';
4
2
 
5
3
  const Item = require('../Item');
@@ -56,6 +54,7 @@ class AdvancedFlow extends Item {
56
54
  if (typeof card.args === 'object') {
57
55
  for (const arg of Object.values(card.args)) {
58
56
  if (typeof arg !== 'string') continue;
57
+ // eslint-disable-next-line no-unused-vars
59
58
  for (const [tokenMatch, tokenId] of arg.matchAll(/\[\[(.*?)\]\]/g)) {
60
59
  await checkToken(tokenId);
61
60
  }
@@ -87,6 +86,7 @@ class AdvancedFlow extends Item {
87
86
  case 'condition': {
88
87
  try {
89
88
  await managerFlow.getFlowCardConditions(); // Fill the cache
89
+ // eslint-disable-next-line no-unused-vars
90
90
  const conditionCard = await this.manager.getFlowCardCondition({ id: card.id });
91
91
 
92
92
  // Add Error Token
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-unused-vars */
2
1
 
3
2
  'use strict';
4
3
 
@@ -56,6 +55,7 @@ class Flow extends Item {
56
55
  if (typeof card.args === 'object') {
57
56
  for (const arg of Object.values(card.args)) {
58
57
  if (typeof arg !== 'string') continue;
58
+ // eslint-disable-next-line no-unused-vars
59
59
  for (const [tokenMatch, tokenId] of arg.matchAll(/\[\[(.*?)\]\]/g)) {
60
60
  await checkToken(tokenId);
61
61
  }
@@ -87,6 +87,7 @@ class Flow extends Item {
87
87
  for (const condition of Object.values(this.conditions)) {
88
88
  try {
89
89
  await managerFlow.getFlowCardConditions(); // Fill the cache
90
+ // eslint-disable-next-line no-unused-vars
90
91
  const conditionCard = await this.manager.getFlowCardCondition({ id: condition.id });
91
92
  await checkTokens(condition);
92
93
  } catch (err) {
@@ -101,6 +102,7 @@ class Flow extends Item {
101
102
  for (const action of Object.values(this.actions)) {
102
103
  try {
103
104
  await managerFlow.getFlowCardActions(); // Fill the cache
105
+ // eslint-disable-next-line no-unused-vars
104
106
  const actionCard = await this.manager.getFlowCardAction({ id: action.id });
105
107
  await checkTokens(action);
106
108
  } catch (err) {
@@ -12,8 +12,6 @@ const ManagerFlow = require('./HomeyAPIV3/ManagerFlow');
12
12
  const ManagerFlowToken = require('./HomeyAPIV3/ManagerFlowToken');
13
13
  const ManagerInsights = require('./HomeyAPIV3/ManagerInsights');
14
14
  const ManagerUsers = require('./HomeyAPIV3/ManagerUsers');
15
-
16
- // eslint-disable-next-line no-unused-vars
17
15
  const Manager = require('./HomeyAPIV3/Manager');
18
16
 
19
17
  /**
@@ -50,9 +48,10 @@ class HomeyAPIV3 extends HomeyAPI {
50
48
  token = null,
51
49
  session = null,
52
50
  reconnect = true,
53
- ...props
51
+ api,
52
+ debug,
54
53
  }) {
55
- super({ properties, ...props });
54
+ super({ properties, api, debug });
56
55
 
57
56
  this.__refreshMap = {};
58
57
 
@@ -128,7 +127,7 @@ class HomeyAPIV3 extends HomeyAPI {
128
127
  this.__baseUrlPromise = this.discoverBaseUrl().then(({ baseUrl }) => {
129
128
  return baseUrl;
130
129
  });
131
- this.__baseUrlPromise.catch(() => {});
130
+ this.__baseUrlPromise.catch(() => { });
132
131
  }
133
132
 
134
133
  return this.__baseUrlPromise;
@@ -145,7 +144,6 @@ class HomeyAPIV3 extends HomeyAPI {
145
144
  */
146
145
 
147
146
  getSpecification() {
148
- // eslint-disable-next-line global-require
149
147
  return require('../../assets/specifications/HomeyAPIV2.json');
150
148
  }
151
149
 
@@ -163,8 +161,8 @@ class HomeyAPIV3 extends HomeyAPI {
163
161
  const ManagerClass = this.constructor.MANAGERS[managerName]
164
162
  ? this.constructor.MANAGERS[managerName]
165
163
  : (() => {
166
- return class extends Manager {};
167
- })();
164
+ return class extends Manager { };
165
+ })();
168
166
 
169
167
  ManagerClass.ID = manager.id;
170
168
 
@@ -241,60 +239,68 @@ class HomeyAPIV3 extends HomeyAPI {
241
239
  // Create the returned Promise
242
240
  let resolve;
243
241
  let reject;
242
+
244
243
  const promise = new Promise((resolve_, reject_) => {
245
244
  resolve = resolve_;
246
245
  reject = reject_;
247
246
  });
247
+
248
248
  promise
249
249
  .then(({ baseUrl, strategyId }) => {
250
250
  this.__baseUrl = baseUrl;
251
251
  this.__strategyId = strategyId;
252
252
  })
253
- .catch(() => {});
253
+ .catch(() => { });
254
254
 
255
255
  // Ping method
256
256
  const ping = async (strategyId, timeout) => {
257
- let pingTimeout;
258
257
  const baseUrl = urls[strategyId];
259
- return Promise.race([
260
- Util.fetch(`${baseUrl}/api/manager/system/ping?id=${this.id}`, {
258
+
259
+ const response = await Util.fetch(
260
+ `${baseUrl}/api/manager/system/ping?id=${this.id}`,
261
+ {
261
262
  headers: {
262
263
  'X-Homey-ID': this.id,
263
264
  },
264
- }).then(async res => {
265
- const text = await res.text();
266
- if (!res.ok) throw new Error(text || res.statusText);
267
- if (text === 'false') throw new Error('Invalid Homey ID');
265
+ },
266
+ timeout
267
+ );
268
268
 
269
- const homeyId = res.headers.get('X-Homey-ID');
269
+ const text = await response.text();
270
270
 
271
- if (homeyId) {
272
- if (homeyId !== this.id) throw new Error('Invalid Homey ID'); // TODO: Add to Homey Connect
273
- }
271
+ if (!response.ok) {
272
+ throw new Error(text || response.statusText)
273
+ }
274
274
 
275
- // Set the version that Homey told us.
276
- // It's the absolute truth, because the Cloud API may be behind.
277
- const homeyVersion = res.headers.get('X-Homey-Version');
278
- if (homeyVersion !== this.version) {
279
- this.version = homeyVersion;
280
- }
275
+ if (text === 'false') {
276
+ throw new Error('Invalid Homey ID')
277
+ }
281
278
 
282
- return {
283
- baseUrl,
284
- strategyId,
285
- };
286
- }),
287
- new Promise((_, reject) => {
288
- pingTimeout = setTimeout(() => reject(new Error('PingTimeout')), timeout);
289
- }),
290
- ]).finally(() => clearTimeout(pingTimeout));
279
+ const homeyId = response.headers.get('X-Homey-ID');
280
+
281
+ if (homeyId && homeyId !== this.id) {
282
+ throw new Error('Invalid Homey ID'); // TODO: Add to Homey Connect
283
+ }
284
+
285
+ // Set the version that Homey told us.
286
+ // It's the absolute truth, because the Cloud API may be behind.
287
+ const homeyVersion = response.headers.get('X-Homey-Version');
288
+
289
+ if (homeyVersion !== this.version) {
290
+ this.version = homeyVersion;
291
+ }
292
+
293
+ return {
294
+ baseUrl,
295
+ strategyId,
296
+ };
291
297
  };
292
298
 
293
299
  const pings = {};
294
300
 
295
301
  // Ping localSecure (https://xxx-xxx-xxx-xx.homey.homeylocal.com)
296
302
  if (urls[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE]) {
297
- pings[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE] = ping(HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE, 5000);
303
+ pings[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE] = ping(HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE, 1200);
298
304
  pings[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE].catch(err => {
299
305
  this.__debug(`Ping ${HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE} Error:`, err && err.message);
300
306
  this.__debug(urls[HomeyAPI.DISCOVERY_STRATEGIES.LOCAL_SECURE]);
@@ -444,6 +450,7 @@ class HomeyAPIV3 extends HomeyAPI {
444
450
  }
445
451
 
446
452
  this.__debug(method, `${baseUrl}${path}`);
453
+
447
454
  const res = await Util.fetch(
448
455
  `${baseUrl}${path}`,
449
456
  {
@@ -474,7 +481,7 @@ class HomeyAPIV3 extends HomeyAPI {
474
481
  try {
475
482
  resBodyJson = JSON.parse(resBodyText);
476
483
  // eslint-disable-next-line no-empty
477
- } catch (err) {}
484
+ } catch (err) { }
478
485
  }
479
486
 
480
487
  if (!res.ok) {
@@ -543,31 +550,7 @@ class HomeyAPIV3 extends HomeyAPI {
543
550
  return;
544
551
  }
545
552
 
546
- // Create a Session by generating a JWT token on AthomCloudAPI,
547
- // and then sending the JWT token to Homey.
548
- if (this.__api) {
549
- this.__debug('Retrieving token...');
550
- const jwtToken = await this.__api.createDelegationToken({ audience: 'homey' });
551
- const token = await this.users.login({
552
- $socket: false,
553
- token: jwtToken,
554
- shouldRetry: false,
555
- });
556
- this.__token = token;
557
-
558
- const session = await this.sessions.getSessionMe({
559
- $socket: false,
560
- shouldRetry: false,
561
- });
562
- this.__session = session;
563
-
564
- await this.__setStore({ token, session });
565
-
566
- this.__debug('Got token');
567
- return;
568
- }
569
-
570
- throw new Error('Cannot Sign In: Missing AthomCloudAPI');
553
+ await this.__refreshSession();
571
554
  });
572
555
 
573
556
  this.__loginPromise
@@ -585,6 +568,50 @@ class HomeyAPIV3 extends HomeyAPI {
585
568
  return this.__loginPromise;
586
569
  }
587
570
 
571
+ async __refreshSession() {
572
+ this.__debug('refreshSession');
573
+
574
+ if (this.__api) {
575
+ // Create a Session by generating a JWT token on AthomCloudAPI,
576
+ // and then sending the JWT token to Homey.
577
+ const jwtToken = await this.__api.createDelegationToken({ audience: 'homey' });
578
+ const token = await this.users.login({
579
+ $socket: false,
580
+ token: jwtToken,
581
+ shouldRetry: false,
582
+ });
583
+ this.__token = token;
584
+
585
+ const session = await this.sessions.getSessionMe({
586
+ $socket: false,
587
+ shouldRetry: false,
588
+ });
589
+ this.__session = session;
590
+
591
+ await this.__setStore({ session, token });
592
+
593
+ this.__debug('Got token');
594
+ return;
595
+ }
596
+
597
+ throw new Error('Cannot Sign In: Missing AthomCloudAPI');
598
+ }
599
+
600
+ async refreshSession() {
601
+ if (!this.__refreshSessionPromise) {
602
+ this.__refreshSessionPromise = this.__refreshSession();
603
+
604
+ this.__refreshSessionPromise
605
+ .catch(err => {
606
+ this.__debug('Error refreshing session:', err);
607
+ }).finally(() => {
608
+ this.__refreshSessionPromise = null;
609
+ });
610
+ }
611
+
612
+ return this.__refreshSessionPromise;
613
+ }
614
+
588
615
  async logout() {
589
616
  this.__token = null;
590
617
  this.__session = null;
@@ -614,12 +641,12 @@ class HomeyAPIV3 extends HomeyAPI {
614
641
  });
615
642
 
616
643
  this.__refreshMap[token]
617
- .then(() => {})
644
+ .then(() => { })
618
645
  .catch(err => {
619
646
  this.__debug('Error Refreshing Token:', err);
620
647
  })
621
648
  .finally(() => {
622
- // Delete after 30 seconds some requests might still be pending an they should be able
649
+ // Delete after 30 seconds some requests might still be pending and they should be able
623
650
  // to receive a rejected promise for this token.
624
651
  this.__refreshMap[token + 'timeout'] = setTimeout(() => {
625
652
  delete this.__refreshMap[token];
@@ -636,17 +663,17 @@ class HomeyAPIV3 extends HomeyAPI {
636
663
  * @returns {Boolean}
637
664
  */
638
665
  isConnected() {
639
- return this.__homeySocket && this.__homeySocket.connected;
666
+ return Boolean(this.__homeySocket && this.__homeySocket.connected);
640
667
  }
641
668
 
642
669
  async subscribe(
643
670
  uri,
644
671
  {
645
- onConnect = () => {},
646
- onReconnect = () => {},
647
- onReconnectError = () => {},
648
- onDisconnect = () => {},
649
- onEvent = () => {},
672
+ onConnect = () => { },
673
+ onReconnect = () => { },
674
+ onReconnectError = () => { },
675
+ onDisconnect = () => { },
676
+ onEvent = () => { },
650
677
  }
651
678
  ) {
652
679
  this.__debug('subscribe', uri);
@@ -51,7 +51,6 @@ class HomeyAPIV3Cloud extends HomeyAPIV3 {
51
51
  }
52
52
 
53
53
  getSpecification() {
54
- // eslint-disable-next-line global-require
55
54
  return require('../../assets/specifications/HomeyAPIV3Cloud.json');
56
55
  }
57
56
 
@@ -26,7 +26,6 @@ class HomeyAPIV3Local extends HomeyAPIV3 {
26
26
  }
27
27
 
28
28
  getSpecification() {
29
- // eslint-disable-next-line global-require
30
29
  return require('../../assets/specifications/HomeyAPIV3Local.json');
31
30
  }
32
31
 
package/lib/Util.js CHANGED
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-undef */
2
-
3
1
  'use strict';
4
2
 
5
3
  const APIErrorTimeout = require('./APIErrorTimeout');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homey-api",
3
- "version": "3.4.33",
3
+ "version": "3.4.34",
4
4
  "description": "Homey API",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -16,6 +16,7 @@
16
16
  "lint": "eslint .",
17
17
  "serve": "concurrently \"serve jsdoc/\" \"npm run jsdoc:watch\"",
18
18
  "build": "npm run build:specs && npm run build:jsdoc && npm run build:types && npm run build:webpack;",
19
+ "build:docs": "plantuml-cli -tsvg SOCKET.md",
19
20
  "build:webpack": "npm run webpack",
20
21
  "build:webpack:watch": "npm run webpack:watch",
21
22
  "build:types": "npm run generate-types;",
@@ -75,6 +76,7 @@
75
76
  "jsdoc-ts-utils": "^4.0.0",
76
77
  "jsdoc-tsimport-plugin": "^1.0.5",
77
78
  "keypather": "^3.1.0",
79
+ "plantuml-cli": "^1.2024.4",
78
80
  "prettier": "^3.2.5",
79
81
  "serve": "^14.0.1",
80
82
  "socket.io": "^4.7.4",