@matter-server/ws-client 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 +165 -0
- package/dist/esm/client.d.ts +67 -0
- package/dist/esm/client.d.ts.map +1 -0
- package/dist/esm/client.js +286 -0
- package/dist/esm/client.js.map +6 -0
- package/dist/esm/connection.d.ts +40 -0
- package/dist/esm/connection.d.ts.map +1 -0
- package/dist/esm/connection.js +75 -0
- package/dist/esm/connection.js.map +6 -0
- package/dist/esm/exceptions.d.ts +10 -0
- package/dist/esm/exceptions.d.ts.map +1 -0
- package/dist/esm/exceptions.js +14 -0
- package/dist/esm/exceptions.js.map +6 -0
- package/dist/esm/index.d.ts +15 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +6 -0
- package/dist/esm/json-utils.d.ts +19 -0
- package/dist/esm/json-utils.d.ts.map +1 -0
- package/dist/esm/json-utils.js +50 -0
- package/dist/esm/json-utils.js.map +6 -0
- package/dist/esm/models/model.d.ts +379 -0
- package/dist/esm/models/model.d.ts.map +1 -0
- package/dist/esm/models/model.js +15 -0
- package/dist/esm/models/model.js.map +6 -0
- package/dist/esm/models/node.d.ts +40 -0
- package/dist/esm/models/node.d.ts.map +1 -0
- package/dist/esm/models/node.js +59 -0
- package/dist/esm/models/node.js.map +6 -0
- package/dist/esm/package.json +3 -0
- package/package.json +38 -0
- package/src/client.ts +405 -0
- package/src/connection.ts +103 -0
- package/src/exceptions.ts +9 -0
- package/src/index.ts +25 -0
- package/src/json-utils.ts +75 -0
- package/src/models/model.ts +344 -0
- package/src/models/node.ts +75 -0
- package/src/tsconfig.json +7 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { MatterNode } from "./node.js";
|
|
8
|
+
|
|
9
|
+
/** Attribute data stored as path -> value mapping */
|
|
10
|
+
export type AttributesData = { [key: string]: unknown };
|
|
11
|
+
|
|
12
|
+
export interface APICommands {
|
|
13
|
+
start_listening: {
|
|
14
|
+
requestArgs: Record<string, never>;
|
|
15
|
+
response: Array<MatterNode>;
|
|
16
|
+
};
|
|
17
|
+
diagnostics: {
|
|
18
|
+
requestArgs: Record<string, never>;
|
|
19
|
+
response: {
|
|
20
|
+
info: ServerInfoMessage;
|
|
21
|
+
nodes: Array<MatterNode>;
|
|
22
|
+
events: Array<MatterNodeEvent>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
server_info: {
|
|
26
|
+
requestArgs: Record<string, never>;
|
|
27
|
+
response: ServerInfoMessage;
|
|
28
|
+
};
|
|
29
|
+
get_nodes: {
|
|
30
|
+
requestArgs: { only_available?: boolean };
|
|
31
|
+
response: Array<MatterNode>;
|
|
32
|
+
};
|
|
33
|
+
get_node: {
|
|
34
|
+
requestArgs: { node_id: number | bigint };
|
|
35
|
+
response: MatterNode;
|
|
36
|
+
};
|
|
37
|
+
commission_with_code: {
|
|
38
|
+
requestArgs: { code: string; network_only?: boolean };
|
|
39
|
+
response: MatterNode;
|
|
40
|
+
};
|
|
41
|
+
commission_on_network: {
|
|
42
|
+
requestArgs: {
|
|
43
|
+
setup_pin_code: number;
|
|
44
|
+
filter_type?: number;
|
|
45
|
+
filter?: number;
|
|
46
|
+
ip_addr?: string;
|
|
47
|
+
};
|
|
48
|
+
response: MatterNode;
|
|
49
|
+
};
|
|
50
|
+
set_wifi_credentials: {
|
|
51
|
+
requestArgs: { ssid: string; credentials: string };
|
|
52
|
+
response: Record<string, never>;
|
|
53
|
+
};
|
|
54
|
+
set_thread_dataset: {
|
|
55
|
+
requestArgs: { dataset: string };
|
|
56
|
+
response: Record<string, never>;
|
|
57
|
+
};
|
|
58
|
+
open_commissioning_window: {
|
|
59
|
+
requestArgs: {
|
|
60
|
+
node_id: number | bigint;
|
|
61
|
+
timeout?: number;
|
|
62
|
+
iteration?: number;
|
|
63
|
+
option?: number;
|
|
64
|
+
discriminator?: number | null;
|
|
65
|
+
};
|
|
66
|
+
response: CommissioningParameters;
|
|
67
|
+
};
|
|
68
|
+
discover: {
|
|
69
|
+
requestArgs: Record<string, never>;
|
|
70
|
+
response: CommissionableNodeData[];
|
|
71
|
+
};
|
|
72
|
+
interview_node: {
|
|
73
|
+
requestArgs: { node_id: number | bigint };
|
|
74
|
+
response: null;
|
|
75
|
+
};
|
|
76
|
+
device_command: {
|
|
77
|
+
requestArgs: {
|
|
78
|
+
node_id: number | bigint;
|
|
79
|
+
endpoint_id: number;
|
|
80
|
+
cluster_id: number;
|
|
81
|
+
command_name: string;
|
|
82
|
+
payload: unknown;
|
|
83
|
+
response_type: unknown;
|
|
84
|
+
timed_request_timeout_ms?: number | null;
|
|
85
|
+
interaction_timeout_ms?: number | null;
|
|
86
|
+
};
|
|
87
|
+
response: unknown;
|
|
88
|
+
};
|
|
89
|
+
remove_node: {
|
|
90
|
+
requestArgs: { node_id: number | bigint };
|
|
91
|
+
response: null;
|
|
92
|
+
};
|
|
93
|
+
get_vendor_names: {
|
|
94
|
+
requestArgs: { filter_vendors?: Array<number> };
|
|
95
|
+
response: { [key: string]: string };
|
|
96
|
+
};
|
|
97
|
+
subscribe_attribute: {
|
|
98
|
+
requestArgs: Record<string, never>;
|
|
99
|
+
response: Record<string, never>;
|
|
100
|
+
};
|
|
101
|
+
read_attribute: {
|
|
102
|
+
requestArgs: {
|
|
103
|
+
node_id: number | bigint;
|
|
104
|
+
attribute_path: string | string[];
|
|
105
|
+
fabric_filtered?: boolean;
|
|
106
|
+
};
|
|
107
|
+
response: AttributesData;
|
|
108
|
+
};
|
|
109
|
+
write_attribute: {
|
|
110
|
+
requestArgs: {
|
|
111
|
+
node_id: number | bigint;
|
|
112
|
+
attribute_path: string;
|
|
113
|
+
value: unknown;
|
|
114
|
+
};
|
|
115
|
+
response: Array<{
|
|
116
|
+
Path: { EndpointId: number; ClusterId: number; AttributeId: number };
|
|
117
|
+
Status: number;
|
|
118
|
+
}>;
|
|
119
|
+
};
|
|
120
|
+
ping_node: {
|
|
121
|
+
requestArgs: { node_id: number | bigint; attempts?: number };
|
|
122
|
+
response: NodePingResult;
|
|
123
|
+
};
|
|
124
|
+
import_test_node: {
|
|
125
|
+
requestArgs: { dump: string };
|
|
126
|
+
response: null;
|
|
127
|
+
};
|
|
128
|
+
get_node_ip_addresses: {
|
|
129
|
+
requestArgs: { node_id: number | bigint; prefer_cache?: boolean; scoped?: boolean };
|
|
130
|
+
response: Array<string>;
|
|
131
|
+
};
|
|
132
|
+
check_node_update: {
|
|
133
|
+
requestArgs: { node_id: number | bigint };
|
|
134
|
+
response: MatterSoftwareVersion | null;
|
|
135
|
+
};
|
|
136
|
+
update_node: {
|
|
137
|
+
requestArgs: { node_id: number | bigint; software_version: number | string };
|
|
138
|
+
response: MatterSoftwareVersion | null;
|
|
139
|
+
};
|
|
140
|
+
discover_commissionable_nodes: {
|
|
141
|
+
requestArgs: Record<string, never>;
|
|
142
|
+
response: CommissionableNodeData[];
|
|
143
|
+
};
|
|
144
|
+
get_matter_fabrics: {
|
|
145
|
+
requestArgs: { node_id: number | bigint };
|
|
146
|
+
response: MatterFabricData[];
|
|
147
|
+
};
|
|
148
|
+
remove_matter_fabric: {
|
|
149
|
+
requestArgs: { node_id: number | bigint; fabric_index: number };
|
|
150
|
+
response: Record<string, never>;
|
|
151
|
+
};
|
|
152
|
+
set_acl_entry: {
|
|
153
|
+
requestArgs: { node_id: number | bigint; entry: AccessControlEntry[] };
|
|
154
|
+
response: AttributeWriteResult[] | null;
|
|
155
|
+
};
|
|
156
|
+
set_node_binding: {
|
|
157
|
+
requestArgs: { node_id: number | bigint; endpoint: number; bindings: BindingTarget[] };
|
|
158
|
+
response: AttributeWriteResult[] | null;
|
|
159
|
+
};
|
|
160
|
+
set_default_fabric_label: {
|
|
161
|
+
requestArgs: { label: string | null };
|
|
162
|
+
response: Record<string, never>;
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Access Control Entry for set_acl_entry command */
|
|
167
|
+
export interface AccessControlEntry {
|
|
168
|
+
privilege: number;
|
|
169
|
+
auth_mode: number;
|
|
170
|
+
subjects: Array<number | bigint> | null;
|
|
171
|
+
targets: AccessControlTarget[] | null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface AccessControlTarget {
|
|
175
|
+
cluster: number | null;
|
|
176
|
+
endpoint: number | null;
|
|
177
|
+
device_type: number | null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Binding target for set_node_binding command */
|
|
181
|
+
export interface BindingTarget {
|
|
182
|
+
node: number | bigint | null;
|
|
183
|
+
group: number | null;
|
|
184
|
+
endpoint: number | null;
|
|
185
|
+
cluster: number | null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Attribute write result for set_acl_entry and set_node_binding responses */
|
|
189
|
+
export interface AttributeWriteResult {
|
|
190
|
+
path: { endpoint_id: number; cluster_id: number; attribute_id: number };
|
|
191
|
+
status: number;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Matter node event structure */
|
|
195
|
+
export interface MatterNodeEvent {
|
|
196
|
+
node_id: number | bigint;
|
|
197
|
+
endpoint_id: number;
|
|
198
|
+
cluster_id: number;
|
|
199
|
+
event_id: number;
|
|
200
|
+
event_number: number | bigint;
|
|
201
|
+
priority: number;
|
|
202
|
+
timestamp: number | bigint;
|
|
203
|
+
timestamp_type: number;
|
|
204
|
+
data: unknown | null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface CommandMessage {
|
|
208
|
+
message_id: string;
|
|
209
|
+
command: keyof APICommands;
|
|
210
|
+
args?: APICommands[keyof APICommands]["requestArgs"];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface ServerInfoMessage {
|
|
214
|
+
fabric_id: number | bigint;
|
|
215
|
+
compressed_fabric_id: number | bigint;
|
|
216
|
+
schema_version: number;
|
|
217
|
+
min_supported_schema_version: number;
|
|
218
|
+
sdk_version: string;
|
|
219
|
+
wifi_credentials_set: boolean;
|
|
220
|
+
thread_credentials_set: boolean;
|
|
221
|
+
bluetooth_enabled: boolean;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
interface ServerEventNodeAdded {
|
|
225
|
+
event: "node_added";
|
|
226
|
+
data: MatterNode;
|
|
227
|
+
}
|
|
228
|
+
interface ServerEventNodeUpdated {
|
|
229
|
+
event: "node_updated";
|
|
230
|
+
data: MatterNode;
|
|
231
|
+
}
|
|
232
|
+
interface ServerEventNodeRemoved {
|
|
233
|
+
event: "node_removed";
|
|
234
|
+
data: number | bigint;
|
|
235
|
+
}
|
|
236
|
+
interface ServerEventNodeEvent {
|
|
237
|
+
event: "node_event";
|
|
238
|
+
data: MatterNodeEvent;
|
|
239
|
+
}
|
|
240
|
+
interface ServerEventAttributeUpdated {
|
|
241
|
+
event: "attribute_updated";
|
|
242
|
+
data: [number | bigint, string, unknown];
|
|
243
|
+
}
|
|
244
|
+
interface ServerEventServerShutdown {
|
|
245
|
+
event: "server_shutdown";
|
|
246
|
+
data: Record<string, never>;
|
|
247
|
+
}
|
|
248
|
+
interface ServerEventEndpointAdded {
|
|
249
|
+
event: "endpoint_added";
|
|
250
|
+
data: { node_id: number | bigint; endpoint_id: number };
|
|
251
|
+
}
|
|
252
|
+
interface ServerEventEndpointRemoved {
|
|
253
|
+
event: "endpoint_removed";
|
|
254
|
+
data: { node_id: number | bigint; endpoint_id: number };
|
|
255
|
+
}
|
|
256
|
+
interface ServerEventInfoUpdated {
|
|
257
|
+
event: "server_info_updated";
|
|
258
|
+
data: ServerInfoMessage;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export type EventMessage =
|
|
262
|
+
| ServerEventNodeAdded
|
|
263
|
+
| ServerEventNodeUpdated
|
|
264
|
+
| ServerEventNodeRemoved
|
|
265
|
+
| ServerEventNodeEvent
|
|
266
|
+
| ServerEventAttributeUpdated
|
|
267
|
+
| ServerEventServerShutdown
|
|
268
|
+
| ServerEventEndpointAdded
|
|
269
|
+
| ServerEventEndpointRemoved
|
|
270
|
+
| ServerEventInfoUpdated;
|
|
271
|
+
|
|
272
|
+
export interface ResultMessageBase {
|
|
273
|
+
message_id: string;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface ErrorResultMessage extends ResultMessageBase {
|
|
277
|
+
error_code: number;
|
|
278
|
+
details?: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface SuccessResultMessage extends ResultMessageBase {
|
|
282
|
+
result: unknown;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface WebSocketConfig {
|
|
286
|
+
host: string;
|
|
287
|
+
port: string;
|
|
288
|
+
scheme: string;
|
|
289
|
+
path: string;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export enum UpdateSource {
|
|
293
|
+
MAIN_NET_DCL = "main-net-dcl",
|
|
294
|
+
TEST_NET_DCL = "test-net-dcl",
|
|
295
|
+
LOCAL = "local",
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export interface MatterSoftwareVersion {
|
|
299
|
+
vid: number;
|
|
300
|
+
pid: number;
|
|
301
|
+
software_version: number;
|
|
302
|
+
software_version_string: string;
|
|
303
|
+
firmware_information?: string;
|
|
304
|
+
min_applicable_software_version: number;
|
|
305
|
+
max_applicable_software_version: number;
|
|
306
|
+
release_notes_url?: string;
|
|
307
|
+
update_source: UpdateSource;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export interface CommissioningParameters {
|
|
311
|
+
setup_pin_code: number;
|
|
312
|
+
setup_manual_code: string;
|
|
313
|
+
setup_qr_code: string;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export interface CommissionableNodeData {
|
|
317
|
+
instance_name?: string;
|
|
318
|
+
host_name?: string;
|
|
319
|
+
port?: number;
|
|
320
|
+
long_discriminator?: number;
|
|
321
|
+
vendor_id?: number;
|
|
322
|
+
product_id?: number;
|
|
323
|
+
commissioning_mode?: number;
|
|
324
|
+
device_type?: number;
|
|
325
|
+
device_name?: string;
|
|
326
|
+
pairing_instruction?: string;
|
|
327
|
+
pairing_hint?: number;
|
|
328
|
+
mrp_retry_interval_idle?: number;
|
|
329
|
+
mrp_retry_interval_active?: number;
|
|
330
|
+
supports_tcp?: boolean;
|
|
331
|
+
addresses?: string[];
|
|
332
|
+
rotating_id?: string;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export interface MatterFabricData {
|
|
336
|
+
fabric_id?: number | bigint;
|
|
337
|
+
vendor_id?: number;
|
|
338
|
+
fabric_index?: number;
|
|
339
|
+
fabric_label?: string;
|
|
340
|
+
vendor_name?: string;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export type NotificationType = "success" | "info" | "warning" | "error";
|
|
344
|
+
export type NodePingResult = Record<string, boolean>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Raw node data from server */
|
|
8
|
+
export interface MatterNodeData {
|
|
9
|
+
node_id: number | bigint;
|
|
10
|
+
date_commissioned: string;
|
|
11
|
+
last_interview: string;
|
|
12
|
+
interview_version: number;
|
|
13
|
+
available: boolean;
|
|
14
|
+
is_bridge: boolean;
|
|
15
|
+
attributes: { [key: string]: unknown };
|
|
16
|
+
attribute_subscriptions: Array<[number | null, number | null, number | null]>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class MatterNode {
|
|
20
|
+
node_id: number | bigint;
|
|
21
|
+
date_commissioned: string;
|
|
22
|
+
last_interview: string;
|
|
23
|
+
interview_version: number;
|
|
24
|
+
available: boolean;
|
|
25
|
+
is_bridge: boolean;
|
|
26
|
+
attributes: { [key: string]: unknown };
|
|
27
|
+
attribute_subscriptions: Array<[number | null, number | null, number | null]>;
|
|
28
|
+
|
|
29
|
+
constructor(public data: MatterNodeData) {
|
|
30
|
+
this.node_id = data.node_id;
|
|
31
|
+
this.date_commissioned = data.date_commissioned;
|
|
32
|
+
this.last_interview = data.last_interview;
|
|
33
|
+
this.interview_version = data.interview_version;
|
|
34
|
+
this.available = data.available;
|
|
35
|
+
this.is_bridge = data.is_bridge;
|
|
36
|
+
this.attributes = data.attributes;
|
|
37
|
+
this.attribute_subscriptions = data.attribute_subscriptions;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get nodeLabel(): string {
|
|
41
|
+
const label = this.attributes["0/40/5"];
|
|
42
|
+
if (typeof label !== "string") return "";
|
|
43
|
+
if (label.includes("\u0000\u0000")) return "";
|
|
44
|
+
return label.trim();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get vendorName(): string {
|
|
48
|
+
const value = this.attributes["0/40/1"];
|
|
49
|
+
return typeof value === "string" ? value : "";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get productName(): string {
|
|
53
|
+
const value = this.attributes["0/40/3"];
|
|
54
|
+
return typeof value === "string" ? value : "";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get serialNumber(): string {
|
|
58
|
+
const value = this.attributes["0/40/15"];
|
|
59
|
+
return typeof value === "string" ? value : "";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get updateState(): number | undefined {
|
|
63
|
+
const value = this.attributes["0/42/2"];
|
|
64
|
+
return typeof value === "number" ? value : undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get updateStateProgress(): number | undefined {
|
|
68
|
+
const value = this.attributes["0/42/3"];
|
|
69
|
+
return typeof value === "number" ? value : undefined;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
update(data: Partial<MatterNodeData>): MatterNode {
|
|
73
|
+
return new MatterNode({ ...this.data, ...data });
|
|
74
|
+
}
|
|
75
|
+
}
|