@project-chip/matter.js 0.16.0-alpha.0-20251001-7eb06da95 → 0.16.0-alpha.0-20251004-92135c7df
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/dist/cjs/CommissioningController.d.ts +2 -2
- package/dist/cjs/CommissioningController.d.ts.map +1 -1
- package/dist/cjs/CommissioningController.js +2 -2
- package/dist/cjs/CommissioningController.js.map +1 -1
- package/dist/cjs/MatterController.d.ts +6 -6
- package/dist/cjs/MatterController.d.ts.map +1 -1
- package/dist/cjs/MatterController.js +12 -12
- package/dist/cjs/MatterController.js.map +1 -1
- package/dist/cjs/PaseCommissioner.js +1 -1
- package/dist/cjs/PaseCommissioner.js.map +1 -1
- package/dist/cjs/device/CachedClientNodeStore.d.ts +5 -4
- package/dist/cjs/device/CachedClientNodeStore.d.ts.map +1 -1
- package/dist/cjs/device/CachedClientNodeStore.js +19 -2
- package/dist/cjs/device/CachedClientNodeStore.js.map +1 -1
- package/dist/cjs/device/Endpoint.d.ts +1 -1
- package/dist/cjs/device/Endpoint.d.ts.map +1 -1
- package/dist/cjs/device/Endpoint.js.map +1 -1
- package/dist/cjs/device/PairedNode.d.ts +52 -28
- package/dist/cjs/device/PairedNode.d.ts.map +1 -1
- package/dist/cjs/device/PairedNode.js +196 -77
- package/dist/cjs/device/PairedNode.js.map +1 -1
- package/dist/esm/CommissioningController.d.ts +2 -2
- package/dist/esm/CommissioningController.d.ts.map +1 -1
- package/dist/esm/CommissioningController.js +3 -3
- package/dist/esm/CommissioningController.js.map +1 -1
- package/dist/esm/MatterController.d.ts +6 -6
- package/dist/esm/MatterController.d.ts.map +1 -1
- package/dist/esm/MatterController.js +13 -13
- package/dist/esm/MatterController.js.map +1 -1
- package/dist/esm/PaseCommissioner.js +1 -1
- package/dist/esm/PaseCommissioner.js.map +1 -1
- package/dist/esm/device/CachedClientNodeStore.d.ts +5 -4
- package/dist/esm/device/CachedClientNodeStore.d.ts.map +1 -1
- package/dist/esm/device/CachedClientNodeStore.js +19 -2
- package/dist/esm/device/CachedClientNodeStore.js.map +1 -1
- package/dist/esm/device/Endpoint.d.ts +1 -1
- package/dist/esm/device/Endpoint.d.ts.map +1 -1
- package/dist/esm/device/Endpoint.js.map +1 -1
- package/dist/esm/device/PairedNode.d.ts +52 -28
- package/dist/esm/device/PairedNode.d.ts.map +1 -1
- package/dist/esm/device/PairedNode.js +197 -78
- package/dist/esm/device/PairedNode.js.map +1 -1
- package/package.json +8 -8
- package/src/CommissioningController.ts +3 -3
- package/src/MatterController.ts +18 -18
- package/src/PaseCommissioner.ts +1 -1
- package/src/device/CachedClientNodeStore.ts +24 -4
- package/src/device/Endpoint.ts +1 -1
- package/src/device/PairedNode.ts +292 -89
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { Descriptor } from "#clusters";
|
|
6
7
|
import { AsyncObservable, BasicSet, Construction, Crypto, Diagnostic, MatterError, Observable } from "#general";
|
|
7
8
|
import { Behavior, Commands } from "#node";
|
|
8
|
-
import { ClusterClientObj, DecodedAttributeReportValue, DecodedEventReportValue, InteractionClient, NodeDiscoveryType, NodeSession } from "#protocol";
|
|
9
|
+
import { AttributeClientValues, ClusterClientObj, DecodedAttributeReportValue, DecodedEventReportValue, InteractionClient, NodeDiscoveryType, NodeSession, StructuredReadAttributeData } from "#protocol";
|
|
9
10
|
import { CaseAuthenticatedTag, ClusterId, ClusterType, EndpointNumber, NodeId } from "#types";
|
|
10
11
|
import { ClusterServerObj } from "../cluster/server/ClusterServerTypes.js";
|
|
11
12
|
import { CommissioningController } from "../CommissioningController.js";
|
|
@@ -120,6 +121,7 @@ export type CommissioningControllerNodeOptions = {
|
|
|
120
121
|
};
|
|
121
122
|
export declare class NodeNotConnectedError extends MatterError {
|
|
122
123
|
}
|
|
124
|
+
type DescriptorData = AttributeClientValues<typeof Descriptor.Complete.attributes>;
|
|
123
125
|
/**
|
|
124
126
|
* Class to represents one node that is paired/commissioned with the matter.js Controller. Instances are returned by
|
|
125
127
|
* the CommissioningController on commissioning or when connecting.
|
|
@@ -128,33 +130,7 @@ export declare class PairedNode {
|
|
|
128
130
|
#private;
|
|
129
131
|
[Diagnostic.value]: unknown;
|
|
130
132
|
readonly nodeId: NodeId;
|
|
131
|
-
readonly events:
|
|
132
|
-
/**
|
|
133
|
-
* Emitted when the node is initialized from local data. These data usually are stale, but you can still already
|
|
134
|
-
* use the node to interact with the device. If no local data are available this event will be emitted together
|
|
135
|
-
* with the initializedFromRemote event.
|
|
136
|
-
*/
|
|
137
|
-
initialized: AsyncObservable<[details: DeviceInformationData], void>;
|
|
138
|
-
/**
|
|
139
|
-
* Emitted when the node is fully initialized from remote and all attributes and events are subscribed.
|
|
140
|
-
* This event can also be awaited if code needs to be blocked until the node is fully initialized.
|
|
141
|
-
*/
|
|
142
|
-
initializedFromRemote: AsyncObservable<[details: DeviceInformationData], void>;
|
|
143
|
-
/** Emitted when the state of the node changes. */
|
|
144
|
-
stateChanged: Observable<[nodeState: NodeStates], void>;
|
|
145
|
-
/**
|
|
146
|
-
* Emitted when an attribute value changes. If the oldValue is undefined then no former value was known.
|
|
147
|
-
*/
|
|
148
|
-
attributeChanged: Observable<[data: DecodedAttributeReportValue<any>, oldValue: any], void>;
|
|
149
|
-
/** Emitted when an event is triggered. */
|
|
150
|
-
eventTriggered: Observable<[DecodedEventReportValue<any>], void>;
|
|
151
|
-
/** Emitted when the structure of the node changes (Endpoints got added or also removed). */
|
|
152
|
-
structureChanged: Observable<[void], void>;
|
|
153
|
-
/** Emitted when the node is decommissioned. */
|
|
154
|
-
decommissioned: Observable<[void], void>;
|
|
155
|
-
/** Emitted when a subscription alive trigger is received (max interval trigger or any data update) */
|
|
156
|
-
connectionAlive: Observable<[void], void>;
|
|
157
|
-
};
|
|
133
|
+
readonly events: PairedNode.Events;
|
|
158
134
|
static create(nodeId: NodeId, commissioningController: CommissioningController, options: CommissioningControllerNodeOptions | undefined, knownNodeDetails: DeviceInformationData, interactionClient: InteractionClient, reconnectFunc: ReconnectionCallback, assignDisconnectedHandler: (handler: () => Promise<void>) => void, sessions: BasicSet<NodeSession>, crypto: Crypto, storedAttributeData?: DecodedAttributeReportValue<any>[]): Promise<PairedNode>;
|
|
159
135
|
constructor(nodeId: NodeId, commissioningController: CommissioningController, options: CommissioningControllerNodeOptions | undefined, knownNodeDetails: DeviceInformationData, interactionClient: InteractionClient, reconnectFunc: ReconnectionCallback, assignDisconnectedHandler: (handler: () => Promise<void>) => void, sessions: BasicSet<NodeSession, NodeSession>, crypto: Crypto, storedAttributeData?: DecodedAttributeReportValue<any>[]);
|
|
160
136
|
get construction(): Construction<PairedNode>;
|
|
@@ -217,6 +193,12 @@ export declare class PairedNode {
|
|
|
217
193
|
}>;
|
|
218
194
|
/** Read all attributes of the devices and return them. If a stored state exists this is used to minimize needed traffic. */
|
|
219
195
|
readAllAttributes(): Promise<DecodedAttributeReportValue<any>[]>;
|
|
196
|
+
/**
|
|
197
|
+
* Traverse the structure data and collect all data for the given endpointId.
|
|
198
|
+
* Return true if data for the endpoint was found, otherwise false.
|
|
199
|
+
* If data was found it is added to the collectedData map.
|
|
200
|
+
*/
|
|
201
|
+
collectDescriptorData(structure: StructuredReadAttributeData, endpointId: EndpointNumber, collectedData: Map<EndpointNumber, DescriptorData>): void;
|
|
220
202
|
/** Returns all parts (endpoints) known for the Root Endpoint of this node. */
|
|
221
203
|
get parts(): Map<number, Endpoint>;
|
|
222
204
|
/** Returns the functional devices/endpoints (the "childs" of the Root Endpoint) known for this node. */
|
|
@@ -307,4 +289,46 @@ export declare class PairedNode {
|
|
|
307
289
|
*/
|
|
308
290
|
commandsOf<T extends Behavior.Type>(type: T): Commands.OfBehavior<T>;
|
|
309
291
|
}
|
|
292
|
+
export declare namespace PairedNode {
|
|
293
|
+
interface NodeStructureEvents {
|
|
294
|
+
/** Emitted when endpoints are added. */
|
|
295
|
+
nodeEndpointAdded: Observable<[EndpointNumber]>;
|
|
296
|
+
/** Emitted when endpoints are removed. */
|
|
297
|
+
nodeEndpointRemoved: Observable<[EndpointNumber]>;
|
|
298
|
+
/** Emitted when endpoints are updated (e.g. device type changed, structure changed). */
|
|
299
|
+
nodeEndpointChanged: Observable<[EndpointNumber]>;
|
|
300
|
+
}
|
|
301
|
+
interface Events extends NodeStructureEvents {
|
|
302
|
+
/**
|
|
303
|
+
* Emitted when the node is initialized from local data. These data usually are stale, but you can still already
|
|
304
|
+
* use the node to interact with the device. If no local data are available this event will be emitted together
|
|
305
|
+
* with the initializedFromRemote event.
|
|
306
|
+
*/
|
|
307
|
+
initialized: AsyncObservable<[details: DeviceInformationData]>;
|
|
308
|
+
/**
|
|
309
|
+
* Emitted when the node is fully initialized from remote and all attributes and events are subscribed.
|
|
310
|
+
* This event can also be awaited if code needs to be blocked until the node is fully initialized.
|
|
311
|
+
*/
|
|
312
|
+
initializedFromRemote: AsyncObservable<[details: DeviceInformationData]>;
|
|
313
|
+
/** Emitted when the state of the node changes. */
|
|
314
|
+
stateChanged: Observable<[nodeState: NodeStates]>;
|
|
315
|
+
/**
|
|
316
|
+
* Emitted when an attribute value changes. If the oldValue is undefined then no former value was known.
|
|
317
|
+
*/
|
|
318
|
+
attributeChanged: Observable<[data: DecodedAttributeReportValue<any>, oldValue: any]>;
|
|
319
|
+
/** Emitted when an event is triggered. */
|
|
320
|
+
eventTriggered: Observable<[DecodedEventReportValue<any>]>;
|
|
321
|
+
/**
|
|
322
|
+
* Emitted when all node structure changes were applied (Endpoints got added or also removed).
|
|
323
|
+
* You can alternatively use the nodeEndpointAdded, nodeEndpointRemoved and nodeEndpointChanged events to react on specific changes.
|
|
324
|
+
* This event is emitted after all nodeEndpointAdded, nodeEndpointRemoved and nodeEndpointChanged events are emitted.
|
|
325
|
+
*/
|
|
326
|
+
structureChanged: Observable<[void]>;
|
|
327
|
+
/** Emitted when the node is decommissioned. */
|
|
328
|
+
decommissioned: Observable<[void]>;
|
|
329
|
+
/** Emitted when a subscription alive trigger is received (max interval trigger or any data update) */
|
|
330
|
+
connectionAlive: Observable<[void]>;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
export {};
|
|
310
334
|
//# sourceMappingURL=PairedNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PairedNode.d.ts","sourceRoot":"","sources":["../../../src/device/PairedNode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"PairedNode.d.ts","sourceRoot":"","sources":["../../../src/device/PairedNode.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { AdministratorCommissioning, BasicInformation,
|
|
6
|
+
import { AdministratorCommissioning, BasicInformation, Descriptor, OperationalCredentials } from "#clusters";
|
|
7
7
|
import {
|
|
8
8
|
AsyncObservable,
|
|
9
9
|
Construction,
|
|
@@ -74,6 +74,15 @@ var NodeStateInformation = /* @__PURE__ */ ((NodeStateInformation2) => {
|
|
|
74
74
|
})(NodeStateInformation || {});
|
|
75
75
|
class NodeNotConnectedError extends MatterError {
|
|
76
76
|
}
|
|
77
|
+
function areNumberListsSame(list1, list2) {
|
|
78
|
+
const set1 = new Set(list1);
|
|
79
|
+
const set2 = new Set(list2);
|
|
80
|
+
if (set1.size !== set2.size) return false;
|
|
81
|
+
for (const entry of set1.values()) {
|
|
82
|
+
if (!set2.has(entry)) return false;
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
77
86
|
class PairedNode {
|
|
78
87
|
constructor(nodeId, commissioningController, options = {}, knownNodeDetails, interactionClient, reconnectFunc, assignDisconnectedHandler, sessions, crypto, storedAttributeData) {
|
|
79
88
|
this.nodeId = nodeId;
|
|
@@ -167,31 +176,23 @@ class PairedNode {
|
|
|
167
176
|
#reconnectFunc;
|
|
168
177
|
#currentSubscriptionIntervalS;
|
|
169
178
|
#crypto;
|
|
179
|
+
/**
|
|
180
|
+
* Endpoint structure change information that are checked when updating structure
|
|
181
|
+
* - null means that the endpoint itself changed, so will be regenerated completely any case
|
|
182
|
+
* - array of ClusterIds means that only these clusters changed and will be updated
|
|
183
|
+
*/
|
|
184
|
+
#registeredEndpointStructureChanges = /* @__PURE__ */ new Map();
|
|
170
185
|
events = {
|
|
171
|
-
/**
|
|
172
|
-
* Emitted when the node is initialized from local data. These data usually are stale, but you can still already
|
|
173
|
-
* use the node to interact with the device. If no local data are available this event will be emitted together
|
|
174
|
-
* with the initializedFromRemote event.
|
|
175
|
-
*/
|
|
176
186
|
initialized: AsyncObservable(),
|
|
177
|
-
/**
|
|
178
|
-
* Emitted when the node is fully initialized from remote and all attributes and events are subscribed.
|
|
179
|
-
* This event can also be awaited if code needs to be blocked until the node is fully initialized.
|
|
180
|
-
*/
|
|
181
187
|
initializedFromRemote: AsyncObservable(),
|
|
182
|
-
/** Emitted when the state of the node changes. */
|
|
183
188
|
stateChanged: Observable(),
|
|
184
|
-
/**
|
|
185
|
-
* Emitted when an attribute value changes. If the oldValue is undefined then no former value was known.
|
|
186
|
-
*/
|
|
187
189
|
attributeChanged: Observable(),
|
|
188
|
-
/** Emitted when an event is triggered. */
|
|
189
190
|
eventTriggered: Observable(),
|
|
190
|
-
/** Emitted when the structure of the node changes (Endpoints got added or also removed). */
|
|
191
191
|
structureChanged: Observable(),
|
|
192
|
-
|
|
192
|
+
nodeEndpointAdded: Observable(),
|
|
193
|
+
nodeEndpointRemoved: Observable(),
|
|
194
|
+
nodeEndpointChanged: Observable(),
|
|
193
195
|
decommissioned: Observable(),
|
|
194
|
-
/** Emitted when a subscription alive trigger is received (max interval trigger or any data update) */
|
|
195
196
|
connectionAlive: Observable()
|
|
196
197
|
};
|
|
197
198
|
static async create(nodeId, commissioningController, options = {}, knownNodeDetails, interactionClient, reconnectFunc, assignDisconnectedHandler, sessions, crypto, storedAttributeData) {
|
|
@@ -406,7 +407,7 @@ class PairedNode {
|
|
|
406
407
|
})) {
|
|
407
408
|
return;
|
|
408
409
|
}
|
|
409
|
-
await this.#initializeEndpointStructure(storedAttributeData);
|
|
410
|
+
await this.#initializeEndpointStructure(storedAttributeData, false);
|
|
410
411
|
await this.events.initialized.emit(this.#nodeDetails.toStorageData());
|
|
411
412
|
this.#localInitializationDone = true;
|
|
412
413
|
}
|
|
@@ -444,7 +445,7 @@ class PairedNode {
|
|
|
444
445
|
if (attributeReports === void 0) {
|
|
445
446
|
throw new InternalError("No attribute reports received when subscribing to all values!");
|
|
446
447
|
}
|
|
447
|
-
await this.#initializeEndpointStructure(attributeReports
|
|
448
|
+
await this.#initializeEndpointStructure(attributeReports);
|
|
448
449
|
this.#remoteInitializationInProgress = false;
|
|
449
450
|
if (!deviceDetailsUpdated) {
|
|
450
451
|
const rootEndpoint = this.getRootEndpoint();
|
|
@@ -455,7 +456,7 @@ class PairedNode {
|
|
|
455
456
|
this.#currentSubscriptionIntervalS = maxInterval;
|
|
456
457
|
} else {
|
|
457
458
|
const allClusterAttributes = await this.readAllAttributes();
|
|
458
|
-
await this.#initializeEndpointStructure(allClusterAttributes
|
|
459
|
+
await this.#initializeEndpointStructure(allClusterAttributes);
|
|
459
460
|
this.#remoteInitializationInProgress = false;
|
|
460
461
|
}
|
|
461
462
|
if (!this.#remoteInitializationDone) {
|
|
@@ -594,18 +595,21 @@ class PairedNode {
|
|
|
594
595
|
this.#reconnectDelayTimer = void 0;
|
|
595
596
|
this.#setConnectionState(0 /* Connected */);
|
|
596
597
|
}
|
|
598
|
+
if (this.#remoteInitializationDone && this.#registeredEndpointStructureChanges.size > 0 && !this.#updateEndpointStructureTimer.isRunning) {
|
|
599
|
+
logger.info(`Node ${this.nodeId}: Endpoint structure needs to be updated ...`);
|
|
600
|
+
this.#updateEndpointStructureTimer.stop().start();
|
|
601
|
+
}
|
|
597
602
|
this.events.connectionAlive.emit();
|
|
598
603
|
}
|
|
599
604
|
};
|
|
600
605
|
this.#currentSubscriptionHandler = subscriptionHandler;
|
|
601
606
|
const maxKnownEventNumber = this.#interactionClient.maxKnownEventNumber;
|
|
602
|
-
|
|
607
|
+
await this.#interactionClient.getAllAttributes({
|
|
603
608
|
dataVersionFilters: this.#interactionClient.getCachedClusterDataVersions(),
|
|
604
|
-
executeQueued: !!threadConnected
|
|
609
|
+
executeQueued: !!threadConnected,
|
|
605
610
|
// We queue subscriptions for thread devices
|
|
611
|
+
attributeChangeListener: subscriptionHandler.attributeListener
|
|
606
612
|
});
|
|
607
|
-
await this.#interactionClient.processAttributeUpdates(attributeData, subscriptionHandler.attributeListener);
|
|
608
|
-
attributeData.length = 0;
|
|
609
613
|
const initialSubscriptionData = await this.#interactionClient.subscribeAllAttributesAndEvents({
|
|
610
614
|
isUrgent: true,
|
|
611
615
|
minIntervalFloorSeconds,
|
|
@@ -631,30 +635,31 @@ class PairedNode {
|
|
|
631
635
|
enrichCachedAttributeData: true
|
|
632
636
|
});
|
|
633
637
|
}
|
|
634
|
-
#checkAttributesForNeededStructureUpdate(
|
|
635
|
-
|
|
636
|
-
if (clusterId === DescriptorCluster.id) {
|
|
638
|
+
#checkAttributesForNeededStructureUpdate(endpointId, clusterId, attributeId) {
|
|
639
|
+
if (clusterId === Descriptor.Complete.id) {
|
|
637
640
|
switch (attributeId) {
|
|
638
|
-
case
|
|
639
|
-
case
|
|
640
|
-
case
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
}
|
|
645
|
-
if (!structureUpdateNeeded) {
|
|
646
|
-
switch (attributeId) {
|
|
647
|
-
case FeatureMap.id:
|
|
648
|
-
case AttributeList.id:
|
|
649
|
-
case AcceptedCommandList.id:
|
|
650
|
-
case ClusterRevision.id:
|
|
651
|
-
structureUpdateNeeded = true;
|
|
652
|
-
break;
|
|
641
|
+
case Descriptor.Complete.attributes.partsList.id:
|
|
642
|
+
case Descriptor.Complete.attributes.serverList.id:
|
|
643
|
+
case Descriptor.Complete.attributes.clientList.id:
|
|
644
|
+
case Descriptor.Complete.attributes.deviceTypeList.id:
|
|
645
|
+
this.#registeredEndpointStructureChanges.set(endpointId, null);
|
|
646
|
+
return;
|
|
653
647
|
}
|
|
654
648
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
649
|
+
switch (attributeId) {
|
|
650
|
+
case FeatureMap.id:
|
|
651
|
+
case AttributeList.id:
|
|
652
|
+
case AcceptedCommandList.id:
|
|
653
|
+
case ClusterRevision.id:
|
|
654
|
+
let knownForUpdate = this.#registeredEndpointStructureChanges.get(endpointId);
|
|
655
|
+
if (knownForUpdate !== null) {
|
|
656
|
+
knownForUpdate = knownForUpdate ?? [];
|
|
657
|
+
if (!knownForUpdate.includes(clusterId)) {
|
|
658
|
+
knownForUpdate.push(clusterId);
|
|
659
|
+
this.#registeredEndpointStructureChanges.set(endpointId, knownForUpdate);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
break;
|
|
658
663
|
}
|
|
659
664
|
}
|
|
660
665
|
#checkEventsForNeededStructureUpdate(_endpointId, clusterId, eventId) {
|
|
@@ -682,55 +687,165 @@ class PairedNode {
|
|
|
682
687
|
this.#reconnectDelayTimer.start();
|
|
683
688
|
}
|
|
684
689
|
async #updateEndpointStructure() {
|
|
685
|
-
const allClusterAttributes =
|
|
690
|
+
const allClusterAttributes = this.#interactionClient.getAllCachedClusterData();
|
|
686
691
|
await this.#initializeEndpointStructure(allClusterAttributes, true);
|
|
687
|
-
|
|
688
|
-
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Traverse the structure data and collect all data for the given endpointId.
|
|
695
|
+
* Return true if data for the endpoint was found, otherwise false.
|
|
696
|
+
* If data was found it is added to the collectedData map.
|
|
697
|
+
*/
|
|
698
|
+
collectDescriptorData(structure, endpointId, collectedData) {
|
|
699
|
+
if (collectedData.has(endpointId)) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
const endpointData = structure[endpointId];
|
|
703
|
+
const descriptorData = endpointData?.[Descriptor.Complete.id];
|
|
704
|
+
if (endpointData === void 0 || descriptorData === void 0) {
|
|
705
|
+
logger.info(`Descriptor data for endpoint ${endpointId} not found in structure! Ignoring endpoint ...`);
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
collectedData.set(endpointId, descriptorData);
|
|
709
|
+
if (descriptorData.partsList.length) {
|
|
710
|
+
for (const partEndpointId of descriptorData.partsList) {
|
|
711
|
+
this.collectDescriptorData(structure, partEndpointId, collectedData);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
#hasEndpointChanged(device, descriptorData) {
|
|
716
|
+
return !(areNumberListsSame(
|
|
717
|
+
device.getDeviceTypes().map(({ code }) => code),
|
|
718
|
+
descriptorData.deviceTypeList.map(({ deviceType }) => deviceType)
|
|
719
|
+
) && // Check if the cluster clients are the same - they map to the serverList attribute
|
|
720
|
+
areNumberListsSame(
|
|
721
|
+
device.getAllClusterClients().map(({ id }) => id),
|
|
722
|
+
descriptorData.serverList
|
|
723
|
+
) && // Check if the cluster servers are the same - they map to the clientList attribute
|
|
724
|
+
areNumberListsSame(
|
|
725
|
+
device.getAllClusterServers().map(({ id }) => id),
|
|
726
|
+
descriptorData.clientList
|
|
727
|
+
));
|
|
689
728
|
}
|
|
690
729
|
/** Reads all data from the device and create a device object structure out of it. */
|
|
691
|
-
async #initializeEndpointStructure(allClusterAttributes, updateStructure =
|
|
730
|
+
async #initializeEndpointStructure(allClusterAttributes, updateStructure = this.#localInitializationDone || this.#remoteInitializationDone) {
|
|
731
|
+
if (this.#updateEndpointStructureTimer.isRunning) {
|
|
732
|
+
this.#updateEndpointStructureTimer.stop();
|
|
733
|
+
}
|
|
734
|
+
const eventsToEmit = /* @__PURE__ */ new Map();
|
|
735
|
+
const structureUpdateDetails = this.#registeredEndpointStructureChanges;
|
|
736
|
+
this.#registeredEndpointStructureChanges = /* @__PURE__ */ new Map();
|
|
692
737
|
const allData = structureReadAttributeDataToClusterObject(allClusterAttributes);
|
|
738
|
+
const descriptors = /* @__PURE__ */ new Map();
|
|
739
|
+
this.collectDescriptorData(allData, EndpointNumber(0), descriptors);
|
|
693
740
|
if (updateStructure) {
|
|
694
741
|
const endpointsToRemove = new Set(this.#endpoints.keys());
|
|
695
|
-
for (const
|
|
696
|
-
const
|
|
697
|
-
if (
|
|
698
|
-
|
|
699
|
-
|
|
742
|
+
for (const endpointId of descriptors.keys()) {
|
|
743
|
+
const device = this.#endpoints.get(endpointId);
|
|
744
|
+
if (device !== void 0) {
|
|
745
|
+
const hasChanged = structureUpdateDetails.has(endpointId);
|
|
746
|
+
if (!hasChanged || !this.#hasEndpointChanged(device, descriptors.get(endpointId))) {
|
|
747
|
+
logger.debug(
|
|
748
|
+
`Node ${this.nodeId}: Retaining endpoint`,
|
|
749
|
+
endpointId,
|
|
750
|
+
hasChanged ? "(with only structure changes)" : "(unchanged)"
|
|
751
|
+
);
|
|
752
|
+
endpointsToRemove.delete(endpointId);
|
|
753
|
+
if (hasChanged) {
|
|
754
|
+
eventsToEmit.set(endpointId, "nodeEndpointChanged");
|
|
755
|
+
}
|
|
756
|
+
} else {
|
|
757
|
+
logger.debug(`Node ${this.nodeId}: Recreating endpoint`, endpointId);
|
|
758
|
+
eventsToEmit.set(endpointId, "nodeEndpointChanged");
|
|
759
|
+
}
|
|
700
760
|
}
|
|
701
761
|
}
|
|
702
|
-
for (const
|
|
703
|
-
|
|
704
|
-
this.#endpoints.get(endpointId)
|
|
705
|
-
|
|
762
|
+
for (const endpoint of endpointsToRemove.values()) {
|
|
763
|
+
const endpointId = EndpointNumber(endpoint);
|
|
764
|
+
const device = this.#endpoints.get(endpointId);
|
|
765
|
+
if (device !== void 0) {
|
|
766
|
+
if (eventsToEmit.get(endpointId) !== "nodeEndpointChanged") {
|
|
767
|
+
logger.debug(`Node ${this.nodeId}: Removing endpoint`, endpointId);
|
|
768
|
+
eventsToEmit.set(endpointId, "nodeEndpointRemoved");
|
|
769
|
+
}
|
|
770
|
+
device.removeFromStructure();
|
|
771
|
+
this.#endpoints.delete(endpointId);
|
|
772
|
+
}
|
|
706
773
|
}
|
|
707
774
|
} else {
|
|
708
775
|
this.#endpoints.clear();
|
|
709
776
|
}
|
|
710
|
-
const
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
const descriptorData = clusters[DescriptorCluster.id];
|
|
714
|
-
partLists.set(endpointIdNumber, descriptorData.partsList);
|
|
715
|
-
if (this.#endpoints.has(endpointIdNumber)) {
|
|
777
|
+
for (const endpointId of descriptors.keys()) {
|
|
778
|
+
const clusters = allData[endpointId];
|
|
779
|
+
if (this.#endpoints.has(endpointId)) {
|
|
716
780
|
continue;
|
|
717
781
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
782
|
+
const isRecreation = eventsToEmit.get(endpointId) === "nodeEndpointChanged";
|
|
783
|
+
logger.debug(
|
|
784
|
+
`Node ${this.nodeId}: ${isRecreation ? "Recreating" : "Creating"} endpoint`,
|
|
785
|
+
endpointId,
|
|
786
|
+
Diagnostic.json(clusters)
|
|
722
787
|
);
|
|
788
|
+
this.#endpoints.set(endpointId, this.#createDevice(endpointId, clusters, this.#interactionClient));
|
|
789
|
+
if (!isRecreation) {
|
|
790
|
+
eventsToEmit.set(endpointId, "nodeEndpointAdded");
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
for (const [endpointId, { partsList }] of descriptors.entries()) {
|
|
794
|
+
const endpoint = this.#endpoints.get(endpointId);
|
|
795
|
+
if (endpoint === void 0) {
|
|
796
|
+
continue;
|
|
797
|
+
}
|
|
798
|
+
endpoint.getChildEndpoints().forEach((child) => {
|
|
799
|
+
if (child.number !== void 0 && !partsList.includes(child.number)) {
|
|
800
|
+
endpoint.removeChildEndpoint(child);
|
|
801
|
+
if (!eventsToEmit.has(endpointId)) {
|
|
802
|
+
eventsToEmit.set(endpointId, "nodeEndpointChanged");
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
this.#structureEndpoints(descriptors);
|
|
808
|
+
if (updateStructure && eventsToEmit.size) {
|
|
809
|
+
for (const [endpointId, eventName] of eventsToEmit.entries()) {
|
|
810
|
+
if (eventName !== "nodeEndpointAdded") {
|
|
811
|
+
const clusterServers = descriptors.get(endpointId)?.serverList;
|
|
812
|
+
await this.#interactionClient.cleanupAttributeData(
|
|
813
|
+
endpointId,
|
|
814
|
+
eventName === "nodeEndpointRemoved" ? void 0 : clusterServers
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
const emitChangeEvents = () => {
|
|
819
|
+
for (const [endpointId, eventName] of eventsToEmit.entries()) {
|
|
820
|
+
logger.debug(`Node ${this.nodeId}: Emitting event ${eventName} for endpoint ${endpointId}`);
|
|
821
|
+
this.events[eventName].emit(endpointId);
|
|
822
|
+
}
|
|
823
|
+
this.#options.stateInformationCallback?.(this.nodeId, 4 /* StructureChanged */);
|
|
824
|
+
this.events.structureChanged.emit();
|
|
825
|
+
};
|
|
826
|
+
if (this.#connectionState === 0 /* Connected */) {
|
|
827
|
+
emitChangeEvents();
|
|
828
|
+
} else {
|
|
829
|
+
this.events.stateChanged.once((State) => {
|
|
830
|
+
if (State === 0 /* Connected */) {
|
|
831
|
+
emitChangeEvents();
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
}
|
|
723
835
|
}
|
|
724
|
-
this.#structureEndpoints(partLists);
|
|
725
836
|
}
|
|
726
|
-
/**
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
837
|
+
/**
|
|
838
|
+
* Bring the endpoints in a structure based on their partsList attribute. This method only adds endpoints into the
|
|
839
|
+
* right place as children, Cleanup is not happening here
|
|
840
|
+
*/
|
|
841
|
+
#structureEndpoints(descriptors) {
|
|
842
|
+
const partLists = Array.from(descriptors.entries()).map(
|
|
843
|
+
([ep, { partsList }]) => [ep, partsList]
|
|
844
|
+
// else Typescript gets confused
|
|
731
845
|
);
|
|
846
|
+
logger.debug(`Node ${this.nodeId}: Endpoints from PartsLists`, Diagnostic.json(partLists));
|
|
732
847
|
const endpointUsages = {};
|
|
733
|
-
|
|
848
|
+
partLists.forEach(
|
|
734
849
|
([parent, partsList]) => partsList.forEach((endPoint) => {
|
|
735
850
|
if (endPoint === parent) {
|
|
736
851
|
logger.warn(`Node ${this.nodeId}: Endpoint ${endPoint} is referencing itself!`);
|
|
@@ -754,14 +869,18 @@ class PairedNode {
|
|
|
754
869
|
const childEndpointId = EndpointNumber(parseInt(childId));
|
|
755
870
|
const childEndpoint = this.#endpoints.get(childEndpointId);
|
|
756
871
|
const parentEndpoint = this.#endpoints.get(usages[0]);
|
|
872
|
+
const existingChildEndpoint = parentEndpoint?.getChildEndpoint(childEndpointId);
|
|
757
873
|
if (childEndpoint === void 0 || parentEndpoint === void 0) {
|
|
758
874
|
logger.warn(
|
|
759
875
|
`Node ${this.nodeId}: Endpoint ${usages[0]} not found in the data received from the device!`
|
|
760
876
|
);
|
|
761
|
-
} else if (
|
|
877
|
+
} else if (existingChildEndpoint !== childEndpoint) {
|
|
762
878
|
logger.debug(
|
|
763
879
|
`Node ${this.nodeId}: Endpoint structure: Child: ${childEndpointId} -> Parent: ${parentEndpoint.number}`
|
|
764
880
|
);
|
|
881
|
+
if (existingChildEndpoint !== void 0) {
|
|
882
|
+
parentEndpoint.removeChildEndpoint(existingChildEndpoint);
|
|
883
|
+
}
|
|
765
884
|
parentEndpoint.addChildEndpoint(childEndpoint);
|
|
766
885
|
}
|
|
767
886
|
delete endpointUsages[EndpointNumber(parseInt(childId))];
|
|
@@ -783,7 +902,7 @@ class PairedNode {
|
|
|
783
902
|
}
|
|
784
903
|
/** Create a device object from the data read from the device. */
|
|
785
904
|
#createDevice(endpointId, data, interactionClient) {
|
|
786
|
-
const descriptorData = data[
|
|
905
|
+
const descriptorData = data[Descriptor.Complete.id];
|
|
787
906
|
const deviceTypes = descriptorData.deviceTypeList.flatMap(({ deviceType, revision }) => {
|
|
788
907
|
const deviceTypeDefinition = getDeviceTypeDefinitionFromModelByCode(deviceType);
|
|
789
908
|
if (deviceTypeDefinition === void 0) {
|