@matter-server/ws-controller 0.2.0-alpha.0-00000000-000000000
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/LICENSE +201 -0
- package/README.md +11 -0
- package/dist/esm/controller/AttributeDataCache.d.ts +49 -0
- package/dist/esm/controller/AttributeDataCache.d.ts.map +1 -0
- package/dist/esm/controller/AttributeDataCache.js +154 -0
- package/dist/esm/controller/AttributeDataCache.js.map +6 -0
- package/dist/esm/controller/ControllerCommandHandler.d.ts +118 -0
- package/dist/esm/controller/ControllerCommandHandler.d.ts.map +1 -0
- package/dist/esm/controller/ControllerCommandHandler.js +1015 -0
- package/dist/esm/controller/ControllerCommandHandler.js.map +6 -0
- package/dist/esm/controller/LegacyDataInjector.d.ts +95 -0
- package/dist/esm/controller/LegacyDataInjector.d.ts.map +1 -0
- package/dist/esm/controller/LegacyDataInjector.js +196 -0
- package/dist/esm/controller/LegacyDataInjector.js.map +6 -0
- package/dist/esm/controller/MatterController.d.ts +59 -0
- package/dist/esm/controller/MatterController.d.ts.map +1 -0
- package/dist/esm/controller/MatterController.js +212 -0
- package/dist/esm/controller/MatterController.js.map +6 -0
- package/dist/esm/controller/Nodes.d.ts +62 -0
- package/dist/esm/controller/Nodes.d.ts.map +1 -0
- package/dist/esm/controller/Nodes.js +85 -0
- package/dist/esm/controller/Nodes.js.map +6 -0
- package/dist/esm/controller/TestNodeCommandHandler.d.ts +84 -0
- package/dist/esm/controller/TestNodeCommandHandler.d.ts.map +1 -0
- package/dist/esm/controller/TestNodeCommandHandler.js +225 -0
- package/dist/esm/controller/TestNodeCommandHandler.js.map +6 -0
- package/dist/esm/data/VendorIDs.d.ts +7 -0
- package/dist/esm/data/VendorIDs.d.ts.map +1 -0
- package/dist/esm/data/VendorIDs.js +1237 -0
- package/dist/esm/data/VendorIDs.js.map +6 -0
- package/dist/esm/example/send-command.d.ts +7 -0
- package/dist/esm/example/send-command.d.ts.map +1 -0
- package/dist/esm/example/send-command.js +60 -0
- package/dist/esm/example/send-command.js.map +6 -0
- package/dist/esm/index.d.ts +21 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +26 -0
- package/dist/esm/index.js.map +6 -0
- package/dist/esm/model/ModelMapper.d.ts +34 -0
- package/dist/esm/model/ModelMapper.d.ts.map +1 -0
- package/dist/esm/model/ModelMapper.js +62 -0
- package/dist/esm/model/ModelMapper.js.map +6 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/server/ConfigStorage.d.ts +29 -0
- package/dist/esm/server/ConfigStorage.d.ts.map +1 -0
- package/dist/esm/server/ConfigStorage.js +84 -0
- package/dist/esm/server/ConfigStorage.js.map +6 -0
- package/dist/esm/server/Converters.d.ts +53 -0
- package/dist/esm/server/Converters.d.ts.map +1 -0
- package/dist/esm/server/Converters.js +343 -0
- package/dist/esm/server/Converters.js.map +6 -0
- package/dist/esm/server/WebSocketControllerHandler.d.ts +21 -0
- package/dist/esm/server/WebSocketControllerHandler.d.ts.map +1 -0
- package/dist/esm/server/WebSocketControllerHandler.js +767 -0
- package/dist/esm/server/WebSocketControllerHandler.js.map +6 -0
- package/dist/esm/types/CommandHandler.d.ts +258 -0
- package/dist/esm/types/CommandHandler.d.ts.map +1 -0
- package/dist/esm/types/CommandHandler.js +6 -0
- package/dist/esm/types/CommandHandler.js.map +6 -0
- package/dist/esm/types/WebServer.d.ts +12 -0
- package/dist/esm/types/WebServer.d.ts.map +1 -0
- package/dist/esm/types/WebServer.js +6 -0
- package/dist/esm/types/WebServer.js.map +6 -0
- package/dist/esm/types/WebSocketMessageTypes.d.ts +478 -0
- package/dist/esm/types/WebSocketMessageTypes.d.ts.map +1 -0
- package/dist/esm/types/WebSocketMessageTypes.js +77 -0
- package/dist/esm/types/WebSocketMessageTypes.js.map +6 -0
- package/dist/esm/util/matterVersion.d.ts +12 -0
- package/dist/esm/util/matterVersion.d.ts.map +1 -0
- package/dist/esm/util/matterVersion.js +32 -0
- package/dist/esm/util/matterVersion.js.map +6 -0
- package/dist/esm/util/network.d.ts +14 -0
- package/dist/esm/util/network.d.ts.map +1 -0
- package/dist/esm/util/network.js +63 -0
- package/dist/esm/util/network.js.map +6 -0
- package/package.json +45 -0
- package/src/controller/AttributeDataCache.ts +194 -0
- package/src/controller/ControllerCommandHandler.ts +1256 -0
- package/src/controller/LegacyDataInjector.ts +314 -0
- package/src/controller/MatterController.ts +265 -0
- package/src/controller/Nodes.ts +115 -0
- package/src/controller/TestNodeCommandHandler.ts +305 -0
- package/src/data/VendorIDs.ts +1234 -0
- package/src/example/send-command.ts +82 -0
- package/src/index.ts +33 -0
- package/src/model/ModelMapper.ts +87 -0
- package/src/server/ConfigStorage.ts +112 -0
- package/src/server/Converters.ts +483 -0
- package/src/server/WebSocketControllerHandler.ts +917 -0
- package/src/tsconfig.json +7 -0
- package/src/types/CommandHandler.ts +270 -0
- package/src/types/WebServer.ts +14 -0
- package/src/types/WebSocketMessageTypes.ts +525 -0
- package/src/util/matterVersion.ts +45 -0
- package/src/util/network.ts +85 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { AttributeId, ClusterId, CommandId, Duration, EventId, EventNumber, NodeId, Observable } from "@matter/main";
|
|
7
|
+
import { CommissionableDeviceIdentifiers } from "@matter/main/protocol";
|
|
8
|
+
import { EndpointNumber, Status } from "@matter/main/types";
|
|
9
|
+
import { ControllerCommissioningFlowOptions } from "@matter/protocol";
|
|
10
|
+
|
|
11
|
+
export type ReadAttributeRequest = {
|
|
12
|
+
nodeId: NodeId;
|
|
13
|
+
/** Endpoint ID or undefined for wildcard */
|
|
14
|
+
endpointId?: EndpointNumber;
|
|
15
|
+
/** Cluster ID or undefined for wildcard */
|
|
16
|
+
clusterId?: ClusterId;
|
|
17
|
+
/** Attribute ID or undefined for wildcard */
|
|
18
|
+
attributeId?: AttributeId;
|
|
19
|
+
fabricFiltered?: boolean;
|
|
20
|
+
};
|
|
21
|
+
export type AttributeResponseData = {
|
|
22
|
+
clusterId: number;
|
|
23
|
+
attributeId: number;
|
|
24
|
+
endpointId: number;
|
|
25
|
+
dataVersion: number;
|
|
26
|
+
value: unknown;
|
|
27
|
+
};
|
|
28
|
+
export type AttributeResponseStatus = {
|
|
29
|
+
clusterId: number;
|
|
30
|
+
attributeId: number;
|
|
31
|
+
endpointId: number;
|
|
32
|
+
status?: Status;
|
|
33
|
+
clusterStatus?: number;
|
|
34
|
+
};
|
|
35
|
+
export type ReadAttributeResponse = { values: AttributeResponseData[]; status?: AttributeResponseStatus[] };
|
|
36
|
+
|
|
37
|
+
export type ReadByIdRequest = {
|
|
38
|
+
nodeId: NodeId;
|
|
39
|
+
endpointId: EndpointNumber;
|
|
40
|
+
clusterId: ClusterId;
|
|
41
|
+
attributeId: AttributeId;
|
|
42
|
+
fabricFiltered?: boolean;
|
|
43
|
+
};
|
|
44
|
+
export type AttributeErrorResponseData = {
|
|
45
|
+
clusterId: number;
|
|
46
|
+
attributeId: number;
|
|
47
|
+
endpointId: number;
|
|
48
|
+
error: string;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type ReadByIdResponse = AttributeErrorResponseData;
|
|
52
|
+
|
|
53
|
+
export type SubscribeAttributeRequest = ReadAttributeRequest & {
|
|
54
|
+
minInterval: number;
|
|
55
|
+
maxInterval: number;
|
|
56
|
+
changeListener: (data: AttributeResponseData) => void;
|
|
57
|
+
};
|
|
58
|
+
export type SubscribeAttributeResponse = {
|
|
59
|
+
values: AttributeResponseData[];
|
|
60
|
+
updated: Observable<[void]>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type WriteAttributeRequest = {
|
|
64
|
+
nodeId: NodeId;
|
|
65
|
+
endpointId: EndpointNumber;
|
|
66
|
+
clusterId: ClusterId;
|
|
67
|
+
attributeId: AttributeId;
|
|
68
|
+
value: unknown;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type WriteAttributeByIdRequest = {
|
|
72
|
+
nodeId: NodeId;
|
|
73
|
+
endpointId: EndpointNumber;
|
|
74
|
+
clusterId: ClusterId;
|
|
75
|
+
attributeId: AttributeId;
|
|
76
|
+
value: unknown;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export type ReadEventRequest = {
|
|
80
|
+
nodeId: NodeId;
|
|
81
|
+
endpointId: EndpointNumber;
|
|
82
|
+
clusterId: ClusterId;
|
|
83
|
+
eventId: EventId;
|
|
84
|
+
eventMin?: EventNumber;
|
|
85
|
+
};
|
|
86
|
+
export type EventResponseData = {
|
|
87
|
+
clusterId: number;
|
|
88
|
+
eventId: number;
|
|
89
|
+
endpointId: number;
|
|
90
|
+
eventNumber: number | bigint;
|
|
91
|
+
value: unknown;
|
|
92
|
+
};
|
|
93
|
+
export type EventResponseStatus = {
|
|
94
|
+
clusterId: number;
|
|
95
|
+
eventId: number;
|
|
96
|
+
endpointId: number;
|
|
97
|
+
status?: Status;
|
|
98
|
+
clusterStatus?: number;
|
|
99
|
+
};
|
|
100
|
+
export type ReadEventResponse = { values: EventResponseData[]; status?: EventResponseStatus[] };
|
|
101
|
+
|
|
102
|
+
export type SubscribeEventRequest = ReadEventRequest & {
|
|
103
|
+
minInterval: number;
|
|
104
|
+
maxInterval: number;
|
|
105
|
+
changeListener: (data: EventResponseData) => void;
|
|
106
|
+
};
|
|
107
|
+
export type SubscribeEventResponse = {
|
|
108
|
+
values: EventResponseData[];
|
|
109
|
+
updated: Observable<[void]>;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export type InvokeRequest = {
|
|
113
|
+
nodeId: NodeId;
|
|
114
|
+
endpointId: EndpointNumber;
|
|
115
|
+
clusterId: ClusterId;
|
|
116
|
+
commandName: string;
|
|
117
|
+
data: unknown;
|
|
118
|
+
timedInteractionTimeoutMs?: Duration;
|
|
119
|
+
interactionTimeoutMs?: Duration;
|
|
120
|
+
};
|
|
121
|
+
export type InvokeResponse = {
|
|
122
|
+
clusterId: number;
|
|
123
|
+
commandId?: number;
|
|
124
|
+
endpointId: number;
|
|
125
|
+
value?: unknown;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export type InvokeByIdRequest = {
|
|
129
|
+
nodeId: NodeId;
|
|
130
|
+
endpointId: EndpointNumber;
|
|
131
|
+
clusterId: ClusterId;
|
|
132
|
+
commandId: CommandId;
|
|
133
|
+
data: unknown;
|
|
134
|
+
timedInteractionTimeoutMs?: number;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export type DelayRequest = {
|
|
138
|
+
nodeId?: NodeId;
|
|
139
|
+
expireExistingSession?: boolean;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export type CommissioningRequest = {
|
|
143
|
+
nodeId?: NodeId;
|
|
144
|
+
knownAddress?: { ip: string; port: number };
|
|
145
|
+
onNetworkOnly?: boolean;
|
|
146
|
+
wifiCredentials?: ControllerCommissioningFlowOptions["wifiNetwork"];
|
|
147
|
+
threadCredentials?: ControllerCommissioningFlowOptions["threadNetwork"];
|
|
148
|
+
} & (
|
|
149
|
+
| { qrCode: string }
|
|
150
|
+
| { manualCode: string }
|
|
151
|
+
| { passcode: number; vendorId: number; productId: number }
|
|
152
|
+
| { passcode: number; shortDiscriminator: number }
|
|
153
|
+
| { passcode: number; longDiscriminator: number }
|
|
154
|
+
| { passcode: number } // Discover any commissionable device
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
export type CommissioningResponse = {
|
|
158
|
+
nodeId: NodeId;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export type DiscoveryRequest = {
|
|
162
|
+
findBy?: CommissionableDeviceIdentifiers;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export type DiscoveryResponse = {
|
|
166
|
+
commissioningMode: number;
|
|
167
|
+
deviceName: string;
|
|
168
|
+
deviceType: number;
|
|
169
|
+
hostName: string;
|
|
170
|
+
instanceName: string;
|
|
171
|
+
longDiscriminator: number;
|
|
172
|
+
numIPs: number;
|
|
173
|
+
pairingHint: number;
|
|
174
|
+
pairingInstruction: string;
|
|
175
|
+
port: number;
|
|
176
|
+
productId: number;
|
|
177
|
+
rotatingId: string;
|
|
178
|
+
rotatingIdLen: number;
|
|
179
|
+
shortDiscriminator: number;
|
|
180
|
+
supportsTcpClient: boolean;
|
|
181
|
+
supportsTcpServer: boolean;
|
|
182
|
+
vendorId: number;
|
|
183
|
+
addresses?: string[];
|
|
184
|
+
mrpSessionIdleInterval?: number;
|
|
185
|
+
mrpSessionActiveInterval?: number;
|
|
186
|
+
}[];
|
|
187
|
+
|
|
188
|
+
export type RootCertificateResponse = {
|
|
189
|
+
RCAC: Uint8Array;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export type IssueNocChainRequest = {
|
|
193
|
+
elements: Uint8Array;
|
|
194
|
+
nodeId: NodeId;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export type IssueNocChainResponse = {
|
|
198
|
+
ICAC?: Uint8Array;
|
|
199
|
+
IPK: Uint8Array;
|
|
200
|
+
NOC: Uint8Array;
|
|
201
|
+
RCAC: Uint8Array;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
export type OpenCommissioningWindowRequest = {
|
|
205
|
+
nodeId: NodeId;
|
|
206
|
+
timeout?: number;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export type OpenCommissioningWindowResponse = {
|
|
210
|
+
manualCode: string;
|
|
211
|
+
qrCode: string;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
import { AttributesData, MatterNode } from "./WebSocketMessageTypes.js";
|
|
215
|
+
|
|
216
|
+
/** MatterNode details for WebSocket API - re-export from WebSocketMessageTypes */
|
|
217
|
+
export type { AttributesData };
|
|
218
|
+
export type MatterNodeData = MatterNode;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Interface for node command handlers.
|
|
222
|
+
* Both real nodes (ControllerCommandHandler) and test nodes (TestNodeCommandHandler) implement this.
|
|
223
|
+
*/
|
|
224
|
+
export interface NodeCommandHandler {
|
|
225
|
+
/**
|
|
226
|
+
* Check if this handler manages the given node ID.
|
|
227
|
+
*/
|
|
228
|
+
hasNode(nodeId: NodeId): boolean;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Get full node details in WebSocket API format.
|
|
232
|
+
*/
|
|
233
|
+
getNodeDetails(nodeId: NodeId): Promise<MatterNodeData>;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Read multiple attributes from a node by path strings.
|
|
237
|
+
* Handles wildcards in paths (e.g., asterisk/29/asterisk for all descriptor attributes).
|
|
238
|
+
*/
|
|
239
|
+
handleReadAttributes(nodeId: NodeId, attributePaths: string[], fabricFiltered?: boolean): Promise<AttributesData>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Read attributes from a node.
|
|
243
|
+
*/
|
|
244
|
+
handleReadAttribute(data: ReadAttributeRequest): Promise<ReadAttributeResponse>;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Write an attribute to a node.
|
|
248
|
+
*/
|
|
249
|
+
handleWriteAttribute(data: WriteAttributeRequest): Promise<AttributeResponseStatus>;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Invoke a command on a node.
|
|
253
|
+
*/
|
|
254
|
+
handleInvoke(data: InvokeRequest): Promise<unknown>;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Get IP addresses for a node.
|
|
258
|
+
*/
|
|
259
|
+
getNodeIpAddresses(nodeId: NodeId, preferCache?: boolean): Promise<string[]>;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Ping a node.
|
|
263
|
+
*/
|
|
264
|
+
pingNode(nodeId: NodeId, attempts?: number): Promise<Record<string, boolean>>;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Remove/decommission a node.
|
|
268
|
+
*/
|
|
269
|
+
removeNode(nodeId: NodeId): Promise<void>;
|
|
270
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { type createServer } from "node:http";
|
|
8
|
+
|
|
9
|
+
export type HttpServer = ReturnType<typeof createServer>;
|
|
10
|
+
|
|
11
|
+
export interface WebServerHandler {
|
|
12
|
+
register(server: HttpServer): Promise<void>;
|
|
13
|
+
unregister(): Promise<void>;
|
|
14
|
+
}
|