@matter/node 0.16.0-alpha.0-20250819-0a388db8b → 0.16.0-alpha.0-20250821-dd03e1003
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/behavior/Events.d.ts +5 -0
- package/dist/cjs/behavior/Events.d.ts.map +1 -1
- package/dist/cjs/behavior/Events.js +7 -4
- package/dist/cjs/behavior/Events.js.map +1 -1
- package/dist/cjs/behavior/Transitions.d.ts.map +1 -1
- package/dist/cjs/behavior/Transitions.js +2 -2
- package/dist/cjs/behavior/Transitions.js.map +1 -1
- package/dist/cjs/behavior/context/ActionContext.d.ts +0 -7
- package/dist/cjs/behavior/context/ActionContext.d.ts.map +1 -1
- package/dist/cjs/behavior/context/server/ContextAgents.d.ts +4 -5
- package/dist/cjs/behavior/context/server/ContextAgents.d.ts.map +1 -1
- package/dist/cjs/behavior/context/server/ContextAgents.js +9 -0
- package/dist/cjs/behavior/context/server/ContextAgents.js.map +1 -1
- package/dist/cjs/behavior/context/server/OfflineContext.d.ts.map +1 -1
- package/dist/cjs/behavior/context/server/OfflineContext.js +0 -8
- package/dist/cjs/behavior/context/server/OfflineContext.js.map +1 -1
- package/dist/cjs/behavior/context/server/OnlineContext.d.ts.map +1 -1
- package/dist/cjs/behavior/context/server/OnlineContext.js +0 -8
- package/dist/cjs/behavior/context/server/OnlineContext.js.map +1 -1
- package/dist/cjs/behavior/internal/Reactors.js +1 -1
- package/dist/cjs/behavior/internal/Reactors.js.map +1 -1
- package/dist/cjs/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
- package/dist/cjs/behavior/system/commissioning/CommissioningClient.js +58 -58
- package/dist/cjs/behavior/system/commissioning/CommissioningClient.js.map +1 -1
- package/dist/cjs/behavior/system/network/ClientNetworkRuntime.d.ts +1 -0
- package/dist/cjs/behavior/system/network/ClientNetworkRuntime.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/ClientNetworkRuntime.js +40 -4
- package/dist/cjs/behavior/system/network/ClientNetworkRuntime.js.map +2 -2
- package/dist/cjs/behavior/system/network/NetworkBehavior.d.ts +5 -0
- package/dist/cjs/behavior/system/network/NetworkBehavior.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkBehavior.js +5 -0
- package/dist/cjs/behavior/system/network/NetworkBehavior.js.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkClient.d.ts +7 -4
- package/dist/cjs/behavior/system/network/NetworkClient.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkClient.js +14 -7
- package/dist/cjs/behavior/system/network/NetworkClient.js.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkRuntime.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkRuntime.js +0 -1
- package/dist/cjs/behavior/system/network/NetworkRuntime.js.map +1 -1
- package/dist/cjs/behavior/system/network/ServerNetworkRuntime.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/ServerNetworkRuntime.js +1 -0
- package/dist/cjs/behavior/system/network/ServerNetworkRuntime.js.map +1 -1
- package/dist/cjs/behavior/system/parts/PartsBehavior.js +1 -1
- package/dist/cjs/behavior/system/parts/PartsBehavior.js.map +1 -1
- package/dist/cjs/behavior/system/product-description/ProductDescriptionServer.js +1 -1
- package/dist/cjs/behavior/system/product-description/ProductDescriptionServer.js.map +1 -1
- package/dist/cjs/behaviors/general-commissioning/ServerNodeFailsafeContext.js +1 -1
- package/dist/cjs/behaviors/general-commissioning/ServerNodeFailsafeContext.js.map +1 -1
- package/dist/cjs/behaviors/groups/GroupsServer.js +4 -4
- package/dist/cjs/behaviors/groups/GroupsServer.js.map +1 -1
- package/dist/cjs/endpoint/Agent.js +1 -1
- package/dist/cjs/endpoint/Agent.js.map +1 -1
- package/dist/cjs/endpoint/Endpoint.d.ts +9 -0
- package/dist/cjs/endpoint/Endpoint.d.ts.map +1 -1
- package/dist/cjs/endpoint/Endpoint.js +12 -1
- package/dist/cjs/endpoint/Endpoint.js.map +1 -1
- package/dist/cjs/endpoint/properties/Behaviors.js +3 -3
- package/dist/cjs/endpoint/properties/Behaviors.js.map +1 -1
- package/dist/cjs/endpoint/properties/Commands.js +1 -1
- package/dist/cjs/endpoint/properties/Commands.js.map +1 -1
- package/dist/cjs/node/ClientNode.d.ts +12 -0
- package/dist/cjs/node/ClientNode.d.ts.map +1 -1
- package/dist/cjs/node/ClientNode.js +28 -0
- package/dist/cjs/node/ClientNode.js.map +1 -1
- package/dist/cjs/node/Node.d.ts.map +1 -1
- package/dist/cjs/node/Node.js +2 -0
- package/dist/cjs/node/Node.js.map +1 -1
- package/dist/cjs/node/client/ClientBehavior.js +11 -4
- package/dist/cjs/node/client/ClientBehavior.js.map +1 -1
- package/dist/cjs/node/client/ClientEventEmitter.d.ts +19 -0
- package/dist/cjs/node/client/ClientEventEmitter.d.ts.map +1 -0
- package/dist/cjs/node/client/ClientEventEmitter.js +97 -0
- package/dist/cjs/node/client/ClientEventEmitter.js.map +6 -0
- package/dist/cjs/node/client/ClientStructure.d.ts +7 -3
- package/dist/cjs/node/client/ClientStructure.d.ts.map +1 -1
- package/dist/cjs/node/client/ClientStructure.js +42 -22
- package/dist/cjs/node/client/ClientStructure.js.map +1 -1
- package/dist/cjs/node/client/NodePeerAddressStore.d.ts +4 -1
- package/dist/cjs/node/client/NodePeerAddressStore.d.ts.map +1 -1
- package/dist/cjs/node/server/IdentityService.js +1 -1
- package/dist/cjs/node/server/IdentityService.js.map +1 -1
- package/dist/cjs/node/server/ProtocolService.js +1 -1
- package/dist/cjs/node/server/ProtocolService.js.map +1 -1
- package/dist/esm/behavior/Events.d.ts +5 -0
- package/dist/esm/behavior/Events.d.ts.map +1 -1
- package/dist/esm/behavior/Events.js +8 -4
- package/dist/esm/behavior/Events.js.map +1 -1
- package/dist/esm/behavior/Transitions.d.ts.map +1 -1
- package/dist/esm/behavior/Transitions.js +2 -2
- package/dist/esm/behavior/Transitions.js.map +1 -1
- package/dist/esm/behavior/context/ActionContext.d.ts +0 -7
- package/dist/esm/behavior/context/ActionContext.d.ts.map +1 -1
- package/dist/esm/behavior/context/server/ContextAgents.d.ts +4 -5
- package/dist/esm/behavior/context/server/ContextAgents.d.ts.map +1 -1
- package/dist/esm/behavior/context/server/ContextAgents.js +9 -0
- package/dist/esm/behavior/context/server/ContextAgents.js.map +1 -1
- package/dist/esm/behavior/context/server/OfflineContext.d.ts.map +1 -1
- package/dist/esm/behavior/context/server/OfflineContext.js +0 -8
- package/dist/esm/behavior/context/server/OfflineContext.js.map +1 -1
- package/dist/esm/behavior/context/server/OnlineContext.d.ts.map +1 -1
- package/dist/esm/behavior/context/server/OnlineContext.js +0 -8
- package/dist/esm/behavior/context/server/OnlineContext.js.map +1 -1
- package/dist/esm/behavior/internal/Reactors.js +1 -1
- package/dist/esm/behavior/internal/Reactors.js.map +1 -1
- package/dist/esm/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
- package/dist/esm/behavior/system/commissioning/CommissioningClient.js +58 -58
- package/dist/esm/behavior/system/commissioning/CommissioningClient.js.map +1 -1
- package/dist/esm/behavior/system/network/ClientNetworkRuntime.d.ts +1 -0
- package/dist/esm/behavior/system/network/ClientNetworkRuntime.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/ClientNetworkRuntime.js +42 -6
- package/dist/esm/behavior/system/network/ClientNetworkRuntime.js.map +2 -2
- package/dist/esm/behavior/system/network/NetworkBehavior.d.ts +5 -0
- package/dist/esm/behavior/system/network/NetworkBehavior.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/NetworkBehavior.js +5 -0
- package/dist/esm/behavior/system/network/NetworkBehavior.js.map +1 -1
- package/dist/esm/behavior/system/network/NetworkClient.d.ts +7 -4
- package/dist/esm/behavior/system/network/NetworkClient.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/NetworkClient.js +14 -7
- package/dist/esm/behavior/system/network/NetworkClient.js.map +1 -1
- package/dist/esm/behavior/system/network/NetworkRuntime.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/NetworkRuntime.js +0 -1
- package/dist/esm/behavior/system/network/NetworkRuntime.js.map +1 -1
- package/dist/esm/behavior/system/network/ServerNetworkRuntime.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/ServerNetworkRuntime.js +1 -0
- package/dist/esm/behavior/system/network/ServerNetworkRuntime.js.map +1 -1
- package/dist/esm/behavior/system/parts/PartsBehavior.js +1 -1
- package/dist/esm/behavior/system/parts/PartsBehavior.js.map +1 -1
- package/dist/esm/behavior/system/product-description/ProductDescriptionServer.js +1 -1
- package/dist/esm/behavior/system/product-description/ProductDescriptionServer.js.map +1 -1
- package/dist/esm/behaviors/general-commissioning/ServerNodeFailsafeContext.js +1 -1
- package/dist/esm/behaviors/general-commissioning/ServerNodeFailsafeContext.js.map +1 -1
- package/dist/esm/behaviors/groups/GroupsServer.js +4 -4
- package/dist/esm/behaviors/groups/GroupsServer.js.map +1 -1
- package/dist/esm/endpoint/Agent.js +1 -1
- package/dist/esm/endpoint/Agent.js.map +1 -1
- package/dist/esm/endpoint/Endpoint.d.ts +9 -0
- package/dist/esm/endpoint/Endpoint.d.ts.map +1 -1
- package/dist/esm/endpoint/Endpoint.js +12 -1
- package/dist/esm/endpoint/Endpoint.js.map +1 -1
- package/dist/esm/endpoint/properties/Behaviors.js +3 -3
- package/dist/esm/endpoint/properties/Behaviors.js.map +1 -1
- package/dist/esm/endpoint/properties/Commands.js +1 -1
- package/dist/esm/endpoint/properties/Commands.js.map +1 -1
- package/dist/esm/node/ClientNode.d.ts +12 -0
- package/dist/esm/node/ClientNode.d.ts.map +1 -1
- package/dist/esm/node/ClientNode.js +28 -0
- package/dist/esm/node/ClientNode.js.map +1 -1
- package/dist/esm/node/Node.d.ts.map +1 -1
- package/dist/esm/node/Node.js +2 -0
- package/dist/esm/node/Node.js.map +1 -1
- package/dist/esm/node/client/ClientBehavior.js +11 -4
- package/dist/esm/node/client/ClientBehavior.js.map +1 -1
- package/dist/esm/node/client/ClientEventEmitter.d.ts +19 -0
- package/dist/esm/node/client/ClientEventEmitter.d.ts.map +1 -0
- package/dist/esm/node/client/ClientEventEmitter.js +77 -0
- package/dist/esm/node/client/ClientEventEmitter.js.map +6 -0
- package/dist/esm/node/client/ClientStructure.d.ts +7 -3
- package/dist/esm/node/client/ClientStructure.d.ts.map +1 -1
- package/dist/esm/node/client/ClientStructure.js +42 -22
- package/dist/esm/node/client/ClientStructure.js.map +1 -1
- package/dist/esm/node/client/NodePeerAddressStore.d.ts +4 -1
- package/dist/esm/node/client/NodePeerAddressStore.d.ts.map +1 -1
- package/dist/esm/node/server/IdentityService.js +1 -1
- package/dist/esm/node/server/IdentityService.js.map +1 -1
- package/dist/esm/node/server/ProtocolService.js +1 -1
- package/dist/esm/node/server/ProtocolService.js.map +1 -1
- package/package.json +7 -7
- package/src/behavior/Events.ts +19 -6
- package/src/behavior/Transitions.ts +7 -6
- package/src/behavior/context/ActionContext.ts +0 -6
- package/src/behavior/context/server/ContextAgents.ts +17 -1
- package/src/behavior/context/server/OfflineContext.ts +0 -11
- package/src/behavior/context/server/OnlineContext.ts +0 -12
- package/src/behavior/internal/Reactors.ts +1 -1
- package/src/behavior/system/commissioning/CommissioningClient.ts +61 -59
- package/src/behavior/system/network/ClientNetworkRuntime.ts +59 -6
- package/src/behavior/system/network/NetworkBehavior.ts +6 -1
- package/src/behavior/system/network/NetworkClient.ts +17 -9
- package/src/behavior/system/network/NetworkRuntime.ts +0 -1
- package/src/behavior/system/network/ServerNetworkRuntime.ts +2 -0
- package/src/behavior/system/parts/PartsBehavior.ts +1 -1
- package/src/behavior/system/product-description/ProductDescriptionServer.ts +1 -1
- package/src/behaviors/general-commissioning/ServerNodeFailsafeContext.ts +1 -1
- package/src/behaviors/groups/GroupsServer.ts +4 -4
- package/src/endpoint/Agent.ts +1 -1
- package/src/endpoint/Endpoint.ts +14 -1
- package/src/endpoint/properties/Behaviors.ts +3 -3
- package/src/endpoint/properties/Commands.ts +1 -1
- package/src/node/ClientNode.ts +34 -1
- package/src/node/Node.ts +2 -0
- package/src/node/client/ClientBehavior.ts +12 -5
- package/src/node/client/ClientEventEmitter.ts +115 -0
- package/src/node/client/ClientStructure.ts +58 -34
- package/src/node/server/IdentityService.ts +1 -1
- package/src/node/server/ProtocolService.ts +1 -1
|
@@ -75,6 +75,7 @@ function generateType(analysis: ShapeAnalysis, baseType: Behavior.Type): Cluster
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
let { schema } = analysis;
|
|
78
|
+
let isCloned = false;
|
|
78
79
|
const { extraAttrs, extraCommands } = analysis;
|
|
79
80
|
|
|
80
81
|
// Obtain a ClusterType. This provides TLV for known elements
|
|
@@ -99,8 +100,7 @@ function generateType(analysis: ShapeAnalysis, baseType: Behavior.Type): Cluster
|
|
|
99
100
|
.map(([k]) => k);
|
|
100
101
|
if (featureNames.length) {
|
|
101
102
|
// Update ClusterModel
|
|
102
|
-
|
|
103
|
-
schema.supportedFeatures = featureNames;
|
|
103
|
+
cloneSchema();
|
|
104
104
|
|
|
105
105
|
// Update the cluster. Note that we do not validate feature combinations. What the device sends we work with
|
|
106
106
|
cluster = new ClusterComposer(cluster, true).compose(featureNames.map(capitalize));
|
|
@@ -109,7 +109,7 @@ function generateType(analysis: ShapeAnalysis, baseType: Behavior.Type): Cluster
|
|
|
109
109
|
// If the schema does not match what the device actually returned, further augment both the ClusterModel and
|
|
110
110
|
// ClusterType with unknown attributes and/or commands
|
|
111
111
|
if (schema.revision !== analysis.shape.revision || extraAttrs.size || extraCommands.size) {
|
|
112
|
-
|
|
112
|
+
cloneSchema();
|
|
113
113
|
|
|
114
114
|
cluster = {
|
|
115
115
|
...cluster,
|
|
@@ -118,8 +118,6 @@ function generateType(analysis: ShapeAnalysis, baseType: Behavior.Type): Cluster
|
|
|
118
118
|
commands: { ...cluster.commands },
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
schema.supportedFeatures = supportedFeatures;
|
|
122
|
-
|
|
123
121
|
for (const id of extraAttrs) {
|
|
124
122
|
const name = createUnknownName("attr", id);
|
|
125
123
|
cluster.attributes[camelize(name, false)] = Attribute(id, TlvAny);
|
|
@@ -145,6 +143,15 @@ function generateType(analysis: ShapeAnalysis, baseType: Behavior.Type): Cluster
|
|
|
145
143
|
|
|
146
144
|
return type;
|
|
147
145
|
|
|
146
|
+
function cloneSchema() {
|
|
147
|
+
if (isCloned) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
schema = schema.clone();
|
|
151
|
+
schema.supportedFeatures = featureNames;
|
|
152
|
+
isCloned = true;
|
|
153
|
+
}
|
|
154
|
+
|
|
148
155
|
function implementCommand(command: ClusterType.Command) {
|
|
149
156
|
return async function (this: ClusterBehavior, fields?: {}) {
|
|
150
157
|
const node = this.env.get(Node) as ClientNode;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ElementEvent, Events } from "#behavior/Events.js";
|
|
8
|
+
import { camelize, Logger } from "#general";
|
|
9
|
+
import { ClusterModel, EventModel, MatterModel } from "#model";
|
|
10
|
+
import { ClientNode } from "#node/ClientNode.js";
|
|
11
|
+
import { ReadResult } from "#protocol";
|
|
12
|
+
import { ClusterId, EndpointNumber, EventId } from "#types";
|
|
13
|
+
import { ClientStructure } from "./ClientStructure.js";
|
|
14
|
+
|
|
15
|
+
const logger = Logger.get("ClientEventEmitter");
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Event handler for Matter events transmitted by a peer.
|
|
19
|
+
*
|
|
20
|
+
* TODO - set priority on context when split for server vs. client
|
|
21
|
+
* TODO - record latest event number for each subscription shape (or just wildcard?)
|
|
22
|
+
*/
|
|
23
|
+
export interface ClientEventEmitter {
|
|
24
|
+
(event: ReadResult.EventValue): void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Cache of MatterModel + cluster + event ID -> event name.
|
|
29
|
+
*/
|
|
30
|
+
const nameCache = new WeakMap<
|
|
31
|
+
MatterModel,
|
|
32
|
+
Record<`${ClusterId}-${EventId}`, undefined | { cluster: string; event: string }>
|
|
33
|
+
>();
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* We warn for each cluster or cluster+event that we don't support.
|
|
37
|
+
*/
|
|
38
|
+
const warnedForUnknown = new Set<ClusterId | `${ClusterId}-${EventId}`>();
|
|
39
|
+
|
|
40
|
+
export function ClientEventEmitter(node: ClientNode, structure: ClientStructure) {
|
|
41
|
+
return emitClientEvent;
|
|
42
|
+
|
|
43
|
+
function emitClientEvent(occurrence: ReadResult.EventValue) {
|
|
44
|
+
const names = getNames(node.matter, occurrence);
|
|
45
|
+
if (!names) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const event = getEvent(occurrence.path.endpointId, names.cluster, names.event);
|
|
50
|
+
if (event) {
|
|
51
|
+
node.act(agent => {
|
|
52
|
+
// Current ActionContext is not writable, could skip act() but meh, see TODO above
|
|
53
|
+
//agent.context.priority = occurrence.priority;
|
|
54
|
+
event.emit(occurrence.value, agent.context);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getEvent(endpointId: EndpointNumber, clusterName: string, eventName: string) {
|
|
60
|
+
const endpoint = structure.endpointFor(endpointId);
|
|
61
|
+
if (endpoint === undefined) {
|
|
62
|
+
logger.error(`Received event for unsupported endpoint #${endpointId}`);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const events = (endpoint.events as Events.Generic<ElementEvent>)[clusterName];
|
|
67
|
+
if (events === undefined) {
|
|
68
|
+
logger.error(`Received event ${eventName} for unsupported cluster ${clusterName} on ${endpoint}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const event = events[eventName];
|
|
73
|
+
if (event === undefined) {
|
|
74
|
+
logger.error(`Received unsupported event ${eventName} for cluster ${clusterName} on ${endpoint}`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return event;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getNames(matter: MatterModel, { path: { clusterId, eventId } }: ReadResult.EventValue) {
|
|
83
|
+
let matterCache = nameCache.get(matter);
|
|
84
|
+
if (matterCache === undefined) {
|
|
85
|
+
matterCache = {};
|
|
86
|
+
nameCache.set(matter, matterCache);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const key = `${clusterId}-${eventId}` as const;
|
|
90
|
+
if (key in matterCache) {
|
|
91
|
+
return matterCache[key];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const cluster = matter.get(ClusterModel, clusterId);
|
|
95
|
+
if (cluster === undefined) {
|
|
96
|
+
if (!warnedForUnknown.has(clusterId)) {
|
|
97
|
+
logger.warn(`Ignoring events for unknown cluster #${clusterId}`);
|
|
98
|
+
warnedForUnknown.add(clusterId);
|
|
99
|
+
matterCache[key] = undefined;
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const event = cluster.get(EventModel, eventId);
|
|
105
|
+
if (event === undefined) {
|
|
106
|
+
if (!warnedForUnknown.has(key)) {
|
|
107
|
+
logger.warn(`Ignoring unknown event #${eventId} for ${cluster.name} cluster`);
|
|
108
|
+
warnedForUnknown.add(key);
|
|
109
|
+
matterCache[key] = undefined;
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return (matterCache[key] = { cluster: camelize(cluster.name), event: camelize(event.name) });
|
|
115
|
+
}
|
|
@@ -17,6 +17,7 @@ import { DatasourceCache } from "#storage/client/DatasourceCache.js";
|
|
|
17
17
|
import { ClientNodeStore } from "#storage/index.js";
|
|
18
18
|
import type { AttributeId, ClusterId, ClusterType, CommandId, DeviceTypeId, EndpointNumber } from "#types";
|
|
19
19
|
import { ClientBehavior } from "./ClientBehavior.js";
|
|
20
|
+
import { ClientEventEmitter } from "./ClientEventEmitter.js";
|
|
20
21
|
|
|
21
22
|
const DEVICE_TYPE_LIST_ATTR_ID = DescriptorCluster.attributes.deviceTypeList.id;
|
|
22
23
|
const SERVER_LIST_ATTR_ID = DescriptorCluster.attributes.serverList.id;
|
|
@@ -28,6 +29,7 @@ const PARTS_LIST_ATTR_ID = DescriptorCluster.attributes.partsList.id;
|
|
|
28
29
|
export class ClientStructure {
|
|
29
30
|
#nodeStore: ClientNodeStore;
|
|
30
31
|
#endpoints: Record<EndpointNumber, EndpointStructure> = {};
|
|
32
|
+
#emitEvent: ClientEventEmitter;
|
|
31
33
|
|
|
32
34
|
constructor(node: ClientNode) {
|
|
33
35
|
this.#nodeStore = node.env.get(ClientNodeStore);
|
|
@@ -35,6 +37,7 @@ export class ClientStructure {
|
|
|
35
37
|
endpoint: node,
|
|
36
38
|
clusters: {},
|
|
37
39
|
};
|
|
40
|
+
this.#emitEvent = ClientEventEmitter(node, this);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
/**
|
|
@@ -76,9 +79,9 @@ export class ClientStructure {
|
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
/**
|
|
82
|
+
* Obtain the store for a non-cluster behavior.
|
|
79
83
|
*
|
|
80
|
-
*
|
|
81
|
-
* @returns
|
|
84
|
+
* The data for these behaviors is managed locally and not synced from the peer.
|
|
82
85
|
*/
|
|
83
86
|
storeForLocal(endpoint: Endpoint, type: Behavior.Type) {
|
|
84
87
|
return this.#nodeStore.storeForEndpoint(endpoint).createStoreForLocalBehavior(type.id);
|
|
@@ -132,39 +135,17 @@ export class ClientStructure {
|
|
|
132
135
|
|
|
133
136
|
for await (const chunk of changes) {
|
|
134
137
|
for (const change of chunk) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const { endpointId, clusterId, attributeId } = change.path;
|
|
138
|
+
switch (change.kind) {
|
|
139
|
+
case "attr-value":
|
|
140
|
+
currentUpdates = await this.#mutateAttribute(change, scope, currentUpdates);
|
|
141
|
+
break;
|
|
140
142
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
currentUpdates &&
|
|
145
|
-
(currentUpdates.endpointId !== endpointId || currentUpdates.clusterId !== clusterId)
|
|
146
|
-
) {
|
|
147
|
-
await this.#updateCluster(currentUpdates);
|
|
148
|
-
currentUpdates = undefined;
|
|
143
|
+
case "event-value":
|
|
144
|
+
this.#emitEvent(change);
|
|
145
|
+
break;
|
|
149
146
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// Updating a new endpoint/cluster
|
|
153
|
-
currentUpdates = {
|
|
154
|
-
endpointId,
|
|
155
|
-
clusterId,
|
|
156
|
-
values: {
|
|
157
|
-
[attributeId]: change.value,
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
// Update version but only if this was a wildcard read
|
|
162
|
-
if (scope.isWildcard(endpointId, clusterId)) {
|
|
163
|
-
currentUpdates.values[DatasourceCache.VERSION_KEY] = change.version;
|
|
164
|
-
}
|
|
165
|
-
} else {
|
|
166
|
-
// Add value to change set for current endpoint/cluster
|
|
167
|
-
currentUpdates.values[attributeId] = change.value;
|
|
147
|
+
if (change.kind !== "attr-value") {
|
|
148
|
+
continue;
|
|
168
149
|
}
|
|
169
150
|
}
|
|
170
151
|
|
|
@@ -176,8 +157,44 @@ export class ClientStructure {
|
|
|
176
157
|
}
|
|
177
158
|
}
|
|
178
159
|
|
|
160
|
+
async #mutateAttribute(
|
|
161
|
+
change: ReadResult.AttributeValue,
|
|
162
|
+
scope: ReadScope,
|
|
163
|
+
currentUpdates: undefined | AttributeUpdates,
|
|
164
|
+
) {
|
|
165
|
+
const { endpointId, clusterId, attributeId } = change.path;
|
|
166
|
+
|
|
167
|
+
// If we are building updates to a cluster and the cluster/endpoint changes, apply the current update
|
|
168
|
+
// set
|
|
169
|
+
if (currentUpdates && (currentUpdates.endpointId !== endpointId || currentUpdates.clusterId !== clusterId)) {
|
|
170
|
+
await this.#updateCluster(currentUpdates);
|
|
171
|
+
currentUpdates = undefined;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (currentUpdates === undefined) {
|
|
175
|
+
// Updating a new endpoint/cluster
|
|
176
|
+
currentUpdates = {
|
|
177
|
+
endpointId,
|
|
178
|
+
clusterId,
|
|
179
|
+
values: {
|
|
180
|
+
[attributeId]: change.value,
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// Update version but only if this was a wildcard read
|
|
185
|
+
if (scope.isWildcard(endpointId, clusterId)) {
|
|
186
|
+
currentUpdates.values[DatasourceCache.VERSION_KEY] = change.version;
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
// Add value to change set for current endpoint/cluster
|
|
190
|
+
currentUpdates.values[attributeId] = change.value;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return currentUpdates;
|
|
194
|
+
}
|
|
195
|
+
|
|
179
196
|
/**
|
|
180
|
-
* Obtain the {@link ClusterType} for an
|
|
197
|
+
* Obtain the {@link ClusterType} for an {@link EndpointNumber} and {@link ClusterId}.
|
|
181
198
|
*/
|
|
182
199
|
clusterFor(endpoint: EndpointNumber, cluster: ClusterId) {
|
|
183
200
|
const ep = this.#endpointFor(endpoint);
|
|
@@ -188,6 +205,13 @@ export class ClientStructure {
|
|
|
188
205
|
return this.#clusterFor(ep, cluster)?.behavior?.cluster;
|
|
189
206
|
}
|
|
190
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Obtain the {@link Endpoint} for a {@link EndpointNumber}.
|
|
210
|
+
*/
|
|
211
|
+
endpointFor(endpoint: EndpointNumber): Endpoint | undefined {
|
|
212
|
+
return this.#endpoints[endpoint]?.endpoint;
|
|
213
|
+
}
|
|
214
|
+
|
|
191
215
|
/**
|
|
192
216
|
* Apply new attribute values for specific endpoint/cluster.
|
|
193
217
|
*
|
|
@@ -44,7 +44,7 @@ export class IdentityService {
|
|
|
44
44
|
other = this.#node;
|
|
45
45
|
} else {
|
|
46
46
|
if (this.#partsById === undefined) {
|
|
47
|
-
this.#partsById = OfflineContext.ReadOnly
|
|
47
|
+
this.#partsById = this.#node.agentFor(OfflineContext.ReadOnly).get(IndexBehavior).partsById;
|
|
48
48
|
}
|
|
49
49
|
other = this.#partsById?.[number];
|
|
50
50
|
}
|