1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
import { NodeId } from "@matter/main";
import type { CommissioningController } from "@project-chip/matter.js";
import { NodeStates, type PairedNode } from "@project-chip/matter.js/device";
import { Log } from "./logging.js";
const log = new Log("device");
export function nodeStateName(state: NodeStates): string {
switch (state) {
case NodeStates.Connected:
return "connected";
case NodeStates.Disconnected:
return "disconnected";
case NodeStates.Reconnecting:
return "reconnecting";
case NodeStates.WaitingForDeviceDiscovery:
return "waiting for device discovery";
}
}
/**
* Connects to the commissioned node using operational discovery (DNS-SD by
* node identity, never a stored IP address) and waits until the node is fully
* initialized from the device.
*
* The returned PairedNode keeps reconnecting in the background; observe
* `events.stateChanged` for connectivity transitions.
*/
export async function connectDevice(
controller: CommissioningController,
nodeId: bigint,
timeoutMs = 60_000,
): Promise<PairedNode> {
const node = await controller.getNode(NodeId(nodeId));
node.events.stateChanged.on(state => {
log.debug(`Node ${nodeId} state: ${nodeStateName(state)}`);
});
if (!node.initialized) {
log.info(`Connecting to Matter node ${nodeId}...`);
node.connect();
await waitForInitialization(node, nodeId, timeoutMs);
} else if (!node.isConnected) {
node.connect();
await waitForInitialization(node, nodeId, timeoutMs);
}
log.info(`Connected to Matter node ${nodeId}`);
return node;
}
async function waitForInitialization(node: PairedNode, nodeId: bigint, timeoutMs: number): Promise<void> {
let timer: NodeJS.Timeout | undefined;
const timeout = new Promise<never>((_, reject) => {
timer = setTimeout(
() =>
reject(
new Error(
`Timed out after ${Math.round(timeoutMs / 1000)}s waiting for node ${nodeId}. ` +
`The device may be offline or unreachable over IPv6.`,
),
),
timeoutMs,
);
});
try {
await Promise.race([node.events.initializedFromRemote, timeout]);
} finally {
clearTimeout(timer);
}
}
|