zigbee-clusters 2.5.1 → 2.6.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.
- package/.prettierrc +7 -0
- package/README.md +4 -3
- package/lib/Cluster.js +79 -42
- package/package.json +1 -1
package/.prettierrc
ADDED
package/README.md
CHANGED
|
@@ -87,9 +87,10 @@ class MyDevice extends Homey.Device {
|
|
|
87
87
|
// Zigbee specification and refuses to send a default response.
|
|
88
88
|
waitForResponse: true,
|
|
89
89
|
|
|
90
|
-
// This is an optional property that allows for adjusting the response
|
|
91
|
-
// timeout (
|
|
92
|
-
timeout
|
|
90
|
+
// This is an optional property that allows for adjusting the default response
|
|
91
|
+
// timeout (10000ms) before the command is considered rejected.
|
|
92
|
+
// The timeout starts after sending the frame and receiving a low-level ack.
|
|
93
|
+
timeout: 5000,
|
|
93
94
|
}
|
|
94
95
|
);
|
|
95
96
|
});
|
package/lib/Cluster.js
CHANGED
|
@@ -340,16 +340,18 @@ class Cluster extends EventEmitter {
|
|
|
340
340
|
* discover any manufacture- specific
|
|
341
341
|
* commands.
|
|
342
342
|
*
|
|
343
|
-
* @param {object} [
|
|
344
|
-
* @param {number} [
|
|
345
|
-
* @param {number} [
|
|
343
|
+
* @param {object} [params=]
|
|
344
|
+
* @param {number} [params.startValue=0]
|
|
345
|
+
* @param {number} [params.maxResults=250]
|
|
346
|
+
* @param {object} [opts=] - Optional parameters
|
|
347
|
+
* @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
|
|
346
348
|
* @returns {Promise<number[]>}
|
|
347
349
|
*/
|
|
348
|
-
async discoverCommandsGenerated({ startValue = 0, maxResults = 250 } = {}) {
|
|
350
|
+
async discoverCommandsGenerated({ startValue = 0, maxResults = 250 } = {}, opts) {
|
|
349
351
|
const { commandIds } = await super.discoverCommandsGenerated({
|
|
350
352
|
startValue,
|
|
351
353
|
maxResults,
|
|
352
|
-
});
|
|
354
|
+
}, opts);
|
|
353
355
|
|
|
354
356
|
const res = commandIds.map(cId => ((this.constructor.commandsById[cId] || [])
|
|
355
357
|
.filter(c => !c.global)
|
|
@@ -375,16 +377,18 @@ class Cluster extends EventEmitter {
|
|
|
375
377
|
* a manufacturer-specific cluster. A manufacturer ID in this field of 0xffff (wildcard) will
|
|
376
378
|
* discover any manufacture- specific commands.
|
|
377
379
|
*
|
|
378
|
-
* @param {object} [
|
|
379
|
-
* @param {number} [
|
|
380
|
-
* @param {number} [
|
|
380
|
+
* @param {object} [params=]
|
|
381
|
+
* @param {number} [params.startValue=0]
|
|
382
|
+
* @param {number} [params.maxResults=255]
|
|
383
|
+
* @param {object} [opts=] - Optional parameters
|
|
384
|
+
* @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
|
|
381
385
|
* @returns {Promise<number[]>}
|
|
382
386
|
*/
|
|
383
|
-
async discoverCommandsReceived({ startValue = 0, maxResults = 255 } = {}) {
|
|
387
|
+
async discoverCommandsReceived({ startValue = 0, maxResults = 255 } = {}, opts) {
|
|
384
388
|
const { commandIds } = await super.discoverCommandsReceived({
|
|
385
389
|
startValue,
|
|
386
390
|
maxResults,
|
|
387
|
-
});
|
|
391
|
+
}, opts);
|
|
388
392
|
|
|
389
393
|
const res = commandIds.map(cId => ((this.constructor.commandsById[cId] || [])
|
|
390
394
|
.filter(c => !c.global)
|
|
@@ -400,7 +404,8 @@ class Cluster extends EventEmitter {
|
|
|
400
404
|
* Command which reads a given set of attributes from the remote cluster.
|
|
401
405
|
* Note: do not mix regular and manufacturer specific attributes.
|
|
402
406
|
* @param {string[]} attributeNames
|
|
403
|
-
* @param {
|
|
407
|
+
* @param {object} [opts=] - Optional parameters
|
|
408
|
+
* @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
|
|
404
409
|
* @returns {Promise<Object.<string, unknown>>} - Object with values (e.g. `{ onOff: true }`)
|
|
405
410
|
*/
|
|
406
411
|
async readAttributes(attributeNames, opts) {
|
|
@@ -453,9 +458,11 @@ class Cluster extends EventEmitter {
|
|
|
453
458
|
* Note: do not mix regular and manufacturer specific attributes.
|
|
454
459
|
* @param {object} attributes - Object with attribute names as keys and their values (e.g. `{
|
|
455
460
|
* onOff: true, fakeAttributeName: 10 }`.
|
|
461
|
+
* @param {object} [opts=] - Optional parameters
|
|
462
|
+
* @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
|
|
456
463
|
* @returns {Promise<*|{attributes: *}>}
|
|
457
464
|
*/
|
|
458
|
-
async writeAttributes(attributes = {}) {
|
|
465
|
+
async writeAttributes(attributes = {}, opts) {
|
|
459
466
|
const arr = Object.keys(attributes).map(n => {
|
|
460
467
|
const attr = this.constructor.attributes[n];
|
|
461
468
|
if (!attr) {
|
|
@@ -477,7 +484,7 @@ class Cluster extends EventEmitter {
|
|
|
477
484
|
|
|
478
485
|
debug(this.logId, 'write attributes', attributes, manufacturerId ? `manufacturer specific id ${manufacturerId}` : '');
|
|
479
486
|
|
|
480
|
-
return super.writeAttributes({ attributes: data, manufacturerId });
|
|
487
|
+
return super.writeAttributes({ attributes: data, manufacturerId }, opts);
|
|
481
488
|
}
|
|
482
489
|
|
|
483
490
|
/**
|
|
@@ -485,9 +492,11 @@ class Cluster extends EventEmitter {
|
|
|
485
492
|
* Note: do not mix regular and manufacturer specific attributes.
|
|
486
493
|
* @param {object} attributes - Attribute reporting configuration (e.g. `{ onOff: {
|
|
487
494
|
* minInterval: 0, maxInterval: 300, minChange: 1 } }`)
|
|
495
|
+
* @param {object} [opts=] - Optional parameters
|
|
496
|
+
* @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
|
|
488
497
|
* @returns {Promise<void>}
|
|
489
498
|
*/
|
|
490
|
-
async configureReporting(attributes = {}) {
|
|
499
|
+
async configureReporting(attributes = {}, opts) {
|
|
491
500
|
const req = [];
|
|
492
501
|
// eslint-disable-next-line guard-for-in,no-restricted-syntax
|
|
493
502
|
for (const attributeName in attributes) {
|
|
@@ -524,7 +533,7 @@ class Cluster extends EventEmitter {
|
|
|
524
533
|
|
|
525
534
|
debug(this.logId, 'configure reporting', req, manufacturerId ? `manufacturer specific id ${manufacturerId}` : '');
|
|
526
535
|
|
|
527
|
-
const { reports } = await super.configureReporting({ reports: req, manufacturerId });
|
|
536
|
+
const { reports } = await super.configureReporting({ reports: req, manufacturerId }, opts);
|
|
528
537
|
|
|
529
538
|
debug(this.logId, 'configured reporting', reports);
|
|
530
539
|
for (const result of reports) {
|
|
@@ -554,10 +563,12 @@ class Cluster extends EventEmitter {
|
|
|
554
563
|
* interesting).
|
|
555
564
|
* Note: do not mix regular and manufacturer specific attributes.
|
|
556
565
|
* @param {Array} attributes - Array with number/strings (either attribute id, or attribute name).
|
|
566
|
+
* @param {object} [opts=] - Optional parameters
|
|
567
|
+
* @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
|
|
557
568
|
* @returns {Promise<ReadReportingConfiguration[]>} - Returns array with
|
|
558
569
|
* ReadReportingConfiguration objects per attribute.
|
|
559
570
|
*/
|
|
560
|
-
async readReportingConfiguration(attributes = []) {
|
|
571
|
+
async readReportingConfiguration(attributes = [], opts) {
|
|
561
572
|
const req = [];
|
|
562
573
|
|
|
563
574
|
// Loop all the provided attributes
|
|
@@ -601,7 +612,7 @@ class Cluster extends EventEmitter {
|
|
|
601
612
|
const { reports } = await super.readReportingConfiguration({
|
|
602
613
|
attributes: req,
|
|
603
614
|
manufacturerId,
|
|
604
|
-
});
|
|
615
|
+
}, opts);
|
|
605
616
|
debug(this.logId, 'read reporting configuration result', reports);
|
|
606
617
|
|
|
607
618
|
// Return the parsed reports
|
|
@@ -624,15 +635,17 @@ class Cluster extends EventEmitter {
|
|
|
624
635
|
* in a ZigBee cluster or 1 to discover manufacturer specific attributes in either a standard
|
|
625
636
|
* or a manufacturer specific cluster.
|
|
626
637
|
*
|
|
638
|
+
* @param {object} [opts=] - Optional parameters
|
|
639
|
+
* @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
|
|
627
640
|
* @returns {Promise<Array>} - Array with string or number values (depending on if the
|
|
628
641
|
* attribute
|
|
629
642
|
* is implemented in zigbee-clusters or not).
|
|
630
643
|
*/
|
|
631
|
-
async discoverAttributes() {
|
|
644
|
+
async discoverAttributes(opts) {
|
|
632
645
|
const { attributes } = await super.discoverAttributes({
|
|
633
646
|
startValue: 0,
|
|
634
647
|
maxResults: 255,
|
|
635
|
-
});
|
|
648
|
+
}, opts);
|
|
636
649
|
|
|
637
650
|
const result = [];
|
|
638
651
|
for (const attr of attributes) {
|
|
@@ -660,16 +673,18 @@ class Cluster extends EventEmitter {
|
|
|
660
673
|
* or a manufacturer- specific cluster. A manufacturer ID in this field of 0xffff (wildcard)
|
|
661
674
|
* will discover any manufacture-specific attributes.
|
|
662
675
|
*
|
|
676
|
+
* @param {object} [opts=] - Optional parameters
|
|
677
|
+
* @param {number} [opts.timeout] - Optional timeout in milliseconds for waiting for response
|
|
663
678
|
* @returns {Promise<Array>} - Returns an array with objects with attribute names as keys and
|
|
664
679
|
* following object as values: `{name: string, id: number, acl: { readable: boolean, writable:
|
|
665
680
|
* boolean, reportable: boolean } }`. Note that `name` is optional based on whether the
|
|
666
681
|
* attribute is implemented in zigbee-clusters.
|
|
667
682
|
*/
|
|
668
|
-
async discoverAttributesExtended() {
|
|
683
|
+
async discoverAttributesExtended(opts) {
|
|
669
684
|
const { attributes } = await super.discoverAttributesExtended({
|
|
670
685
|
startValue: 0,
|
|
671
686
|
maxResults: 250,
|
|
672
|
-
});
|
|
687
|
+
}, opts);
|
|
673
688
|
|
|
674
689
|
const result = [];
|
|
675
690
|
for (const attr of attributes) {
|
|
@@ -956,23 +971,6 @@ class Cluster extends EventEmitter {
|
|
|
956
971
|
return this._nextTrxSeqNr;
|
|
957
972
|
}
|
|
958
973
|
|
|
959
|
-
async _awaitPacket(trxSequenceNumber, timeout = 25000) {
|
|
960
|
-
if (this._trxHandlers[trxSequenceNumber]) {
|
|
961
|
-
throw new Error(`already waiting for this trx: ${trxSequenceNumber}`);
|
|
962
|
-
}
|
|
963
|
-
return new Promise((resolve, reject) => {
|
|
964
|
-
const t = setTimeout(() => {
|
|
965
|
-
delete this._trxHandlers[trxSequenceNumber];
|
|
966
|
-
reject(new Error('Timeout: Expected Response'));
|
|
967
|
-
}, timeout);
|
|
968
|
-
this._trxHandlers[trxSequenceNumber] = async frame => {
|
|
969
|
-
delete this._trxHandlers[trxSequenceNumber];
|
|
970
|
-
resolve(frame);
|
|
971
|
-
clearTimeout(t);
|
|
972
|
-
};
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
|
|
976
974
|
// / START STATIC METHODS
|
|
977
975
|
|
|
978
976
|
// Adds command proxy stubs to a proto object which is one level higher.
|
|
@@ -1106,15 +1104,54 @@ class Cluster extends EventEmitter {
|
|
|
1106
1104
|
return this.sendFrame(payload);
|
|
1107
1105
|
}
|
|
1108
1106
|
|
|
1109
|
-
//
|
|
1110
|
-
let responseTimeout;
|
|
1107
|
+
// Timeout between getting a low-level ack and receiving the ZCL response
|
|
1108
|
+
let responseTimeout = 10_000;
|
|
1109
|
+
|
|
1110
|
+
// Check if a timeout override is provided
|
|
1111
1111
|
if (typeof opts.timeout === 'number') {
|
|
1112
1112
|
responseTimeout = opts.timeout;
|
|
1113
1113
|
}
|
|
1114
1114
|
|
|
1115
|
+
if (this._trxHandlers[payload.trxSequenceNumber]) {
|
|
1116
|
+
throw new Error(`already waiting for this trx: ${payload.trxSequenceNumber}`);
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
let rejectAwaitResponse;
|
|
1120
|
+
let resolveAwaitResponse;
|
|
1121
|
+
let awaitResponseTimeout;
|
|
1115
1122
|
const [response] = await Promise.all([
|
|
1116
|
-
|
|
1117
|
-
|
|
1123
|
+
new Promise((resolve, reject) => {
|
|
1124
|
+
rejectAwaitResponse = reject;
|
|
1125
|
+
resolveAwaitResponse = resolve;
|
|
1126
|
+
|
|
1127
|
+
this._trxHandlers[payload.trxSequenceNumber] = async frame => {
|
|
1128
|
+
delete this._trxHandlers[payload.trxSequenceNumber];
|
|
1129
|
+
if (awaitResponseTimeout) clearTimeout(awaitResponseTimeout);
|
|
1130
|
+
resolveAwaitResponse(frame);
|
|
1131
|
+
};
|
|
1132
|
+
}),
|
|
1133
|
+
|
|
1134
|
+
// Send the frame and when the frame is actually sent start the timeout for receiving
|
|
1135
|
+
// the response, sending the frame could be queued or delayed for other reasons
|
|
1136
|
+
// so only start the timeout when it is certain that the frame is sent.
|
|
1137
|
+
this.sendFrame(payload)
|
|
1138
|
+
.then(() => {
|
|
1139
|
+
if (typeof responseTimeout !== 'number') return;
|
|
1140
|
+
|
|
1141
|
+
// Make sure the response is still expected
|
|
1142
|
+
if (this._trxHandlers[payload.trxSequenceNumber] == null) return;
|
|
1143
|
+
|
|
1144
|
+
awaitResponseTimeout = setTimeout(() => {
|
|
1145
|
+
delete this._trxHandlers[payload.trxSequenceNumber];
|
|
1146
|
+
rejectAwaitResponse(new Error('Timeout: Expected Response'));
|
|
1147
|
+
}, responseTimeout);
|
|
1148
|
+
})
|
|
1149
|
+
.catch(err => {
|
|
1150
|
+
delete this._trxHandlers[payload.trxSequenceNumber];
|
|
1151
|
+
if (awaitResponseTimeout) clearTimeout(awaitResponseTimeout);
|
|
1152
|
+
rejectAwaitResponse(err);
|
|
1153
|
+
throw err;
|
|
1154
|
+
}),
|
|
1118
1155
|
]);
|
|
1119
1156
|
|
|
1120
1157
|
if (response instanceof this.constructor.defaultResponseArgsType) {
|