zigbee-clusters 2.7.2 → 2.8.0

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.
Files changed (2) hide show
  1. package/lib/Cluster.js +39 -20
  2. package/package.json +1 -1
package/lib/Cluster.js CHANGED
@@ -403,29 +403,39 @@ class Cluster extends EventEmitter {
403
403
  /**
404
404
  * Command which reads a given set of attributes from the remote cluster.
405
405
  * Note: do not mix regular and manufacturer specific attributes.
406
- * @param {string[]} attributeNames
406
+ * @param {Array<string | number>} attributes - Attribute names or numeric IDs
407
407
  * @param {object} [opts=] - Optional parameters
408
- * @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
409
- * @returns {Promise<Object.<string, unknown>>} - Object with values (e.g. `{ onOff: true }`)
408
+ * @param {number} [opts.timeout] - Optional timeout in ms
409
+ * @returns {Promise<Object.<string, unknown>>} - Keyed by attribute name or
410
+ * numeric ID
410
411
  */
411
- async readAttributes(attributeNames, opts) {
412
- if (attributeNames instanceof Array === false) {
413
- throw new Error('Expected attribute names array, as of zigbee-clusters@2.0.0 call readAttributes([\'myAttr\'])');
412
+ async readAttributes(attributes, opts) {
413
+ if (attributes instanceof Array === false) {
414
+ throw new Error('Expected attributes array, as of zigbee-clusters@2.0.0 call readAttributes([\'myAttr\'])');
414
415
  }
415
416
 
416
- if (!attributeNames.length) {
417
- attributeNames = Object.keys(this.constructor.attributes);
418
- }
419
- const mismatch = attributeNames.find(n => !this.constructor.attributes[n]);
420
- if (mismatch) {
421
- throw new TypeError(`${mismatch} is not a valid attribute of ${this.name}`);
417
+ if (!attributes.length) {
418
+ attributes = Object.keys(this.constructor.attributes);
422
419
  }
423
420
 
424
421
  const idToName = {};
425
- const attrIds = new Set(attributeNames.map(a => {
426
- idToName[this.constructor.attributes[a].id] = a;
427
- return this.constructor.attributes[a].id;
428
- }));
422
+ const numericIds = new Set();
423
+ const attrIds = new Set();
424
+ for (const attr of attributes) {
425
+ if (typeof attr === 'number') {
426
+ if (!Number.isInteger(attr) || attr < 0 || attr > 0xFFFF) {
427
+ throw new TypeError(`${attr} is not a valid numeric attribute ID for ${this.name}, must be an integer between 0 and 0xFFFF`);
428
+ }
429
+ numericIds.add(attr);
430
+ if (idToName[attr] === undefined) idToName[attr] = attr;
431
+ attrIds.add(attr);
432
+ } else if (this.constructor.attributes[attr]) {
433
+ idToName[this.constructor.attributes[attr].id] = attr;
434
+ attrIds.add(this.constructor.attributes[attr].id);
435
+ } else {
436
+ throw new TypeError(`${attr} is not a valid attribute of ${this.name}`);
437
+ }
438
+ }
429
439
 
430
440
  const resultObj = {};
431
441
  while (attrIds.size) {
@@ -433,19 +443,23 @@ class Cluster extends EventEmitter {
433
443
  const manufacturerId = this._checkForManufacturerSpecificAttributes(Array.from(attrIds));
434
444
  debug(this.logId, 'read attributes', [...attrIds], manufacturerId ? `manufacturer specific id ${manufacturerId}` : '');
435
445
 
436
- const { attributes } = await super.readAttributes({
446
+ const response = await super.readAttributes({
437
447
  attributes: [...attrIds],
438
448
  manufacturerId,
439
449
  }, opts);
440
450
 
441
- debug(this.logId, 'read attributes result', { attributes });
442
- const result = this.constructor.attributeArrayStatusDataType.fromBuffer(attributes, 0);
451
+ debug(this.logId, 'read attributes result', response);
452
+ const { attributeArrayStatusDataType } = this.constructor;
453
+ const result = attributeArrayStatusDataType.fromBuffer(response.attributes, 0);
443
454
  if (!result.length) break;
444
455
 
445
456
  result.forEach(a => {
446
457
  attrIds.delete(a.id);
447
458
  if (a.status === 'SUCCESS') {
448
459
  resultObj[idToName[a.id]] = a.value;
460
+ if (numericIds.has(a.id) && idToName[a.id] !== a.id) {
461
+ resultObj[a.id] = a.value;
462
+ }
449
463
  }
450
464
  });
451
465
  }
@@ -690,8 +704,13 @@ class Cluster extends EventEmitter {
690
704
  for (const attr of attributes) {
691
705
  const attribute = this.constructor.attributesById[attr.id];
692
706
  const discoveredAttribute = {
693
- acl: attr.acl,
707
+ acl: {
708
+ readable: !!attr.acl.readable,
709
+ writable: !!attr.acl.writable,
710
+ reportable: !!attr.acl.reportable,
711
+ },
694
712
  id: attr.id,
713
+ dataTypeId: attr.dataTypeId,
695
714
  };
696
715
 
697
716
  // If the attribute is implemented in zigbee-clusters add name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-clusters",
3
- "version": "2.7.2",
3
+ "version": "2.8.0",
4
4
  "description": "Zigbee Cluster Library for Node.js",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",