homey-api 1.6.1 → 1.7.3

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.
@@ -201,6 +201,29 @@
201
201
  ):
202
202
  Promise<void>;
203
203
 
204
+ authenticateWithAuthorizationCode(
205
+
206
+
207
+
208
+
209
+ opts: {
210
+
211
+
212
+ code: String,
213
+
214
+
215
+
216
+ removeCodeFromHistory: Boolean,
217
+
218
+
219
+ },
220
+
221
+
222
+
223
+
224
+ ):
225
+ Promise<AthomCloudAPI.Token>;
226
+
204
227
  }
205
228
 
206
229
  export class HomeyAPI {
@@ -2985,6 +2985,73 @@
2985
2985
  ):
2986
2986
  Promise<void>;
2987
2987
 
2988
+ authenticateWithAuthorizationCode(
2989
+
2990
+
2991
+
2992
+
2993
+ opts: {
2994
+
2995
+
2996
+ code: String,
2997
+
2998
+
2999
+
3000
+ removeCodeFromHistory: Boolean,
3001
+
3002
+
3003
+ },
3004
+
3005
+
3006
+
3007
+
3008
+ ):
3009
+ Promise<AthomCloudAPI.Token>;
3010
+
3011
+ updateUserMe(
3012
+
3013
+
3014
+
3015
+
3016
+ opts: {
3017
+
3018
+
3019
+ firstname: String,
3020
+
3021
+
3022
+
3023
+ lastname: String,
3024
+
3025
+
3026
+
3027
+ email: String,
3028
+
3029
+
3030
+ },
3031
+
3032
+
3033
+
3034
+
3035
+ ):
3036
+ Promise<AthomCloudAPI.User>;
3037
+
3038
+ updateUserMeAvatar(
3039
+
3040
+
3041
+
3042
+
3043
+ imageBuffer: Buffer,
3044
+
3045
+
3046
+
3047
+ imageType: "jpg" | "jpeg" | "png" | "gif",
3048
+
3049
+
3050
+
3051
+
3052
+ ):
3053
+ Promise<Object>;
3054
+
2988
3055
  }
2989
3056
 
