@project-chip/matter-node.js-examples 0.11.0-alpha.0-20240911-db8f7c80 → 0.11.0-alpha.0-20241007-547af42a8
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +3 -271
- package/dist/esm/examples/BridgedDevicesNodeLegacy.js +5 -4
- package/dist/esm/examples/BridgedDevicesNodeLegacy.js.map +1 -2
- package/dist/esm/examples/ComposedDeviceNodeLegacy.js +4 -3
- package/dist/esm/examples/ComposedDeviceNodeLegacy.js.map +1 -2
- package/dist/esm/examples/ControllerNodeLegacy.js +7 -6
- package/dist/esm/examples/ControllerNodeLegacy.js.map +1 -2
- package/dist/esm/examples/DeviceNodeFullLegacy.js +8 -6
- package/dist/esm/examples/DeviceNodeFullLegacy.js.map +1 -2
- package/dist/esm/examples/LegacyStorageConverter.js +2 -2
- package/dist/esm/examples/LegacyStorageConverter.js.map +0 -1
- package/dist/esm/examples/MultiDeviceNodeLegacy.js +5 -4
- package/dist/esm/examples/MultiDeviceNodeLegacy.js.map +1 -2
- package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.js +7 -6
- package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.js.map +1 -2
- package/dist/esm/package.json +3 -0
- package/package.json +16 -37
- package/src/examples/BridgedDevicesNodeLegacy.ts +4 -3
- package/src/examples/ComposedDeviceNodeLegacy.ts +4 -3
- package/src/examples/ControllerNodeLegacy.ts +6 -5
- package/src/examples/DeviceNodeFullLegacy.ts +7 -5
- package/src/examples/LegacyStorageConverter.ts +2 -2
- package/src/examples/MultiDeviceNodeLegacy.ts +4 -4
- package/src/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.ts +7 -6
- package/src/tsconfig.json +13 -13
- package/dist/esm/examples/BridgedDevicesNode.js +0 -144
- package/dist/esm/examples/BridgedDevicesNode.js.map +0 -7
- package/dist/esm/examples/ComposedDeviceNode.js +0 -123
- package/dist/esm/examples/ComposedDeviceNode.js.map +0 -7
- package/dist/esm/examples/ControllerNode.js +0 -194
- package/dist/esm/examples/ControllerNode.js.map +0 -7
- package/dist/esm/examples/DeviceNode.js +0 -127
- package/dist/esm/examples/DeviceNode.js.map +0 -7
- package/dist/esm/examples/DeviceNodeFull.js +0 -253
- package/dist/esm/examples/DeviceNodeFull.js.map +0 -7
- package/dist/esm/examples/IlluminatedRollerShade.js +0 -60
- package/dist/esm/examples/IlluminatedRollerShade.js.map +0 -7
- package/dist/esm/examples/LightDevice.js +0 -35
- package/dist/esm/examples/LightDevice.js.map +0 -7
- package/dist/esm/examples/MultiDeviceNode.js +0 -140
- package/dist/esm/examples/MultiDeviceNode.js.map +0 -7
- package/dist/esm/examples/SensorDeviceNode.js +0 -175
- package/dist/esm/examples/SensorDeviceNode.js.map +0 -7
- package/dist/esm/examples/cluster/DummyThreadNetworkCommissioningServer.js +0 -121
- package/dist/esm/examples/cluster/DummyThreadNetworkCommissioningServer.js.map +0 -7
- package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServer.js +0 -121
- package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServer.js.map +0 -7
- package/dist/esm/examples/cluster/MyFancyOwnFunctionality.js +0 -110
- package/dist/esm/examples/cluster/MyFancyOwnFunctionality.js.map +0 -7
- package/dist/esm/tutorial/example01.js +0 -5
- package/dist/esm/tutorial/example01.js.map +0 -7
- package/dist/esm/tutorial/example02.js +0 -7
- package/dist/esm/tutorial/example02.js.map +0 -7
- package/dist/esm/tutorial/example03.js +0 -15
- package/dist/esm/tutorial/example03.js.map +0 -7
- package/dist/esm/tutorial/example04.js +0 -10
- package/dist/esm/tutorial/example04.js.map +0 -7
- package/dist/esm/tutorial/example05.js +0 -14
- package/dist/esm/tutorial/example05.js.map +0 -7
- package/src/examples/BridgedDevicesNode.ts +0 -259
- package/src/examples/ComposedDeviceNode.ts +0 -196
- package/src/examples/ControllerNode.ts +0 -314
- package/src/examples/DeviceNode.ts +0 -201
- package/src/examples/DeviceNodeFull.ts +0 -440
- package/src/examples/IlluminatedRollerShade.ts +0 -96
- package/src/examples/LightDevice.ts +0 -61
- package/src/examples/MultiDeviceNode.ts +0 -208
- package/src/examples/SensorDeviceNode.ts +0 -247
- package/src/examples/cluster/DummyThreadNetworkCommissioningServer.ts +0 -156
- package/src/examples/cluster/DummyWifiNetworkCommissioningServer.ts +0 -154
- package/src/examples/cluster/MyFancyOwnFunctionality.ts +0 -185
- package/src/tutorial/example01.ts +0 -6
- package/src/tutorial/example02.ts +0 -9
- package/src/tutorial/example03.ts +0 -19
- package/src/tutorial/example04.ts +0 -13
- package/src/tutorial/example05.ts +0 -19
@@ -1,144 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
/**
|
3
|
-
* @license
|
4
|
-
* Copyright 2022-2024 Matter.js Authors
|
5
|
-
* SPDX-License-Identifier: Apache-2.0
|
6
|
-
*/
|
7
|
-
import { requireMinNodeVersion } from "@project-chip/matter.js-nodejs";
|
8
|
-
import { Time } from "@project-chip/matter.js-general";
|
9
|
-
import { BridgedDeviceBasicInformationServer } from "@project-chip/matter.js/behavior/definitions/bridged-device-basic-information";
|
10
|
-
import { VendorId } from "@project-chip/matter.js/datatype";
|
11
|
-
import { logEndpoint } from "@project-chip/matter.js/device";
|
12
|
-
import { OnOffLightDevice } from "@project-chip/matter.js/devices/OnOffLightDevice";
|
13
|
-
import { OnOffPlugInUnitDevice } from "@project-chip/matter.js/devices/OnOffPlugInUnitDevice";
|
14
|
-
import { Endpoint, EndpointServer } from "@project-chip/matter.js/endpoint";
|
15
|
-
import { AggregatorEndpoint } from "@project-chip/matter.js/endpoints/AggregatorEndpoint";
|
16
|
-
import { Environment, StorageService } from "@project-chip/matter.js/environment";
|
17
|
-
import { ServerNode } from "@project-chip/matter.js/node";
|
18
|
-
import { execSync } from "child_process";
|
19
|
-
requireMinNodeVersion(16);
|
20
|
-
const { isSocket, deviceName, vendorName, passcode, discriminator, vendorId, productName, productId, port, uniqueId } = await getConfiguration();
|
21
|
-
const server = await ServerNode.create({
|
22
|
-
// Required: Give the Node a unique ID which is used to store the state of this node
|
23
|
-
id: uniqueId,
|
24
|
-
// Provide Network relevant configuration like the port
|
25
|
-
// Optional when operating only one device on a host, Default port is 5540
|
26
|
-
network: {
|
27
|
-
port
|
28
|
-
},
|
29
|
-
// Provide Commissioning relevant settings
|
30
|
-
// Optional for development/testing purposes
|
31
|
-
commissioning: {
|
32
|
-
passcode,
|
33
|
-
discriminator
|
34
|
-
},
|
35
|
-
// Provide Node announcement settings
|
36
|
-
// Optional: If Ommitted some development defaults are used
|
37
|
-
productDescription: {
|
38
|
-
name: deviceName,
|
39
|
-
deviceType: AggregatorEndpoint.deviceType
|
40
|
-
},
|
41
|
-
// Provide defaults for the BasicInformation cluster on the Root endpoint
|
42
|
-
// Optional: If Omitted some development defaults are used
|
43
|
-
basicInformation: {
|
44
|
-
vendorName,
|
45
|
-
vendorId: VendorId(vendorId),
|
46
|
-
nodeLabel: productName,
|
47
|
-
productName,
|
48
|
-
productLabel: productName,
|
49
|
-
productId,
|
50
|
-
serialNumber: `matterjs-${uniqueId}`,
|
51
|
-
uniqueId
|
52
|
-
}
|
53
|
-
});
|
54
|
-
const aggregator = new Endpoint(AggregatorEndpoint, { id: "aggregator" });
|
55
|
-
await server.add(aggregator);
|
56
|
-
for (let idx = 0; idx < isSocket.length; idx++) {
|
57
|
-
const i = idx + 1;
|
58
|
-
const isASocket = isSocket[idx];
|
59
|
-
const name = `OnOff ${isASocket ? "Socket" : "Light"} ${i}`;
|
60
|
-
const endpoint = new Endpoint(
|
61
|
-
isASocket ? (
|
62
|
-
// For a Bridged Device we need to add a BridgedDeviceBasicInformation cluster as server
|
63
|
-
OnOffPlugInUnitDevice.with(BridgedDeviceBasicInformationServer)
|
64
|
-
) : OnOffLightDevice.with(BridgedDeviceBasicInformationServer),
|
65
|
-
{
|
66
|
-
id: `onoff-${i}`,
|
67
|
-
bridgedDeviceBasicInformation: {
|
68
|
-
nodeLabel: name,
|
69
|
-
// Main end user name for the device
|
70
|
-
productName: name,
|
71
|
-
productLabel: name,
|
72
|
-
serialNumber: `node-matter-${uniqueId}-${i}`,
|
73
|
-
reachable: true
|
74
|
-
}
|
75
|
-
}
|
76
|
-
);
|
77
|
-
await aggregator.add(endpoint);
|
78
|
-
endpoint.events.identify.startIdentifying.on(() => {
|
79
|
-
console.log(`Run identify logic for ${name}, ideally blink a light every 0.5s ...`);
|
80
|
-
});
|
81
|
-
endpoint.events.identify.stopIdentifying.on(() => {
|
82
|
-
console.log(`Stop identify logic for ${name} ...`);
|
83
|
-
});
|
84
|
-
endpoint.events.onOff.onOff$Changed.on((value) => {
|
85
|
-
executeCommand(value ? `on${i}` : `off${i}`);
|
86
|
-
console.log(`${name} is now ${value ? "ON" : "OFF"}`);
|
87
|
-
});
|
88
|
-
}
|
89
|
-
await server.start();
|
90
|
-
logEndpoint(EndpointServer.forEndpoint(server));
|
91
|
-
function executeCommand(scriptParamName) {
|
92
|
-
const script = Environment.default.vars.string(scriptParamName);
|
93
|
-
if (script === void 0) return void 0;
|
94
|
-
console.log(`${scriptParamName}: ${execSync(script).toString().slice(0, -1)}`);
|
95
|
-
}
|
96
|
-
async function getConfiguration() {
|
97
|
-
const environment = Environment.default;
|
98
|
-
const storageService = environment.get(StorageService);
|
99
|
-
console.log(`Storage location: ${storageService.location} (Directory)`);
|
100
|
-
console.log(
|
101
|
-
'Use the parameter "--storage-path=NAME-OR-PATH" to specify a different storage location in this directory, use --storage-clear to start with an empty storage.'
|
102
|
-
);
|
103
|
-
const deviceStorage = (await storageService.open("device")).createContext("data");
|
104
|
-
const isSocket2 = Array();
|
105
|
-
const numDevices = environment.vars.number("num") || 2;
|
106
|
-
if (await deviceStorage.has("isSocket")) {
|
107
|
-
console.log(`Device types found in storage. --type parameter is ignored.`);
|
108
|
-
(await deviceStorage.get("isSocket")).forEach((type) => isSocket2.push(type));
|
109
|
-
}
|
110
|
-
for (let i = 1; i <= numDevices; i++) {
|
111
|
-
if (isSocket2[i - 1] !== void 0) continue;
|
112
|
-
isSocket2.push(environment.vars.string(`type${i}`) === "socket");
|
113
|
-
}
|
114
|
-
const deviceName2 = "Matter test device";
|
115
|
-
const vendorName2 = "matter-node.js";
|
116
|
-
const passcode2 = environment.vars.number("passcode") ?? await deviceStorage.get("passcode", 20202021);
|
117
|
-
const discriminator2 = environment.vars.number("discriminator") ?? await deviceStorage.get("discriminator", 3840);
|
118
|
-
const vendorId2 = environment.vars.number("vendorid") ?? await deviceStorage.get("vendorid", 65521);
|
119
|
-
const productName2 = `node-matter OnOff ${isSocket2 ? "Socket" : "Light"}`;
|
120
|
-
const productId2 = environment.vars.number("productid") ?? await deviceStorage.get("productid", 32768);
|
121
|
-
const port2 = environment.vars.number("port") ?? 5540;
|
122
|
-
const uniqueId2 = environment.vars.string("uniqueid") ?? await deviceStorage.get("uniqueid", Time.nowMs().toString());
|
123
|
-
await deviceStorage.set({
|
124
|
-
passcode: passcode2,
|
125
|
-
discriminator: discriminator2,
|
126
|
-
vendorid: vendorId2,
|
127
|
-
productid: productId2,
|
128
|
-
isSocket: isSocket2,
|
129
|
-
uniqueid: uniqueId2
|
130
|
-
});
|
131
|
-
return {
|
132
|
-
isSocket: isSocket2,
|
133
|
-
deviceName: deviceName2,
|
134
|
-
vendorName: vendorName2,
|
135
|
-
passcode: passcode2,
|
136
|
-
discriminator: discriminator2,
|
137
|
-
vendorId: vendorId2,
|
138
|
-
productName: productName2,
|
139
|
-
productId: productId2,
|
140
|
-
port: port2,
|
141
|
-
uniqueId: uniqueId2
|
142
|
-
};
|
143
|
-
}
|
144
|
-
//# sourceMappingURL=BridgedDevicesNode.js.map
|
@@ -1,7 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"version": 3,
|
3
|
-
"sources": ["../../../src/examples/BridgedDevicesNode.ts"],
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * This example shows how to create a new device node that is composed of multiple devices.\n * It creates multiple endpoints on the server. For information on how to add a composed device to a bridge please\n * refer to the bridge example!\n * It can be used as CLI script and starting point for your own device node implementation.\n */\n\n/**\n * Import needed modules from @project-chip/matter-node.js\n */\n// Include this first to auto-register Crypto, Network and Time Node.js implementations\nimport { requireMinNodeVersion } from \"@project-chip/matter.js-nodejs\";\n\nimport { Time } from \"@project-chip/matter.js-general\";\nimport { BridgedDeviceBasicInformationServer } from \"@project-chip/matter.js/behavior/definitions/bridged-device-basic-information\";\nimport { VendorId } from \"@project-chip/matter.js/datatype\";\nimport { logEndpoint } from \"@project-chip/matter.js/device\";\nimport { OnOffLightDevice } from \"@project-chip/matter.js/devices/OnOffLightDevice\";\nimport { OnOffPlugInUnitDevice } from \"@project-chip/matter.js/devices/OnOffPlugInUnitDevice\";\nimport { Endpoint, EndpointServer } from \"@project-chip/matter.js/endpoint\";\nimport { AggregatorEndpoint } from \"@project-chip/matter.js/endpoints/AggregatorEndpoint\";\nimport { Environment, StorageService } from \"@project-chip/matter.js/environment\";\nimport { ServerNode } from \"@project-chip/matter.js/node\";\nimport { execSync } from \"child_process\";\n\nrequireMinNodeVersion(16);\n\n/** Initialize configuration values */\nconst { isSocket, deviceName, vendorName, passcode, discriminator, vendorId, productName, productId, port, uniqueId } =\n await getConfiguration();\n\n/**\n * Create a Matter ServerNode, which contains the Root Endpoint and all relevant data and configuration\n */\nconst server = await ServerNode.create({\n // Required: Give the Node a unique ID which is used to store the state of this node\n id: uniqueId,\n\n // Provide Network relevant configuration like the port\n // Optional when operating only one device on a host, Default port is 5540\n network: {\n port,\n },\n\n // Provide Commissioning relevant settings\n // Optional for development/testing purposes\n commissioning: {\n passcode,\n discriminator,\n },\n\n // Provide Node announcement settings\n // Optional: If Ommitted some development defaults are used\n productDescription: {\n name: deviceName,\n deviceType: AggregatorEndpoint.deviceType,\n },\n\n // Provide defaults for the BasicInformation cluster on the Root endpoint\n // Optional: If Omitted some development defaults are used\n basicInformation: {\n vendorName,\n vendorId: VendorId(vendorId),\n nodeLabel: productName,\n productName,\n productLabel: productName,\n productId,\n serialNumber: `matterjs-${uniqueId}`,\n uniqueId,\n },\n});\n\n/**\n * Matter Nodes are a composition of endpoints. Create and add a single multiple endpoint to the node to make it a\n * composed device. This example uses the OnOffLightDevice or OnOffPlugInUnitDevice depending on the value of the type\n * parameter. It also assigns each Endpoint a unique ID to store the endpoint number for it in the storage to restore\n * the device on restart.\n *\n * In this case we directly use the default command implementation from matter.js. Check out the DeviceNodeFull example\n * to see how to customize the command handlers.\n */\n\nconst aggregator = new Endpoint(AggregatorEndpoint, { id: \"aggregator\" });\nawait server.add(aggregator);\n\nfor (let idx = 0; idx < isSocket.length; idx++) {\n const i = idx + 1;\n const isASocket = isSocket[idx]; // Is the Device we add a Socket or a Light?\n\n const name = `OnOff ${isASocket ? \"Socket\" : \"Light\"} ${i}`;\n\n const endpoint = new Endpoint(\n isASocket\n ? // For a Bridged Device we need to add a BridgedDeviceBasicInformation cluster as server\n OnOffPlugInUnitDevice.with(BridgedDeviceBasicInformationServer)\n : OnOffLightDevice.with(BridgedDeviceBasicInformationServer),\n {\n id: `onoff-${i}`,\n bridgedDeviceBasicInformation: {\n nodeLabel: name, // Main end user name for the device\n productName: name,\n productLabel: name,\n serialNumber: `node-matter-${uniqueId}-${i}`,\n reachable: true,\n },\n },\n );\n await aggregator.add(endpoint);\n\n /**\n * Register state change handlers and events of the endpoint for identify and onoff states to react to the commands.\n *\n * If the code in these change handlers fail then the change is also rolled back and not executed and an error is\n * reported back to the controller.\n */\n endpoint.events.identify.startIdentifying.on(() => {\n console.log(`Run identify logic for ${name}, ideally blink a light every 0.5s ...`);\n });\n\n endpoint.events.identify.stopIdentifying.on(() => {\n console.log(`Stop identify logic for ${name} ...`);\n });\n\n endpoint.events.onOff.onOff$Changed.on(value => {\n executeCommand(value ? `on${i}` : `off${i}`);\n console.log(`${name} is now ${value ? \"ON\" : \"OFF\"}`);\n });\n}\n\n/**\n * In order to start the node and announce it into the network we use the run method which resolves when the node goes\n * offline again because we do not need anything more here. See the Full example for other starting options.\n * The QR Code is printed automatically.\n */\nawait server.start();\n\n/**\n * Log the endpoint structure for debugging reasons and to allow to verify anything is correct\n */\nlogEndpoint(EndpointServer.forEndpoint(server));\n\n/*\n If you want to dynamically add another device during runtime you can do so by doing the following:\n\n const name = `OnOff Light 3`;\n\n const endpoint = new Endpoint(OnOffLightDevice.with(BridgedDeviceBasicInformationServer), {\n id: `onoff-3`,\n bridgedDeviceBasicInformation: {\n nodeLabel: name,\n productName: name,\n productLabel: name,\n serialNumber: `node-matter-${uniqueId}-3`,\n reachable: true,\n },\n });\n await aggregator.add(endpoint);\n\n endpoint.events.onOff.onOff$Changed.on(value => {\n executeCommand(value ? `on3` : `off3`);\n console.log(`${name} is now ${value ? \"ON\" : \"OFF\"}`);\n });\n\n */\n\n/*\n To remove a device during runtime you can do so by doing the following:\n console.log(\"Removing Light 3 now!!\");\n\n await endpoint.close();\n\n This will automatically remove the endpoint from the bridge.\n */\n\n/*********************************************************************************************************\n * Convenience Methods\n *********************************************************************************************************/\n\n/** Defined a shell command from an environment variable and execute it and log the response. */\nfunction executeCommand(scriptParamName: string) {\n const script = Environment.default.vars.string(scriptParamName);\n if (script === undefined) return undefined;\n console.log(`${scriptParamName}: ${execSync(script).toString().slice(0, -1)}`);\n}\n\nasync function getConfiguration() {\n /**\n * Collect all needed data\n *\n * This block collects all needed data from cli, environment or storage. Replace this with where ever your data come from.\n *\n * Note: This example uses the matter.js process storage system to store the device parameter data for convenience\n * and easy reuse. When you also do that be careful to not overlap with Matter-Server own storage contexts\n * (so maybe better not do it ;-)).\n */\n const environment = Environment.default;\n\n const storageService = environment.get(StorageService);\n console.log(`Storage location: ${storageService.location} (Directory)`);\n console.log(\n 'Use the parameter \"--storage-path=NAME-OR-PATH\" to specify a different storage location in this directory, use --storage-clear to start with an empty storage.',\n );\n const deviceStorage = (await storageService.open(\"device\")).createContext(\"data\");\n\n const isSocket = Array<boolean>();\n const numDevices = environment.vars.number(\"num\") || 2;\n if (await deviceStorage.has(\"isSocket\")) {\n console.log(`Device types found in storage. --type parameter is ignored.`);\n (await deviceStorage.get<Array<boolean>>(\"isSocket\")).forEach(type => isSocket.push(type));\n }\n for (let i = 1; i <= numDevices; i++) {\n if (isSocket[i - 1] !== undefined) continue;\n isSocket.push(environment.vars.string(`type${i}`) === \"socket\");\n }\n\n const deviceName = \"Matter test device\";\n const vendorName = \"matter-node.js\";\n const passcode = environment.vars.number(\"passcode\") ?? (await deviceStorage.get(\"passcode\", 20202021));\n const discriminator = environment.vars.number(\"discriminator\") ?? (await deviceStorage.get(\"discriminator\", 3840));\n // product name / id and vendor id should match what is in the device certificate\n const vendorId = environment.vars.number(\"vendorid\") ?? (await deviceStorage.get(\"vendorid\", 0xfff1));\n const productName = `node-matter OnOff ${isSocket ? \"Socket\" : \"Light\"}`;\n const productId = environment.vars.number(\"productid\") ?? (await deviceStorage.get(\"productid\", 0x8000));\n\n const port = environment.vars.number(\"port\") ?? 5540;\n\n const uniqueId =\n environment.vars.string(\"uniqueid\") ?? (await deviceStorage.get(\"uniqueid\", Time.nowMs().toString()));\n\n // Persist basic data to keep them also on restart\n await deviceStorage.set({\n passcode,\n discriminator,\n vendorid: vendorId,\n productid: productId,\n isSocket,\n uniqueid: uniqueId,\n });\n\n return {\n isSocket,\n deviceName,\n vendorName,\n passcode,\n discriminator,\n vendorId,\n productName,\n productId,\n port,\n uniqueId,\n };\n}\n"],
|
5
|
-
"mappings": "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",
|
6
|
-
"names": ["isSocket", "deviceName", "vendorName", "passcode", "discriminator", "vendorId", "productName", "productId", "port", "uniqueId"]
|
7
|
-
}
|
@@ -1,123 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
/**
|
3
|
-
* @license
|
4
|
-
* Copyright 2022-2024 Matter.js Authors
|
5
|
-
* SPDX-License-Identifier: Apache-2.0
|
6
|
-
*/
|
7
|
-
import { requireMinNodeVersion } from "@project-chip/matter.js-nodejs";
|
8
|
-
import { Time } from "@project-chip/matter.js-general";
|
9
|
-
import { DeviceTypeId, VendorId } from "@project-chip/matter.js/datatype";
|
10
|
-
import { logEndpoint } from "@project-chip/matter.js/device";
|
11
|
-
import { OnOffLightDevice } from "@project-chip/matter.js/devices/OnOffLightDevice";
|
12
|
-
import { OnOffPlugInUnitDevice } from "@project-chip/matter.js/devices/OnOffPlugInUnitDevice";
|
13
|
-
import { Endpoint, EndpointServer } from "@project-chip/matter.js/endpoint";
|
14
|
-
import { Environment, StorageService } from "@project-chip/matter.js/environment";
|
15
|
-
import { ServerNode } from "@project-chip/matter.js/node";
|
16
|
-
import { execSync } from "child_process";
|
17
|
-
requireMinNodeVersion(16);
|
18
|
-
const { isSocket, deviceName, vendorName, passcode, discriminator, vendorId, productName, productId, port, uniqueId } = await getConfiguration();
|
19
|
-
const server = await ServerNode.create({
|
20
|
-
// Required: Give the Node a unique ID which is used to store the state of this node
|
21
|
-
id: uniqueId,
|
22
|
-
// Provide Network relevant configuration like the port
|
23
|
-
// Optional when operating only one device on a host, Default port is 5540
|
24
|
-
network: {
|
25
|
-
port
|
26
|
-
},
|
27
|
-
// Provide Commissioning relevant settings
|
28
|
-
// Optional for development/testing purposes
|
29
|
-
commissioning: {
|
30
|
-
passcode,
|
31
|
-
discriminator
|
32
|
-
},
|
33
|
-
// Provide Node announcement settings
|
34
|
-
// Optional: If Ommitted some development defaults are used
|
35
|
-
productDescription: {
|
36
|
-
name: deviceName,
|
37
|
-
deviceType: DeviceTypeId(isSocket[0] ? OnOffPlugInUnitDevice.deviceType : OnOffLightDevice.deviceType)
|
38
|
-
},
|
39
|
-
// Provide defaults for the BasicInformation cluster on the Root endpoint
|
40
|
-
// Optional: If Omitted some development defaults are used
|
41
|
-
basicInformation: {
|
42
|
-
vendorName,
|
43
|
-
vendorId: VendorId(vendorId),
|
44
|
-
nodeLabel: productName,
|
45
|
-
productName,
|
46
|
-
productLabel: productName,
|
47
|
-
productId,
|
48
|
-
serialNumber: `matterjs-${uniqueId}`,
|
49
|
-
uniqueId
|
50
|
-
}
|
51
|
-
});
|
52
|
-
for (let idx = 0; idx < isSocket.length; idx++) {
|
53
|
-
const i = idx + 1;
|
54
|
-
const isASocket = isSocket[idx];
|
55
|
-
const endpoint = new Endpoint(isASocket ? OnOffPlugInUnitDevice : OnOffLightDevice, { id: `onoff-${i}` });
|
56
|
-
await server.add(endpoint);
|
57
|
-
endpoint.events.identify.startIdentifying.on(() => {
|
58
|
-
console.log(`Run identify logic for sub device ${i}, ideally blink a light every 0.5s ...`);
|
59
|
-
});
|
60
|
-
endpoint.events.identify.stopIdentifying.on(() => {
|
61
|
-
console.log(`Stop identify logic for sub device ${i}...`);
|
62
|
-
});
|
63
|
-
endpoint.events.onOff.onOff$Changed.on((value) => {
|
64
|
-
executeCommand(value ? `on${i}` : `off${i}`);
|
65
|
-
console.log(`OnOff ${i} is now ${value ? "ON" : "OFF"}`);
|
66
|
-
});
|
67
|
-
}
|
68
|
-
logEndpoint(EndpointServer.forEndpoint(server));
|
69
|
-
await server.run();
|
70
|
-
function executeCommand(scriptParamName) {
|
71
|
-
const script = Environment.default.vars.string(scriptParamName);
|
72
|
-
if (script === void 0) return void 0;
|
73
|
-
console.log(`${scriptParamName}: ${execSync(script).toString().slice(0, -1)}`);
|
74
|
-
}
|
75
|
-
async function getConfiguration() {
|
76
|
-
const environment = Environment.default;
|
77
|
-
const storageService = environment.get(StorageService);
|
78
|
-
console.log(`Storage location: ${storageService.location} (Directory)`);
|
79
|
-
console.log(
|
80
|
-
'Use the parameter "--storage-path=NAME-OR-PATH" to specify a different storage location in this directory, use --storage-clear to start with an empty storage.'
|
81
|
-
);
|
82
|
-
const deviceStorage = (await storageService.open("device")).createContext("data");
|
83
|
-
const isSocket2 = Array();
|
84
|
-
const numDevices = environment.vars.number("num") || 2;
|
85
|
-
if (await deviceStorage.has("isSocket")) {
|
86
|
-
console.log(`Device types found in storage. --type parameter is ignored.`);
|
87
|
-
(await deviceStorage.get("isSocket")).forEach((type) => isSocket2.push(type));
|
88
|
-
}
|
89
|
-
for (let i = 1; i < numDevices; i++) {
|
90
|
-
if (isSocket2[i - 1] !== void 0) continue;
|
91
|
-
isSocket2.push(environment.vars.string(`type${i}`) === "socket");
|
92
|
-
}
|
93
|
-
const deviceName2 = "Matter test device";
|
94
|
-
const vendorName2 = "matter-node.js";
|
95
|
-
const passcode2 = environment.vars.number("passcode") ?? await deviceStorage.get("passcode", 20202021);
|
96
|
-
const discriminator2 = environment.vars.number("discriminator") ?? await deviceStorage.get("discriminator", 3840);
|
97
|
-
const vendorId2 = environment.vars.number("vendorid") ?? await deviceStorage.get("vendorid", 65521);
|
98
|
-
const productName2 = `node-matter OnOff ${isSocket2 ? "Socket" : "Light"}`;
|
99
|
-
const productId2 = environment.vars.number("productid") ?? await deviceStorage.get("productid", 32768);
|
100
|
-
const port2 = environment.vars.number("port") ?? 5540;
|
101
|
-
const uniqueId2 = environment.vars.string("uniqueid") ?? await deviceStorage.get("uniqueid", Time.nowMs().toString());
|
102
|
-
await deviceStorage.set({
|
103
|
-
passcode: passcode2,
|
104
|
-
discriminator: discriminator2,
|
105
|
-
vendorid: vendorId2,
|
106
|
-
productid: productId2,
|
107
|
-
isSocket: isSocket2,
|
108
|
-
uniqueid: uniqueId2
|
109
|
-
});
|
110
|
-
return {
|
111
|
-
isSocket: isSocket2,
|
112
|
-
deviceName: deviceName2,
|
113
|
-
vendorName: vendorName2,
|
114
|
-
passcode: passcode2,
|
115
|
-
discriminator: discriminator2,
|
116
|
-
vendorId: vendorId2,
|
117
|
-
productName: productName2,
|
118
|
-
productId: productId2,
|
119
|
-
port: port2,
|
120
|
-
uniqueId: uniqueId2
|
121
|
-
};
|
122
|
-
}
|
123
|
-
//# sourceMappingURL=ComposedDeviceNode.js.map
|
@@ -1,7 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"version": 3,
|
3
|
-
"sources": ["../../../src/examples/ComposedDeviceNode.ts"],
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * This example shows how to create a new device node that is composed of multiple devices.\n * It creates multiple endpoints on the server. For information on how to add a composed device to a bridge please\n * refer to the bridge example!\n * It can be used as CLI script and starting point for your own device node implementation.\n */\n\n/**\n * Import needed modules from @project-chip/matter-node.js\n */\n// Include this first to auto-register Crypto, Network and Time Node.js implementations\nimport { requireMinNodeVersion } from \"@project-chip/matter.js-nodejs\";\n\nimport { Time } from \"@project-chip/matter.js-general\";\nimport { DeviceTypeId, VendorId } from \"@project-chip/matter.js/datatype\";\nimport { logEndpoint } from \"@project-chip/matter.js/device\";\nimport { OnOffLightDevice } from \"@project-chip/matter.js/devices/OnOffLightDevice\";\nimport { OnOffPlugInUnitDevice } from \"@project-chip/matter.js/devices/OnOffPlugInUnitDevice\";\nimport { Endpoint, EndpointServer } from \"@project-chip/matter.js/endpoint\";\nimport { Environment, StorageService } from \"@project-chip/matter.js/environment\";\nimport { ServerNode } from \"@project-chip/matter.js/node\";\nimport { execSync } from \"child_process\";\n\nrequireMinNodeVersion(16);\n\n/** Initialize configuration values */\nconst { isSocket, deviceName, vendorName, passcode, discriminator, vendorId, productName, productId, port, uniqueId } =\n await getConfiguration();\n\n/**\n * Create a Matter ServerNode, which contains the Root Endpoint and all relevant data and configuration\n */\nconst server = await ServerNode.create({\n // Required: Give the Node a unique ID which is used to store the state of this node\n id: uniqueId,\n\n // Provide Network relevant configuration like the port\n // Optional when operating only one device on a host, Default port is 5540\n network: {\n port,\n },\n\n // Provide Commissioning relevant settings\n // Optional for development/testing purposes\n commissioning: {\n passcode,\n discriminator,\n },\n\n // Provide Node announcement settings\n // Optional: If Ommitted some development defaults are used\n productDescription: {\n name: deviceName,\n deviceType: DeviceTypeId(isSocket[0] ? OnOffPlugInUnitDevice.deviceType : OnOffLightDevice.deviceType),\n },\n\n // Provide defaults for the BasicInformation cluster on the Root endpoint\n // Optional: If Omitted some development defaults are used\n basicInformation: {\n vendorName,\n vendorId: VendorId(vendorId),\n nodeLabel: productName,\n productName,\n productLabel: productName,\n productId,\n serialNumber: `matterjs-${uniqueId}`,\n uniqueId,\n },\n});\n\n/**\n * Matter Nodes are a composition of endpoints. Create and add a single multiple endpoint to the node to make it a\n * composed device. This example uses the OnOffLightDevice or OnOffPlugInUnitDevice depending on the value of the type\n * parameter. It also assigns each Endpoint a unique ID to store the endpoint number for it in the storage to restore\n * the device on restart.\n *\n * In this case we directly use the default command implementation from matter.js. Check out the DeviceNodeFull example\n * to see how to customize the command handlers.\n */\n\nfor (let idx = 0; idx < isSocket.length; idx++) {\n const i = idx + 1;\n const isASocket = isSocket[idx]; // Is the Device we add a Socket or a Light?\n const endpoint = new Endpoint(isASocket ? OnOffPlugInUnitDevice : OnOffLightDevice, { id: `onoff-${i}` });\n await server.add(endpoint);\n\n /**\n * Register state change handlers of the endpoint for identify and onoff states to react to the commands.\n *\n * If the code in these change handlers fail then the change is also rolled back and not executed and an error is\n * reported back to the controller.\n */\n endpoint.events.identify.startIdentifying.on(() => {\n console.log(`Run identify logic for sub device ${i}, ideally blink a light every 0.5s ...`);\n });\n\n endpoint.events.identify.stopIdentifying.on(() => {\n console.log(`Stop identify logic for sub device ${i}...`);\n });\n\n endpoint.events.onOff.onOff$Changed.on(value => {\n executeCommand(value ? `on${i}` : `off${i}`);\n console.log(`OnOff ${i} is now ${value ? \"ON\" : \"OFF\"}`);\n });\n}\n\n/**\n * Log the endpoint structure for debugging reasons and to allow to verify anything is correct\n */\nlogEndpoint(EndpointServer.forEndpoint(server));\n\n/**\n * In order to start the node and announce it into the network we use the run method which resolves when the node goes\n * offline again because we do not need anything more here. See the Full example for other starting options.\n * The QR Code is printed automatically.\n */\nawait server.run();\n\n/*********************************************************************************************************\n * Convenience Methods\n *********************************************************************************************************/\n\n/**\n * Defines a shell command from an environment variable and execute it and log the response\n */\nfunction executeCommand(scriptParamName: string) {\n const script = Environment.default.vars.string(scriptParamName);\n if (script === undefined) return undefined;\n console.log(`${scriptParamName}: ${execSync(script).toString().slice(0, -1)}`);\n}\n\nasync function getConfiguration() {\n const environment = Environment.default;\n\n const storageService = environment.get(StorageService);\n console.log(`Storage location: ${storageService.location} (Directory)`);\n console.log(\n 'Use the parameter \"--storage-path=NAME-OR-PATH\" to specify a different storage location in this directory, use --storage-clear to start with an empty storage.',\n );\n const deviceStorage = (await storageService.open(\"device\")).createContext(\"data\");\n\n const isSocket = Array<boolean>();\n const numDevices = environment.vars.number(\"num\") || 2;\n if (await deviceStorage.has(\"isSocket\")) {\n console.log(`Device types found in storage. --type parameter is ignored.`);\n (await deviceStorage.get<Array<boolean>>(\"isSocket\")).forEach(type => isSocket.push(type));\n }\n for (let i = 1; i < numDevices; i++) {\n if (isSocket[i - 1] !== undefined) continue;\n isSocket.push(environment.vars.string(`type${i}`) === \"socket\");\n }\n\n const deviceName = \"Matter test device\";\n const vendorName = \"matter-node.js\";\n const passcode = environment.vars.number(\"passcode\") ?? (await deviceStorage.get(\"passcode\", 20202021));\n const discriminator = environment.vars.number(\"discriminator\") ?? (await deviceStorage.get(\"discriminator\", 3840));\n // product name / id and vendor id should match what is in the device certificate\n const vendorId = environment.vars.number(\"vendorid\") ?? (await deviceStorage.get(\"vendorid\", 0xfff1));\n const productName = `node-matter OnOff ${isSocket ? \"Socket\" : \"Light\"}`;\n const productId = environment.vars.number(\"productid\") ?? (await deviceStorage.get(\"productid\", 0x8000));\n\n const port = environment.vars.number(\"port\") ?? 5540;\n\n const uniqueId =\n environment.vars.string(\"uniqueid\") ?? (await deviceStorage.get(\"uniqueid\", Time.nowMs().toString()));\n\n // Persist basic data to keep them also on restart\n await deviceStorage.set({\n passcode,\n discriminator,\n vendorid: vendorId,\n productid: productId,\n isSocket,\n uniqueid: uniqueId,\n });\n\n return {\n isSocket,\n deviceName,\n vendorName,\n passcode,\n discriminator,\n vendorId,\n productName,\n productId,\n port,\n uniqueId,\n };\n}\n"],
|
5
|
-
"mappings": "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",
|
6
|
-
"names": ["isSocket", "deviceName", "vendorName", "passcode", "discriminator", "vendorId", "productName", "productId", "port", "uniqueId"]
|
7
|
-
}
|
@@ -1,194 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
/**
|
3
|
-
* @license
|
4
|
-
* Copyright 2022-2024 Matter.js Authors
|
5
|
-
* SPDX-License-Identifier: Apache-2.0
|
6
|
-
*/
|
7
|
-
import { requireMinNodeVersion } from "@project-chip/matter.js-nodejs";
|
8
|
-
import { BleNode } from "@project-chip/matter-node-ble.js/ble";
|
9
|
-
import { CommissioningController } from "@project-chip/matter.js";
|
10
|
-
import { Logger, singleton, Time } from "@project-chip/matter.js-general";
|
11
|
-
import { Ble } from "@project-chip/matter.js/ble";
|
12
|
-
import {
|
13
|
-
BasicInformationCluster,
|
14
|
-
DescriptorCluster,
|
15
|
-
GeneralCommissioning,
|
16
|
-
OnOff
|
17
|
-
} from "@project-chip/matter.js/cluster";
|
18
|
-
import { NodeId } from "@project-chip/matter.js/datatype";
|
19
|
-
import { NodeStateInformation } from "@project-chip/matter.js/device";
|
20
|
-
import { Environment, StorageService } from "@project-chip/matter.js/environment";
|
21
|
-
import { ManualPairingCodeCodec } from "@project-chip/matter.js/schema";
|
22
|
-
const logger = Logger.get("Controller");
|
23
|
-
requireMinNodeVersion(16);
|
24
|
-
const environment = Environment.default;
|
25
|
-
if (environment.vars.get("ble")) {
|
26
|
-
Ble.get = singleton(
|
27
|
-
() => new BleNode({
|
28
|
-
hciId: environment.vars.number("ble-hci-id")
|
29
|
-
})
|
30
|
-
);
|
31
|
-
}
|
32
|
-
const storageService = environment.get(StorageService);
|
33
|
-
console.log(`Storage location: ${storageService.location} (Directory)`);
|
34
|
-
logger.info(
|
35
|
-
'Use the parameter "--storage-path=NAME-OR-PATH" to specify a different storage location in this directory, use --storage-clear to start with an empty storage.'
|
36
|
-
);
|
37
|
-
class ControllerNode {
|
38
|
-
async start() {
|
39
|
-
logger.info(`node-matter Controller started`);
|
40
|
-
const controllerStorage = (await storageService.open("controller")).createContext("data");
|
41
|
-
const ip = await controllerStorage.has("ip") ? await controllerStorage.get("ip") : environment.vars.string("ip");
|
42
|
-
const port = await controllerStorage.has("port") ? await controllerStorage.get("port") : environment.vars.number("port");
|
43
|
-
const uniqueId = await controllerStorage.has("uniqueid") ? await controllerStorage.get("uniqueid") : environment.vars.string("uniqueid") ?? Time.nowMs().toString();
|
44
|
-
await controllerStorage.set("uniqueid", uniqueId);
|
45
|
-
const pairingCode = environment.vars.string("pairingcode");
|
46
|
-
let longDiscriminator, setupPin, shortDiscriminator;
|
47
|
-
if (pairingCode !== void 0) {
|
48
|
-
const pairingCodeCodec = ManualPairingCodeCodec.decode(pairingCode);
|
49
|
-
shortDiscriminator = pairingCodeCodec.shortDiscriminator;
|
50
|
-
longDiscriminator = void 0;
|
51
|
-
setupPin = pairingCodeCodec.passcode;
|
52
|
-
logger.debug(`Data extracted from pairing code: ${Logger.toJSON(pairingCodeCodec)}`);
|
53
|
-
} else {
|
54
|
-
longDiscriminator = environment.vars.number("longDiscriminator") ?? await controllerStorage.get("longDiscriminator", 3840);
|
55
|
-
if (longDiscriminator > 4095) throw new Error("Discriminator value must be less than 4096");
|
56
|
-
setupPin = environment.vars.number("pin") ?? await controllerStorage.get("pin", 20202021);
|
57
|
-
}
|
58
|
-
if (shortDiscriminator === void 0 && longDiscriminator === void 0 || setupPin === void 0) {
|
59
|
-
throw new Error(
|
60
|
-
"Please specify the longDiscriminator of the device to commission with -longDiscriminator or provide a valid passcode with -passcode"
|
61
|
-
);
|
62
|
-
}
|
63
|
-
const commissioningOptions = {
|
64
|
-
regulatoryLocation: GeneralCommissioning.RegulatoryLocationType.IndoorOutdoor,
|
65
|
-
regulatoryCountryCode: "XX"
|
66
|
-
};
|
67
|
-
let ble = false;
|
68
|
-
if (environment.vars.get("ble")) {
|
69
|
-
ble = true;
|
70
|
-
const wifiSsid = environment.vars.string("ble-wifi-ssid");
|
71
|
-
const wifiCredentials = environment.vars.string("ble-wifi-credentials");
|
72
|
-
const threadNetworkName = environment.vars.string("ble-thread-networkname");
|
73
|
-
const threadOperationalDataset = environment.vars.string("ble-thread-operationaldataset");
|
74
|
-
if (wifiSsid !== void 0 && wifiCredentials !== void 0) {
|
75
|
-
logger.info(`Registering Commissioning over BLE with WiFi: ${wifiSsid}`);
|
76
|
-
commissioningOptions.wifiNetwork = {
|
77
|
-
wifiSsid,
|
78
|
-
wifiCredentials
|
79
|
-
};
|
80
|
-
}
|
81
|
-
if (threadNetworkName !== void 0 && threadOperationalDataset !== void 0) {
|
82
|
-
logger.info(`Registering Commissioning over BLE with Thread: ${threadNetworkName}`);
|
83
|
-
commissioningOptions.threadNetwork = {
|
84
|
-
networkName: threadNetworkName,
|
85
|
-
operationalDataset: threadOperationalDataset
|
86
|
-
};
|
87
|
-
}
|
88
|
-
}
|
89
|
-
const commissioningController = new CommissioningController({
|
90
|
-
environment: {
|
91
|
-
environment,
|
92
|
-
id: uniqueId
|
93
|
-
},
|
94
|
-
autoConnect: false
|
95
|
-
});
|
96
|
-
await commissioningController.start();
|
97
|
-
if (!commissioningController.isCommissioned()) {
|
98
|
-
const options = {
|
99
|
-
commissioning: commissioningOptions,
|
100
|
-
discovery: {
|
101
|
-
knownAddress: ip !== void 0 && port !== void 0 ? { ip, port, type: "udp" } : void 0,
|
102
|
-
identifierData: longDiscriminator !== void 0 ? { longDiscriminator } : shortDiscriminator !== void 0 ? { shortDiscriminator } : {},
|
103
|
-
discoveryCapabilities: {
|
104
|
-
ble
|
105
|
-
}
|
106
|
-
},
|
107
|
-
passcode: setupPin
|
108
|
-
};
|
109
|
-
logger.info(`Commissioning ... ${Logger.toJSON(options)}`);
|
110
|
-
const nodeId = await commissioningController.commissionNode(options);
|
111
|
-
console.log(`Commissioning successfully done with nodeId ${nodeId}`);
|
112
|
-
}
|
113
|
-
try {
|
114
|
-
const nodes = commissioningController.getCommissionedNodes();
|
115
|
-
console.log("Found commissioned nodes:", Logger.toJSON(nodes));
|
116
|
-
const nodeId = NodeId(environment.vars.number("nodeid") ?? nodes[0]);
|
117
|
-
if (!nodes.includes(nodeId)) {
|
118
|
-
throw new Error(`Node ${nodeId} not found in commissioned nodes`);
|
119
|
-
}
|
120
|
-
const node = await commissioningController.connectNode(nodeId, {
|
121
|
-
attributeChangedCallback: (peerNodeId, { path: { nodeId: nodeId2, clusterId, endpointId, attributeName }, value }) => console.log(
|
122
|
-
`attributeChangedCallback ${peerNodeId}: Attribute ${nodeId2}/${endpointId}/${clusterId}/${attributeName} changed to ${Logger.toJSON(
|
123
|
-
value
|
124
|
-
)}`
|
125
|
-
),
|
126
|
-
eventTriggeredCallback: (peerNodeId, { path: { nodeId: nodeId2, clusterId, endpointId, eventName }, events }) => console.log(
|
127
|
-
`eventTriggeredCallback ${peerNodeId}: Event ${nodeId2}/${endpointId}/${clusterId}/${eventName} triggered with ${Logger.toJSON(
|
128
|
-
events
|
129
|
-
)}`
|
130
|
-
),
|
131
|
-
stateInformationCallback: (peerNodeId, info2) => {
|
132
|
-
switch (info2) {
|
133
|
-
case NodeStateInformation.Connected:
|
134
|
-
console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} connected`);
|
135
|
-
break;
|
136
|
-
case NodeStateInformation.Disconnected:
|
137
|
-
console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} disconnected`);
|
138
|
-
break;
|
139
|
-
case NodeStateInformation.Reconnecting:
|
140
|
-
console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} reconnecting`);
|
141
|
-
break;
|
142
|
-
case NodeStateInformation.WaitingForDeviceDiscovery:
|
143
|
-
console.log(
|
144
|
-
`stateInformationCallback ${peerNodeId}: Node ${nodeId} waiting for device discovery`
|
145
|
-
);
|
146
|
-
break;
|
147
|
-
case NodeStateInformation.StructureChanged:
|
148
|
-
console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} structure changed`);
|
149
|
-
break;
|
150
|
-
case NodeStateInformation.Decommissioned:
|
151
|
-
console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} decommissioned`);
|
152
|
-
break;
|
153
|
-
}
|
154
|
-
}
|
155
|
-
});
|
156
|
-
node.logStructure();
|
157
|
-
const descriptor = node.getRootClusterClient(DescriptorCluster);
|
158
|
-
if (descriptor !== void 0) {
|
159
|
-
console.log(await descriptor.attributes.deviceTypeList.get());
|
160
|
-
console.log(await descriptor.getServerListAttribute());
|
161
|
-
} else {
|
162
|
-
console.log("No Descriptor Cluster found. This should never happen!");
|
163
|
-
}
|
164
|
-
const info = node.getRootClusterClient(BasicInformationCluster);
|
165
|
-
if (info !== void 0) {
|
166
|
-
console.log(await info.getProductNameAttribute());
|
167
|
-
} else {
|
168
|
-
console.log("No BasicInformation Cluster found. This should never happen!");
|
169
|
-
}
|
170
|
-
const devices = node.getDevices();
|
171
|
-
if (devices[0] && devices[0].number === 1) {
|
172
|
-
const onOff = devices[0].getClusterClient(OnOff.Complete);
|
173
|
-
if (onOff !== void 0) {
|
174
|
-
let onOffStatus = await onOff.getOnOffAttribute();
|
175
|
-
console.log("initial onOffStatus", onOffStatus);
|
176
|
-
onOff.addOnOffAttributeListener((value) => {
|
177
|
-
console.log("subscription onOffStatus", value);
|
178
|
-
onOffStatus = value;
|
179
|
-
});
|
180
|
-
setInterval(() => {
|
181
|
-
onOff.toggle().then(() => {
|
182
|
-
onOffStatus = !onOffStatus;
|
183
|
-
console.log("onOffStatus", onOffStatus);
|
184
|
-
}).catch((error) => logger.error(error));
|
185
|
-
}, 6e4);
|
186
|
-
}
|
187
|
-
}
|
188
|
-
} finally {
|
189
|
-
setTimeout(() => process.exit(0), 1e6);
|
190
|
-
}
|
191
|
-
}
|
192
|
-
}
|
193
|
-
new ControllerNode().start().catch((error) => logger.error(error));
|
194
|
-
//# sourceMappingURL=ControllerNode.js.map
|
@@ -1,7 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"version": 3,
|
3
|
-
"sources": ["../../../src/examples/ControllerNode.ts"],
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * This example shows how to create a Matter controller to pair with a device and interfact with it.\n * It can be used as CLI script, but is more thought as a starting point for your own controller implementation\n * because you need to adjust the code in any way depending on your use case.\n */\n\n/**\n * Import needed modules from @project-chip/matter-node.js\n */\n// Include this first to auto-register Crypto, Network and Time Node.js implementations\nimport { requireMinNodeVersion } from \"@project-chip/matter.js-nodejs\";\n\nimport { BleNode } from \"@project-chip/matter-node-ble.js/ble\";\nimport { CommissioningController, NodeCommissioningOptions } from \"@project-chip/matter.js\";\nimport { Logger, singleton, Time } from \"@project-chip/matter.js-general\";\nimport { Ble } from \"@project-chip/matter.js/ble\";\nimport {\n BasicInformationCluster,\n ClusterClientObj,\n DescriptorCluster,\n GeneralCommissioning,\n OnOff,\n} from \"@project-chip/matter.js/cluster\";\nimport { NodeId } from \"@project-chip/matter.js/datatype\";\nimport { NodeStateInformation } from \"@project-chip/matter.js/device\";\nimport { Environment, StorageService } from \"@project-chip/matter.js/environment\";\nimport { CommissioningOptions } from \"@project-chip/matter.js/protocol\";\nimport { ManualPairingCodeCodec } from \"@project-chip/matter.js/schema\";\n\nconst logger = Logger.get(\"Controller\");\n\nrequireMinNodeVersion(16);\n\nconst environment = Environment.default;\n\nif (environment.vars.get(\"ble\")) {\n // Initialize Ble\n Ble.get = singleton(\n () =>\n new BleNode({\n hciId: environment.vars.number(\"ble-hci-id\"),\n }),\n );\n}\n\nconst storageService = environment.get(StorageService);\n\nconsole.log(`Storage location: ${storageService.location} (Directory)`);\nlogger.info(\n 'Use the parameter \"--storage-path=NAME-OR-PATH\" to specify a different storage location in this directory, use --storage-clear to start with an empty storage.',\n);\n\nclass ControllerNode {\n async start() {\n logger.info(`node-matter Controller started`);\n\n /**\n * Collect all needed data\n *\n * This block makes sure to collect all needed data from cli or storage. Replace this with where ever your data\n * come from.\n *\n * Note: This example also uses the initialized storage system to store the device parameter data for convenience\n * and easy reuse. When you also do that be careful to not overlap with Matter-Server own contexts\n * (so maybe better not ;-)).\n */\n\n const controllerStorage = (await storageService.open(\"controller\")).createContext(\"data\");\n const ip = (await controllerStorage.has(\"ip\"))\n ? await controllerStorage.get<string>(\"ip\")\n : environment.vars.string(\"ip\");\n const port = (await controllerStorage.has(\"port\"))\n ? await controllerStorage.get<number>(\"port\")\n : environment.vars.number(\"port\");\n const uniqueId = (await controllerStorage.has(\"uniqueid\"))\n ? await controllerStorage.get<string>(\"uniqueid\")\n : (environment.vars.string(\"uniqueid\") ?? Time.nowMs().toString());\n await controllerStorage.set(\"uniqueid\", uniqueId);\n\n const pairingCode = environment.vars.string(\"pairingcode\");\n let longDiscriminator, setupPin, shortDiscriminator;\n if (pairingCode !== undefined) {\n const pairingCodeCodec = ManualPairingCodeCodec.decode(pairingCode);\n shortDiscriminator = pairingCodeCodec.shortDiscriminator;\n longDiscriminator = undefined;\n setupPin = pairingCodeCodec.passcode;\n logger.debug(`Data extracted from pairing code: ${Logger.toJSON(pairingCodeCodec)}`);\n } else {\n longDiscriminator =\n environment.vars.number(\"longDiscriminator\") ??\n (await controllerStorage.get(\"longDiscriminator\", 3840));\n if (longDiscriminator > 4095) throw new Error(\"Discriminator value must be less than 4096\");\n setupPin = environment.vars.number(\"pin\") ?? (await controllerStorage.get(\"pin\", 20202021));\n }\n if ((shortDiscriminator === undefined && longDiscriminator === undefined) || setupPin === undefined) {\n throw new Error(\n \"Please specify the longDiscriminator of the device to commission with -longDiscriminator or provide a valid passcode with -passcode\",\n );\n }\n\n // Collect commissioning options from commandline parameters\n const commissioningOptions: CommissioningOptions = {\n regulatoryLocation: GeneralCommissioning.RegulatoryLocationType.IndoorOutdoor,\n regulatoryCountryCode: \"XX\",\n };\n\n let ble = false;\n if (environment.vars.get(\"ble\")) {\n ble = true;\n const wifiSsid = environment.vars.string(\"ble-wifi-ssid\");\n const wifiCredentials = environment.vars.string(\"ble-wifi-credentials\");\n const threadNetworkName = environment.vars.string(\"ble-thread-networkname\");\n const threadOperationalDataset = environment.vars.string(\"ble-thread-operationaldataset\");\n if (wifiSsid !== undefined && wifiCredentials !== undefined) {\n logger.info(`Registering Commissioning over BLE with WiFi: ${wifiSsid}`);\n commissioningOptions.wifiNetwork = {\n wifiSsid: wifiSsid,\n wifiCredentials: wifiCredentials,\n };\n }\n if (threadNetworkName !== undefined && threadOperationalDataset !== undefined) {\n logger.info(`Registering Commissioning over BLE with Thread: ${threadNetworkName}`);\n commissioningOptions.threadNetwork = {\n networkName: threadNetworkName,\n operationalDataset: threadOperationalDataset,\n };\n }\n }\n\n /**\n * Create Matter Server and Controller Node\n *\n * To allow the device to be announced, found, paired and operated we need a MatterServer instance and add a\n * CommissioningController to it and add the just created device instance to it.\n * The Controller node defines the port where the server listens for the UDP packages of the Matter protocol\n * and initializes deice specific certificates and such.\n *\n * The below logic also adds command handlers for commands of clusters that normally are handled internally\n * like testEventTrigger (General Diagnostic Cluster) that can be implemented with the logic when these commands\n * are called.\n */\n\n const commissioningController = new CommissioningController({\n environment: {\n environment,\n id: uniqueId,\n },\n autoConnect: false,\n });\n\n /**\n * Start the Matter Server\n *\n * After everything was plugged together we can start the server. When not delayed announcement is set for the\n * CommissioningServer node then this command also starts the announcement of the device into the network.\n */\n await commissioningController.start();\n\n if (!commissioningController.isCommissioned()) {\n const options = {\n commissioning: commissioningOptions,\n discovery: {\n knownAddress: ip !== undefined && port !== undefined ? { ip, port, type: \"udp\" } : undefined,\n identifierData:\n longDiscriminator !== undefined\n ? { longDiscriminator }\n : shortDiscriminator !== undefined\n ? { shortDiscriminator }\n : {},\n discoveryCapabilities: {\n ble,\n },\n },\n passcode: setupPin,\n } as NodeCommissioningOptions;\n logger.info(`Commissioning ... ${Logger.toJSON(options)}`);\n const nodeId = await commissioningController.commissionNode(options);\n\n console.log(`Commissioning successfully done with nodeId ${nodeId}`);\n }\n\n /**\n * TBD\n */\n try {\n const nodes = commissioningController.getCommissionedNodes();\n console.log(\"Found commissioned nodes:\", Logger.toJSON(nodes));\n\n const nodeId = NodeId(environment.vars.number(\"nodeid\") ?? nodes[0]);\n if (!nodes.includes(nodeId)) {\n throw new Error(`Node ${nodeId} not found in commissioned nodes`);\n }\n\n const node = await commissioningController.connectNode(nodeId, {\n attributeChangedCallback: (\n peerNodeId,\n { path: { nodeId, clusterId, endpointId, attributeName }, value },\n ) =>\n console.log(\n `attributeChangedCallback ${peerNodeId}: Attribute ${nodeId}/${endpointId}/${clusterId}/${attributeName} changed to ${Logger.toJSON(\n value,\n )}`,\n ),\n eventTriggeredCallback: (peerNodeId, { path: { nodeId, clusterId, endpointId, eventName }, events }) =>\n console.log(\n `eventTriggeredCallback ${peerNodeId}: Event ${nodeId}/${endpointId}/${clusterId}/${eventName} triggered with ${Logger.toJSON(\n events,\n )}`,\n ),\n stateInformationCallback: (peerNodeId, info) => {\n switch (info) {\n case NodeStateInformation.Connected:\n console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} connected`);\n break;\n case NodeStateInformation.Disconnected:\n console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} disconnected`);\n break;\n case NodeStateInformation.Reconnecting:\n console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} reconnecting`);\n break;\n case NodeStateInformation.WaitingForDeviceDiscovery:\n console.log(\n `stateInformationCallback ${peerNodeId}: Node ${nodeId} waiting for device discovery`,\n );\n break;\n case NodeStateInformation.StructureChanged:\n console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} structure changed`);\n break;\n case NodeStateInformation.Decommissioned:\n console.log(`stateInformationCallback ${peerNodeId}: Node ${nodeId} decommissioned`);\n break;\n }\n },\n });\n\n // Important: This is a temporary API to proof the methods working and this will change soon and is NOT stable!\n // It is provided to proof the concept\n\n node.logStructure();\n\n // Example to initialize a ClusterClient and access concrete fields as API methods\n const descriptor = node.getRootClusterClient(DescriptorCluster);\n if (descriptor !== undefined) {\n console.log(await descriptor.attributes.deviceTypeList.get()); // you can call that way\n console.log(await descriptor.getServerListAttribute()); // or more convenient that way\n } else {\n console.log(\"No Descriptor Cluster found. This should never happen!\");\n }\n\n // Example to subscribe to a field and get the value\n const info = node.getRootClusterClient(BasicInformationCluster);\n if (info !== undefined) {\n console.log(await info.getProductNameAttribute()); // This call is executed remotely\n //console.log(await info.subscribeProductNameAttribute(value => console.log(\"productName\", value), 5, 30));\n //console.log(await info.getProductNameAttribute()); // This call is resolved locally because we have subscribed to the value!\n } else {\n console.log(\"No BasicInformation Cluster found. This should never happen!\");\n }\n\n // Example to get all Attributes of the commissioned node: */*/*\n //const attributesAll = await interactionClient.getAllAttributes();\n //console.log(\"Attributes-All:\", Logger.toJSON(attributesAll));\n\n // Example to get all Attributes of all Descriptor Clusters of the commissioned node: */DescriptorCluster/*\n //const attributesAllDescriptor = await interactionClient.getMultipleAttributes([{ clusterId: DescriptorCluster.id} ]);\n //console.log(\"Attributes-Descriptor:\", JSON.stringify(attributesAllDescriptor, null, 2));\n\n // Example to get all Attributes of the Basic Information Cluster of endpoint 0 of the commissioned node: 0/BasicInformationCluster/*\n //const attributesBasicInformation = await interactionClient.getMultipleAttributes([{ endpointId: 0, clusterId: BasicInformationCluster.id} ]);\n //console.log(\"Attributes-BasicInformation:\", JSON.stringify(attributesBasicInformation, null, 2));\n\n const devices = node.getDevices();\n if (devices[0] && devices[0].number === 1) {\n // Example to subscribe to all Attributes of endpoint 1 of the commissioned node: */*/*\n //await interactionClient.subscribeMultipleAttributes([{ endpointId: 1, /* subscribe anything from endpoint 1 */ }], 0, 180, data => {\n // console.log(\"Subscribe-All Data:\", Logger.toJSON(data));\n //});\n\n const onOff: ClusterClientObj<OnOff.Complete> | undefined = devices[0].getClusterClient(OnOff.Complete);\n if (onOff !== undefined) {\n let onOffStatus = await onOff.getOnOffAttribute();\n console.log(\"initial onOffStatus\", onOffStatus);\n\n onOff.addOnOffAttributeListener(value => {\n console.log(\"subscription onOffStatus\", value);\n onOffStatus = value;\n });\n // read data every minute to keep up the connection to show the subscription is working\n setInterval(() => {\n onOff\n .toggle()\n .then(() => {\n onOffStatus = !onOffStatus;\n console.log(\"onOffStatus\", onOffStatus);\n })\n .catch(error => logger.error(error));\n }, 60000);\n }\n }\n } finally {\n //await matterServer.close(); // Comment out when subscribes are used, else the connection will be closed\n setTimeout(() => process.exit(0), 1000000);\n }\n }\n}\n\nnew ControllerNode().start().catch(error => logger.error(error));\n"],
|
5
|
-
"mappings": ";AACA;AAAA;AAAA;AAAA;AAAA;AAgBA,SAAS,6BAA6B;AAEtC,SAAS,eAAe;AACxB,SAAS,+BAAyD;AAClE,SAAS,QAAQ,WAAW,YAAY;AACxC,SAAS,WAAW;AACpB;AAAA,EACI;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC,SAAS,aAAa,sBAAsB;AAE5C,SAAS,8BAA8B;AAEvC,MAAM,SAAS,OAAO,IAAI,YAAY;AAEtC,sBAAsB,EAAE;AAExB,MAAM,cAAc,YAAY;AAEhC,IAAI,YAAY,KAAK,IAAI,KAAK,GAAG;AAE7B,MAAI,MAAM;AAAA,IACN,MACI,IAAI,QAAQ;AAAA,MACR,OAAO,YAAY,KAAK,OAAO,YAAY;AAAA,IAC/C,CAAC;AAAA,EACT;AACJ;AAEA,MAAM,iBAAiB,YAAY,IAAI,cAAc;AAErD,QAAQ,IAAI,qBAAqB,eAAe,QAAQ,cAAc;AACtE,OAAO;AAAA,EACH;AACJ;AAEA,MAAM,eAAe;AAAA,EACjB,MAAM,QAAQ;AACV,WAAO,KAAK,gCAAgC;AAa5C,UAAM,qBAAqB,MAAM,eAAe,KAAK,YAAY,GAAG,cAAc,MAAM;AACxF,UAAM,KAAM,MAAM,kBAAkB,IAAI,IAAI,IACtC,MAAM,kBAAkB,IAAY,IAAI,IACxC,YAAY,KAAK,OAAO,IAAI;AAClC,UAAM,OAAQ,MAAM,kBAAkB,IAAI,MAAM,IAC1C,MAAM,kBAAkB,IAAY,MAAM,IAC1C,YAAY,KAAK,OAAO,MAAM;AACpC,UAAM,WAAY,MAAM,kBAAkB,IAAI,UAAU,IAClD,MAAM,kBAAkB,IAAY,UAAU,IAC7C,YAAY,KAAK,OAAO,UAAU,KAAK,KAAK,MAAM,EAAE,SAAS;AACpE,UAAM,kBAAkB,IAAI,YAAY,QAAQ;AAEhD,UAAM,cAAc,YAAY,KAAK,OAAO,aAAa;AACzD,QAAI,mBAAmB,UAAU;AACjC,QAAI,gBAAgB,QAAW;AAC3B,YAAM,mBAAmB,uBAAuB,OAAO,WAAW;AAClE,2BAAqB,iBAAiB;AACtC,0BAAoB;AACpB,iBAAW,iBAAiB;AAC5B,aAAO,MAAM,qCAAqC,OAAO,OAAO,gBAAgB,CAAC,EAAE;AAAA,IACvF,OAAO;AACH,0BACI,YAAY,KAAK,OAAO,mBAAmB,KAC1C,MAAM,kBAAkB,IAAI,qBAAqB,IAAI;AAC1D,UAAI,oBAAoB,KAAM,OAAM,IAAI,MAAM,4CAA4C;AAC1F,iBAAW,YAAY,KAAK,OAAO,KAAK,KAAM,MAAM,kBAAkB,IAAI,OAAO,QAAQ;AAAA,IAC7F;AACA,QAAK,uBAAuB,UAAa,sBAAsB,UAAc,aAAa,QAAW;AACjG,YAAM,IAAI;AAAA,QACN;AAAA,MACJ;AAAA,IACJ;AAGA,UAAM,uBAA6C;AAAA,MAC/C,oBAAoB,qBAAqB,uBAAuB;AAAA,MAChE,uBAAuB;AAAA,IAC3B;AAEA,QAAI,MAAM;AACV,QAAI,YAAY,KAAK,IAAI,KAAK,GAAG;AAC7B,YAAM;AACN,YAAM,WAAW,YAAY,KAAK,OAAO,eAAe;AACxD,YAAM,kBAAkB,YAAY,KAAK,OAAO,sBAAsB;AACtE,YAAM,oBAAoB,YAAY,KAAK,OAAO,wBAAwB;AAC1E,YAAM,2BAA2B,YAAY,KAAK,OAAO,+BAA+B;AACxF,UAAI,aAAa,UAAa,oBAAoB,QAAW;AACzD,eAAO,KAAK,iDAAiD,QAAQ,EAAE;AACvE,6BAAqB,cAAc;AAAA,UAC/B;AAAA,UACA;AAAA,QACJ;AAAA,MACJ;AACA,UAAI,sBAAsB,UAAa,6BAA6B,QAAW;AAC3E,eAAO,KAAK,mDAAmD,iBAAiB,EAAE;AAClF,6BAAqB,gBAAgB;AAAA,UACjC,aAAa;AAAA,UACb,oBAAoB;AAAA,QACxB;AAAA,MACJ;AAAA,IACJ;AAeA,UAAM,0BAA0B,IAAI,wBAAwB;AAAA,MACxD,aAAa;AAAA,QACT;AAAA,QACA,IAAI;AAAA,MACR;AAAA,MACA,aAAa;AAAA,IACjB,CAAC;AAQD,UAAM,wBAAwB,MAAM;AAEpC,QAAI,CAAC,wBAAwB,eAAe,GAAG;AAC3C,YAAM,UAAU;AAAA,QACZ,eAAe;AAAA,QACf,WAAW;AAAA,UACP,cAAc,OAAO,UAAa,SAAS,SAAY,EAAE,IAAI,MAAM,MAAM,MAAM,IAAI;AAAA,UACnF,gBACI,sBAAsB,SAChB,EAAE,kBAAkB,IACpB,uBAAuB,SACrB,EAAE,mBAAmB,IACrB,CAAC;AAAA,UACb,uBAAuB;AAAA,YACnB;AAAA,UACJ;AAAA,QACJ;AAAA,QACA,UAAU;AAAA,MACd;AACA,aAAO,KAAK,qBAAqB,OAAO,OAAO,OAAO,CAAC,EAAE;AACzD,YAAM,SAAS,MAAM,wBAAwB,eAAe,OAAO;AAEnE,cAAQ,IAAI,+CAA+C,MAAM,EAAE;AAAA,IACvE;AAKA,QAAI;AACA,YAAM,QAAQ,wBAAwB,qBAAqB;AAC3D,cAAQ,IAAI,6BAA6B,OAAO,OAAO,KAAK,CAAC;AAE7D,YAAM,SAAS,OAAO,YAAY,KAAK,OAAO,QAAQ,KAAK,MAAM,CAAC,CAAC;AACnE,UAAI,CAAC,MAAM,SAAS,MAAM,GAAG;AACzB,cAAM,IAAI,MAAM,QAAQ,MAAM,kCAAkC;AAAA,MACpE;AAEA,YAAM,OAAO,MAAM,wBAAwB,YAAY,QAAQ;AAAA,QAC3D,0BAA0B,CACtB,YACA,EAAE,MAAM,EAAE,QAAAA,SAAQ,WAAW,YAAY,cAAc,GAAG,MAAM,MAEhE,QAAQ;AAAA,UACJ,4BAA4B,UAAU,eAAeA,OAAM,IAAI,UAAU,IAAI,SAAS,IAAI,aAAa,eAAe,OAAO;AAAA,YACzH;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,QACJ,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAAA,SAAQ,WAAW,YAAY,UAAU,GAAG,OAAO,MAC9F,QAAQ;AAAA,UACJ,0BAA0B,UAAU,WAAWA,OAAM,IAAI,UAAU,IAAI,SAAS,IAAI,SAAS,mBAAmB,OAAO;AAAA,YACnH;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,QACJ,0BAA0B,CAAC,YAAYC,UAAS;AAC5C,kBAAQA,OAAM;AAAA,YACV,KAAK,qBAAqB;AACtB,sBAAQ,IAAI,4BAA4B,UAAU,UAAU,MAAM,YAAY;AAC9E;AAAA,YACJ,KAAK,qBAAqB;AACtB,sBAAQ,IAAI,4BAA4B,UAAU,UAAU,MAAM,eAAe;AACjF;AAAA,YACJ,KAAK,qBAAqB;AACtB,sBAAQ,IAAI,4BAA4B,UAAU,UAAU,MAAM,eAAe;AACjF;AAAA,YACJ,KAAK,qBAAqB;AACtB,sBAAQ;AAAA,gBACJ,4BAA4B,UAAU,UAAU,MAAM;AAAA,cAC1D;AACA;AAAA,YACJ,KAAK,qBAAqB;AACtB,sBAAQ,IAAI,4BAA4B,UAAU,UAAU,MAAM,oBAAoB;AACtF;AAAA,YACJ,KAAK,qBAAqB;AACtB,sBAAQ,IAAI,4BAA4B,UAAU,UAAU,MAAM,iBAAiB;AACnF;AAAA,UACR;AAAA,QACJ;AAAA,MACJ,CAAC;AAKD,WAAK,aAAa;AAGlB,YAAM,aAAa,KAAK,qBAAqB,iBAAiB;AAC9D,UAAI,eAAe,QAAW;AAC1B,gBAAQ,IAAI,MAAM,WAAW,WAAW,eAAe,IAAI,CAAC;AAC5D,gBAAQ,IAAI,MAAM,WAAW,uBAAuB,CAAC;AAAA,MACzD,OAAO;AACH,gBAAQ,IAAI,wDAAwD;AAAA,MACxE;AAGA,YAAM,OAAO,KAAK,qBAAqB,uBAAuB;AAC9D,UAAI,SAAS,QAAW;AACpB,gBAAQ,IAAI,MAAM,KAAK,wBAAwB,CAAC;AAAA,MAGpD,OAAO;AACH,gBAAQ,IAAI,8DAA8D;AAAA,MAC9E;AAcA,YAAM,UAAU,KAAK,WAAW;AAChC,UAAI,QAAQ,CAAC,KAAK,QAAQ,CAAC,EAAE,WAAW,GAAG;AAMvC,cAAM,QAAsD,QAAQ,CAAC,EAAE,iBAAiB,MAAM,QAAQ;AACtG,YAAI,UAAU,QAAW;AACrB,cAAI,cAAc,MAAM,MAAM,kBAAkB;AAChD,kBAAQ,IAAI,uBAAuB,WAAW;AAE9C,gBAAM,0BAA0B,WAAS;AACrC,oBAAQ,IAAI,4BAA4B,KAAK;AAC7C,0BAAc;AAAA,UAClB,CAAC;AAED,sBAAY,MAAM;AACd,kBACK,OAAO,EACP,KAAK,MAAM;AACR,4BAAc,CAAC;AACf,sBAAQ,IAAI,eAAe,WAAW;AAAA,YAC1C,CAAC,EACA,MAAM,WAAS,OAAO,MAAM,KAAK,CAAC;AAAA,UAC3C,GAAG,GAAK;AAAA,QACZ;AAAA,MACJ;AAAA,IACJ,UAAE;AAEE,iBAAW,MAAM,QAAQ,KAAK,CAAC,GAAG,GAAO;AAAA,IAC7C;AAAA,EACJ;AACJ;AAEA,IAAI,eAAe,EAAE,MAAM,EAAE,MAAM,WAAS,OAAO,MAAM,KAAK,CAAC;",
|
6
|
-
"names": ["nodeId", "info"]
|
7
|
-
}
|