2990
3057
  export class AthomConnectAPI {
@@ -35,7 +35,7 @@ and login on that user's Homey.`;
35
35
  const AthomCloudAPI = require('homey-api/lib/AthomCloudAPI');
36
36
 
37
37
  // Create an AthomCloudAPI instance
38
- const api = new AthomCloudAPI({
38
+ const cloudApi = new {@link AthomCloudAPI AthomCloudAPI}({
39
39
  clientId: '5a8d4ca6eb9f7a2c9d6ccf6d',
40
40
  clientSecret: 'e3ace394af9f615857ceaa61b053f966ddcfb12a',
41
41
  redirectUrl: 'http://localhost',
@@ -43,30 +43,38 @@ const api = new AthomCloudAPI({
43
43
 
44
44
  // Check if we're logged in
45
45
  // If not, redirect the user to the OAuth2 dialog
46
- const loggedIn = await api.isLoggedIn();
46
+ const loggedIn = await {@link AthomCloudAPI cloudApi}.{@link AthomCloudAPI#isLoggedIn isLoggedIn}();
47
47
  if (!loggedIn) {
48
- if (api.hasAuthorizationCode()) {
49
- const token = await api.authenticateWithAuthorizationCode();
48
+ if ({@link AthomCloudAPI cloudApi}.{@link AthomCloudAPI#hasAuthorizationCode hasAuthorizationCode}()) {
49
+ const token = await {@link AthomCloudAPI cloudApi}.{@link AthomCloudAPI#authenticateWithAuthorizationCode authenticateWithAuthorizationCode}();
50
50
  } else {
51
- window.location.href = api.getLoginUrl();
51
+ window.location.href = {@link AthomCloudAPI cloudApi}.{@link AthomCloudAPI#getLoginUrl getLoginUrl}();
52
52
  return;
53
53
  }
54
54
  }
55
55
 
56
56
  // Get the logged in user
57
- const user = await cloudApi.getAuthenticatedUser();
57
+ const user = await {@link AthomCloudAPI cloudApi}.{@link AthomCloudAPI#getAuthenticatedUser getAuthenticatedUser}();
58
58
 
59
59
  // Get the first Homey of the logged in user
60
- const homey = await user.getFirstHomey();
60
+ const homey = await {@link AthomCloudAPI.User user}.{@link AthomCloudAPI.User#getFirstHomey getFirstHomey}();
61
61
 
62
62
  // Create a session on this Homey
63
- const homeyApi = await homey.authenticate();
63
+ const homeyApi = await {@link AthomCloudAPI.Homey homey}.{@link AthomCloudAPI.Homey#authenticate authenticate}();
64
64
 
65
- // Loop all devices
66
- const devices = await homeyApi.devices.getDevices();
67
- for(const device of Object.values(devices)) {
65
+ // Get all Zones from ManagerZones
66
+ const zones = await {@link HomeyAPIV2 homeyApi}.{@link HomeyAPIV2.ManagerZones zones}.{@link HomeyAPIV2.ManagerZones#getZones getZones}();
67
+
68
+ // Get all Devices from ManagerDevices
69
+ const devices = await {@link HomeyAPIV2 homeyApi}.{@link HomeyAPIV2.ManagerDevices devices}.{@link HomeyAPIV2.ManagerDevices#getDevices getDevices}();
70
+
71
+ // Turn all devices on
72
+ for(const {@link HomeyAPIV2.ManagerDevices.Device device} of Object.values(devices)) {
68
73
  // Turn device on
69
- await device.setCapabilityValue({ capabilityId: 'onoff', value: true });
74
+ await {@link HomeyAPIV2.ManagerDevices.Device device}.{@link HomeyAPIV2.ManagerDevices.Device#setCapabilityValue setCapabilityValue}({
75
+ capabilityId: 'onoff',
76
+ value: true,
77
+ });
70
78
  }`;
71
79
 
72
80
  static JSDOC_PARAMS = `
@@ -198,6 +206,9 @@ for(const device of Object.values(devices)) {
198
206
  * @returns {Promise<void>}
199
207
  */
200
208
  async logout() {
209
+ // Delete Cached User
210
+ this.__user = null;
211
+
201
212
  // Delete Token from Store
202
213
  await this.__resetStore();
203
214
  this.__token = null;
@@ -307,7 +318,7 @@ for(const device of Object.values(devices)) {
307
318
  body: body.toString(),
308
319
  method: 'post',
309
320
  headers: {
310
- 'Authorization': `Basic ${Util.base64(`${this.__clientId}:${this.__clientSecret}`)}`,
321
+ Authorization: `Basic ${Util.base64(`${this.__clientId}:${this.__clientSecret}`)}`,
311
322
  'Content-Type': 'application/x-www-form-urlencoded',
312
323
  },
313
324
  });
@@ -333,6 +344,13 @@ for(const device of Object.values(devices)) {
333
344
  return this.__token;
334
345
  }
335
346
 
347
+ /**
348
+ * Authenticate with an authorization code.
349
+ * @param {Object} [opts]
350
+ * @param {String} opts.code - Default to `?code=...` when in a browser.
351
+ * @param {Boolean} [opts.removeCodeFromHistory=true] - Remove `?code=...` from the URL in the address bar.
352
+ * @returns {Promise<AthomCloudAPI.Token>}
353
+ */
336
354
  async authenticateWithAuthorizationCode({
337
355
  code,
338
356
  removeCodeFromHistory = true,
@@ -362,7 +380,7 @@ for(const device of Object.values(devices)) {
362
380
  body: body.toString(),
363
381
  method: 'post',
364
382
  headers: {
365
- 'Authorization': `Basic ${Util.base64(`${this.__clientId}:${this.__clientSecret}`)}`,
383
+ Authorization: `Basic ${Util.base64(`${this.__clientId}:${this.__clientSecret}`)}`,
366
384
  'Content-Type': 'application/x-www-form-urlencoded',
367
385
  },
368
386
  });
@@ -423,7 +441,7 @@ for(const device of Object.values(devices)) {
423
441
  body: body.toString(),
424
442
  method: 'post',
425
443
  headers: {
426
- 'Authorization': `Basic ${Util.base64(`${this.__clientId}:${this.__clientSecret}`)}`,
444
+ Authorization: `Basic ${Util.base64(`${this.__clientId}:${this.__clientSecret}`)}`,
427
445
  'Content-Type': 'application/x-www-form-urlencoded',
428
446
  },
429
447
  });
@@ -468,7 +486,7 @@ for(const device of Object.values(devices)) {
468
486
  body: body.toString(),
469
487
  method: 'post',
470
488
  headers: {
471
- 'Authorization': `Basic ${Util.base64(`${this.__clientId}:${this.__clientSecret}`)}`,
489
+ Authorization: `Basic ${Util.base64(`${this.__clientId}:${this.__clientSecret}`)}`,
472
490
  'Content-Type': 'application/x-www-form-urlencoded',
473
491
  },
474
492
  });
@@ -504,6 +522,76 @@ for(const device of Object.values(devices)) {
504
522
  return this.__refreshTokenPromise;
505
523
  }
506
524
 
525
+ /**
526
+ * Update the currently authenticated user.
527
+ *
528
+ * @private
529
+ * @param {Object} [opts]
530
+ * @param {String} [opts.firstname]
531
+ * @param {String} [opts.lastname]
532
+ * @param {String} [opts.email]
533
+ * @returns {Promise<AthomCloudAPI.User>}
534
+ */
535
+ async updateUserMe({
536
+ firstname,
537
+ lastname,
538
+ email,
539
+ }) {
540
+ const me = await this.getAuthenticatedUser();
541
+ return this.updateUser({
542
+ id: me._id,
543
+ user: {
544
+ firstname,
545
+ lastname,
546
+ email,
547
+ },
548
+ });
549
+ }
550
+
551
+ /**
552
+ * Update the currently authenticated user's avatar.
553
+ *
554
+ * @private
555
+ * @param {Buffer} imageBuffer Buffer of the new avatar
556
+ * @param {"jpg"|"jpeg"|"png"|"gif"} imageType Type of the new avatar
557
+ * @returns {Promise<Object>}
558
+ */
559
+ async updateUserMeAvatar(imageBuffer, imageType) {
560
+ if (!Buffer.isBuffer(imageBuffer)) {
561
+ throw new Error('Invalid Image. Expected Buffer.');
562
+ }
563
+
564
+ if (!imageType) {
565
+ throw new Error('Missing Image Type');
566
+ }
567
+
568
+ if (!['jpg', 'png', 'gif'].includes(imageType)) {
569
+ throw new Error(`Invalid Image Type: ${imageType}`);
570
+ }
571
+
572
+ if (imageType === 'jpg') {
573
+ imageType = 'jpeg';
574
+ }
575
+
576
+ const me = await this.getAuthenticatedUser();
577
+ const body = Buffer.concat([
578
+ Buffer.from(`--__X_HOMEY_BOUNDARY__\r\nContent-Disposition: form-data; name="avatar"; filename="avatar"\r\nContent-Type: image/${imageType}\r\n\r\n`),
579
+ Buffer.from(imageBuffer),
580
+ Buffer.from('\r\n--__X_HOMEY_BOUNDARY__--\r\n'),
581
+ ]);
582
+
583
+ return this.call({
584
+ method: 'POST',
585
+ path: `/user/${me._id}/avatar`,
586
+ headers: {
587
+ 'Content-Type': 'multipart/form-data; boundary="__X_HOMEY_BOUNDARY__"',
588
+ 'Content-Length': body.length,
589
+ },
590
+ body,
591
+ bodyJSON: false,
592
+ });
593
+ }
594
+
507
595
  }
508
596
 
509
597
  module.exports = AthomCloudAPI;
@@ -24,6 +24,14 @@ class Device extends Item {
24
24
  * @param {number|boolean|string} listener.value
25
25
  * @returns {HomeyAPIV2.ManagerDevices.Device.DeviceCapability}
26
26
  * @function HomeyAPIV2.ManagerDevices.Device#makeCapabilityInstance
27
+ * @example
28
+ *
29
+ * const onOffInstance = device.makeCapabilityInstance('onoff', value => {
30
+ * console.log('Device onoff changed to:', value);
31
+ * });
32
+ *
33
+ * // Turn on
34
+ * onOffInstance.setValue(true).catch(console.error);
27
35
  */
28
36
  makeCapabilityInstance(capabilityId, listener) {
29
37
  this.connect().catch(err => {
package/package.json CHANGED
@@ -1,8 +1,15 @@
1
1
  {
2
2
  "name": "homey-api",
3
- "version": "1.6.1",
3
+ "version": "1.7.3",
4
4
  "description": "Homey API",
5
5
  "main": "index.js",
6
+ "files": [
7
+ "/lib",
8
+ "/assets/specifications",
9
+ "/assets/types",
10
+ "/index.js",
11
+ "/index.browser.js"
12
+ ],
6
13
  "types": "assets/types/homey-api.d.ts",
7
14
  "scripts": {
8
15
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -11,12 +18,11 @@
11
18
  "build": "npm run build:specs; npm run build:jsdoc; npm run build:types; npm run build:webpack;",
12
19
  "build:webpack": "npm run webpack",
13
20
  "build:webpack:watch": "npm run webpack:watch",
14
- "build:jsdoc": "npm run jsdoc:clean; npm run generate-specs; npm run generate-jsdoc; npm run jsdoc;",
15
21
  "build:types": "npm run generate-types;",
16
22
  "build:specs": "npm run generate-specs",
17
23
  "webpack": "webpack",
18
24
  "webpack:watch": "webpack --watch",
19
- "jsdoc": "jsdoc --configure ./jsdoc.json --recurse --destination build/jsdoc; jsdoc --configure ./jsdoc.json --recurse --private --destination build/jsdoc/private; rm build/jsdoc/*.js.html;",
25
+ "jsdoc": "npm run jsdoc:clean; npm run generate-specs; npm run generate-jsdoc; jsdoc --configure ./jsdoc.json --recurse; jsdoc --configure ./jsdoc.json --recurse --private --destination ./jsdoc/private; rm ./jsdoc/*.js.html;",
20
26
  "jsdoc:clean": "rm -rf ./build/jsdoc; rm -rf ./build/jsdoc-tmp",
21
27
  "jsdoc:watch": "watch \"npm run jsdoc:clean; npm run generate-jsdoc; npm run jsdoc;\" lib \"node_modules/homey-jsdoc-template\" --interval 0.5",
22
28
  "jsdoc:serve": "http-server ./build/jsdoc/",
@@ -44,6 +50,7 @@
44
50
  "socket.io-client": "^1.7.4"
45
51
  },
46
52
  "devDependencies": {
53
+ "@athombv/jsdoc-template": "^1.6.1",
47
54
  "@babel/core": "^7.16.0",
48
55
  "@babel/plugin-proposal-class-properties": "^7.16.0",
49
56
  "@babel/preset-env": "^7.16.0",
@@ -53,7 +60,6 @@
53
60
  "eslint": "^7.32.0",
54
61
  "eslint-config-athom": "^2.1.1",
55
62
  "fs-extra": "^10.0.0",
56
- "homey-jsdoc-template": "github:athombv/homey-jsdoc-template#1.4",
57
63
  "http-server": "^0.12.3",
58
64
  "jsdoc": "^3.6.7",
59
65
  "jsdoc-to-markdown": "^7.1.0",