@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.
Files changed (76) hide show
  1. package/README.md +3 -271
  2. package/dist/esm/examples/BridgedDevicesNodeLegacy.js +5 -4
  3. package/dist/esm/examples/BridgedDevicesNodeLegacy.js.map +1 -2
  4. package/dist/esm/examples/ComposedDeviceNodeLegacy.js +4 -3
  5. package/dist/esm/examples/ComposedDeviceNodeLegacy.js.map +1 -2
  6. package/dist/esm/examples/ControllerNodeLegacy.js +7 -6
  7. package/dist/esm/examples/ControllerNodeLegacy.js.map +1 -2
  8. package/dist/esm/examples/DeviceNodeFullLegacy.js +8 -6
  9. package/dist/esm/examples/DeviceNodeFullLegacy.js.map +1 -2
  10. package/dist/esm/examples/LegacyStorageConverter.js +2 -2
  11. package/dist/esm/examples/LegacyStorageConverter.js.map +0 -1
  12. package/dist/esm/examples/MultiDeviceNodeLegacy.js +5 -4
  13. package/dist/esm/examples/MultiDeviceNodeLegacy.js.map +1 -2
  14. package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.js +7 -6
  15. package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.js.map +1 -2
  16. package/dist/esm/package.json +3 -0
  17. package/package.json +16 -37
  18. package/src/examples/BridgedDevicesNodeLegacy.ts +4 -3
  19. package/src/examples/ComposedDeviceNodeLegacy.ts +4 -3
  20. package/src/examples/ControllerNodeLegacy.ts +6 -5
  21. package/src/examples/DeviceNodeFullLegacy.ts +7 -5
  22. package/src/examples/LegacyStorageConverter.ts +2 -2
  23. package/src/examples/MultiDeviceNodeLegacy.ts +4 -4
  24. package/src/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.ts +7 -6
  25. package/src/tsconfig.json +13 -13
  26. package/dist/esm/examples/BridgedDevicesNode.js +0 -144
  27. package/dist/esm/examples/BridgedDevicesNode.js.map +0 -7
  28. package/dist/esm/examples/ComposedDeviceNode.js +0 -123
  29. package/dist/esm/examples/ComposedDeviceNode.js.map +0 -7
  30. package/dist/esm/examples/ControllerNode.js +0 -194
  31. package/dist/esm/examples/ControllerNode.js.map +0 -7
  32. package/dist/esm/examples/DeviceNode.js +0 -127
  33. package/dist/esm/examples/DeviceNode.js.map +0 -7
  34. package/dist/esm/examples/DeviceNodeFull.js +0 -253
  35. package/dist/esm/examples/DeviceNodeFull.js.map +0 -7
  36. package/dist/esm/examples/IlluminatedRollerShade.js +0 -60
  37. package/dist/esm/examples/IlluminatedRollerShade.js.map +0 -7
  38. package/dist/esm/examples/LightDevice.js +0 -35
  39. package/dist/esm/examples/LightDevice.js.map +0 -7
  40. package/dist/esm/examples/MultiDeviceNode.js +0 -140
  41. package/dist/esm/examples/MultiDeviceNode.js.map +0 -7
  42. package/dist/esm/examples/SensorDeviceNode.js +0 -175
  43. package/dist/esm/examples/SensorDeviceNode.js.map +0 -7
  44. package/dist/esm/examples/cluster/DummyThreadNetworkCommissioningServer.js +0 -121
  45. package/dist/esm/examples/cluster/DummyThreadNetworkCommissioningServer.js.map +0 -7
  46. package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServer.js +0 -121
  47. package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServer.js.map +0 -7
  48. package/dist/esm/examples/cluster/MyFancyOwnFunctionality.js +0 -110
  49. package/dist/esm/examples/cluster/MyFancyOwnFunctionality.js.map +0 -7
  50. package/dist/esm/tutorial/example01.js +0 -5
  51. package/dist/esm/tutorial/example01.js.map +0 -7
  52. package/dist/esm/tutorial/example02.js +0 -7
  53. package/dist/esm/tutorial/example02.js.map +0 -7
  54. package/dist/esm/tutorial/example03.js +0 -15
  55. package/dist/esm/tutorial/example03.js.map +0 -7
  56. package/dist/esm/tutorial/example04.js +0 -10
  57. package/dist/esm/tutorial/example04.js.map +0 -7
  58. package/dist/esm/tutorial/example05.js +0 -14
  59. package/dist/esm/tutorial/example05.js.map +0 -7
  60. package/src/examples/BridgedDevicesNode.ts +0 -259
  61. package/src/examples/ComposedDeviceNode.ts +0 -196
  62. package/src/examples/ControllerNode.ts +0 -314
  63. package/src/examples/DeviceNode.ts +0 -201
  64. package/src/examples/DeviceNodeFull.ts +0 -440
  65. package/src/examples/IlluminatedRollerShade.ts +0 -96
  66. package/src/examples/LightDevice.ts +0 -61
  67. package/src/examples/MultiDeviceNode.ts +0 -208
  68. package/src/examples/SensorDeviceNode.ts +0 -247
  69. package/src/examples/cluster/DummyThreadNetworkCommissioningServer.ts +0 -156
  70. package/src/examples/cluster/DummyWifiNetworkCommissioningServer.ts +0 -154
  71. package/src/examples/cluster/MyFancyOwnFunctionality.ts +0 -185
  72. package/src/tutorial/example01.ts +0 -6
  73. package/src/tutorial/example02.ts +0 -9
  74. package/src/tutorial/example03.ts +0 -19
  75. package/src/tutorial/example04.ts +0 -13
  76. package/src/tutorial/example05.ts +0 -19
@@ -1,96 +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
-
8
- // Include this first to auto-register Crypto, Network and Time Node.js implementations
9
- import "@project-chip/matter.js-nodejs";
10
-
11
- import {
12
- MovementDirection,
13
- MovementType,
14
- WindowCoveringServer,
15
- } from "@project-chip/matter.js/behaviors/window-covering";
16
- import { OnOffLightDevice, OnOffLightRequirements } from "@project-chip/matter.js/devices/OnOffLightDevice";
17
- import { WindowCoveringDevice } from "@project-chip/matter.js/devices/WindowCoveringDevice";
18
- import { ServerNode } from "@project-chip/matter.js/node";
19
-
20
- /**
21
- * This example demonstrates implementation of a "composed" device comprising multiple sub-devices
22
- *
23
- * Our example device, the Excelsior 1000 EZ-Nite™, is a roller shade with an illuminated valance.
24
- */
25
-
26
- const LiftingWindowCoveringServer = WindowCoveringServer.with("Lift", "AbsolutePosition", "PositionAwareLift");
27
-
28
- /**
29
- * Implementation of the Matter WindowCovering cluster for the shade motor.
30
- */
31
- class RollerShade extends LiftingWindowCoveringServer {
32
- override async handleMovement(
33
- type: MovementType,
34
- reversed: boolean,
35
- direction: MovementDirection,
36
- targetPercent100ths?: number,
37
- ) {
38
- console.log(
39
- "Move window shade",
40
- direction === MovementDirection.Open ? "Open" : "Close",
41
- targetPercent100ths !== undefined ? `${targetPercent100ths / 100}%` : "",
42
- );
43
-
44
- // Updates the shade position
45
- await super.handleMovement(type, reversed, direction, targetPercent100ths);
46
- }
47
- }
48
-
49
- /**
50
- * Implementation of the OnOff cluster for our valance light.
51
- */
52
- class ValanceLight extends OnOffLightRequirements.OnOffServer {
53
- override initialize() {
54
- this.reactTo(this.events.onOff$Changed, this.#stateChanged);
55
- }
56
-
57
- #stateChanged(value: boolean) {
58
- console.log(`Valance is now ${value ? "illuminated" : "dark"}`);
59
- }
60
- }
61
-
62
- /**
63
- * Our Matter node.
64
- */
65
- const node = new ServerNode({
66
- id: "excelsior1000",
67
-
68
- productDescription: {},
69
-
70
- commissioning: {
71
- passcode: 20202021,
72
- discriminator: 3840,
73
- },
74
-
75
- basicInformation: {
76
- vendorName: "Acme Corporation",
77
- productName: "Excelsior 1000 EZ-Nite™",
78
- vendorId: 0xfff1,
79
- productId: 0x8000,
80
- serialNumber: "1234-12345-123",
81
- },
82
-
83
- parts: [
84
- {
85
- type: WindowCoveringDevice.with(RollerShade),
86
- id: "shade",
87
- },
88
-
89
- {
90
- type: OnOffLightDevice.with(ValanceLight),
91
- id: "valance",
92
- },
93
- ],
94
- });
95
-
96
- await node.run();
@@ -1,61 +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
-
8
- // This demonstrates bringing a "light" device online with matter.js.
9
-
10
- // Include this first to auto-register Crypto, Network and Time Node.js implementations
11
- import "@project-chip/matter.js-nodejs";
12
-
13
- import { OnOffLightDevice, OnOffLightRequirements } from "@project-chip/matter.js/devices/OnOffLightDevice";
14
- import { ServerNode } from "@project-chip/matter.js/node";
15
-
16
- // Matter exposes functionality in groups called "clusters". For this example device we override the matter.js "On/Off"
17
- // cluster implementation to print status to the console.
18
- class ReportingOnOffServer extends OnOffLightRequirements.OnOffServer {
19
- // Intercept the "on" command to the Matter On/Off cluster to print a log message.
20
- override async on() {
21
- console.log("Turning light ON");
22
- await super.on();
23
- }
24
-
25
- // This is the functional inverse of on() above.
26
- //
27
- // For demonstration purposes we update state ourselves rather than deferring to matter.js's default "off" handler
28
- // via super.off().
29
- override off() {
30
- console.log("Turning light OFF");
31
- this.state.onOff = false;
32
- }
33
-
34
- // Use event handlers to log on/off state reactively, after it changes.
35
- override initialize() {
36
- this.events.onOff$Changed.on(value => {
37
- console.log(`Light is now ${value ? "ON" : "OFF"}`);
38
- });
39
- }
40
- }
41
-
42
- // Devices are compositions of behaviors like OnOffServer above. To extend an existing device you use builder methods.
43
- //
44
- // In this case we are using with() to install our On/Off cluster behavior.
45
- const ExampleLight = OnOffLightDevice.with(ReportingOnOffServer);
46
-
47
- // Physical devices appear as "nodes" on a Matter network. As a device implementer you use a NodeServer to bring a
48
- // device online.
49
- //
50
- // Note there are a large number of options to NodeServer that we are allowing to take default values here. See
51
- // IlluminatedRollerShade.ts for a more detailed example.
52
- const node = await ServerNode.create();
53
-
54
- // Nodes are a composition of endpoints. Add a single endpoint to the node, our example light device.
55
- await node.add(ExampleLight);
56
-
57
- // Our device is now built and we can bring the node online.
58
- //
59
- // Note that you may serve multiple nodes from a single process. We only have one, however, so we can use the run()
60
- // method of the node.
61
- await node.run();
@@ -1,208 +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
-
8
- /**
9
- * This example shows how to create a new device node that is composed of multiple devices.
10
- * It creates multiple endpoints on the server. For information on how to add a composed device to a bridge please
11
- * refer to the bridge example!
12
- * It can be used as CLI script and starting point for your own device node implementation.
13
- */
14
-
15
- /**
16
- * Import needed modules from @project-chip/matter-node.js
17
- */
18
- // Include this first to auto-register Crypto, Network and Time Node.js implementations
19
- import { requireMinNodeVersion } from "@project-chip/matter.js-nodejs";
20
-
21
- import { Time } from "@project-chip/matter.js-general";
22
- import { DeviceTypeId, VendorId } from "@project-chip/matter.js/datatype";
23
- import { logEndpoint } from "@project-chip/matter.js/device";
24
- import { OnOffLightDevice } from "@project-chip/matter.js/devices/OnOffLightDevice";
25
- import { OnOffPlugInUnitDevice } from "@project-chip/matter.js/devices/OnOffPlugInUnitDevice";
26
- import { Endpoint, EndpointServer } from "@project-chip/matter.js/endpoint";
27
- import { Environment, StorageService } from "@project-chip/matter.js/environment";
28
- import { ServerNode } from "@project-chip/matter.js/node";
29
- import { execSync } from "child_process";
30
-
31
- requireMinNodeVersion(16);
32
-
33
- const devices = await getConfiguration();
34
- for (let idx = 1; idx < devices.length; idx++) {
35
- const {
36
- isSocket,
37
- deviceName,
38
- vendorName,
39
- passcode,
40
- discriminator,
41
- vendorId,
42
- productName,
43
- productId,
44
- port,
45
- uniqueId,
46
- } = devices[idx];
47
- const i = idx + 1;
48
-
49
- /**
50
- * Create a Matter ServerNode, which contains the Root Endpoint and all relevant data and configuration
51
- */
52
- const server = await ServerNode.create({
53
- // Required: Give the Node a unique ID which is used to store the state of this node
54
- id: uniqueId,
55
-
56
- // Provide Network relevant configuration like the port
57
- // Optional when operating only one device on a host, Default port is 5540
58
- network: {
59
- port,
60
- },
61
-
62
- // Provide Commissioning relevant settings
63
- // Optional for development/testing purposes
64
- commissioning: {
65
- passcode,
66
- discriminator,
67
- },
68
-
69
- // Provide Node announcement settings
70
- // Optional: If Ommitted some development defaults are used
71
- productDescription: {
72
- name: deviceName,
73
- deviceType: DeviceTypeId(isSocket ? OnOffPlugInUnitDevice.deviceType : OnOffLightDevice.deviceType),
74
- },
75
-
76
- // Provide defaults for the BasicInformation cluster on the Root endpoint
77
- // Optional: If Omitted some development defaults are used
78
- basicInformation: {
79
- vendorName,
80
- vendorId: VendorId(vendorId),
81
- nodeLabel: productName,
82
- productName,
83
- productLabel: productName,
84
- productId,
85
- serialNumber: `matterjs-${uniqueId}`,
86
- uniqueId,
87
- },
88
- });
89
-
90
- console.log(
91
- `Added device ${i} on port ${port} and unique id ${uniqueId}: Passcode: ${passcode}, Discriminator: ${discriminator}`,
92
- );
93
-
94
- const endpoint = new Endpoint(isSocket ? OnOffPlugInUnitDevice : OnOffLightDevice, { id: "onoff" });
95
- await server.add(endpoint);
96
-
97
- /**
98
- * Register state change handlers of the node for identify and onoff states to react to the commands.
99
- * If the code in these change handlers fail then the change is also rolled back and not executed and an error is
100
- * reported back to the controller.
101
- */
102
- endpoint.events.identify.startIdentifying.on(() => {
103
- console.log(`Run identify logic for device ${i}, ideally blink a light every 0.5s ...`);
104
- });
105
-
106
- endpoint.events.identify.stopIdentifying.on(() => {
107
- console.log(`Stop identify logic for device ${i}...`);
108
- });
109
-
110
- endpoint.events.onOff.onOff$Changed.on(value => {
111
- executeCommand(value ? `on${i}` : `off${i}`);
112
- console.log(`OnOff ${i} is now ${value ? "ON" : "OFF"}`);
113
- });
114
-
115
- /**
116
- * Log the endpoint structure for debugging reasons and to allow to verify anything is correct
117
- */
118
- logEndpoint(EndpointServer.forEndpoint(server));
119
-
120
- console.log("----------------------------");
121
- console.log(`QR Code for Device ${i} on port ${port}:`);
122
- console.log("----------------------------");
123
-
124
- /**
125
- * In order to start the node and announce it into the network we use the run method which resolves when the node goes
126
- * offline again because we do not need anything more here. See the Full example for other starting options.
127
- * The QR Code is printed automatically.
128
- */
129
- await server.start();
130
- }
131
-
132
- /*********************************************************************************************************
133
- * Convenience Methods
134
- *********************************************************************************************************/
135
-
136
- /**
137
- * Defines a shell command from an environment variable and execute it and log the response
138
- */
139
- function executeCommand(scriptParamName: string) {
140
- const script = Environment.default.vars.string(scriptParamName);
141
- if (script === undefined) return undefined;
142
- console.log(`${scriptParamName}: ${execSync(script).toString().slice(0, -1)}`);
143
- }
144
-
145
- async function getConfiguration() {
146
- const environment = Environment.default;
147
-
148
- const storageService = environment.get(StorageService);
149
- console.log(`Storage location: ${storageService.location} (Directory)`);
150
- console.log(
151
- '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.',
152
- );
153
- const deviceStorage = (await storageService.open("device")).createContext("data");
154
-
155
- let defaultPasscode = 20202021;
156
- let defaultDiscriminator = 3840;
157
- let defaultPort = 5550;
158
-
159
- const devices = [];
160
- const numDevices = environment.vars.number("num") ?? 2;
161
- for (let i = 1; i <= numDevices; i++) {
162
- const isSocket = await deviceStorage.get(`isSocket${i}`, environment.vars.string(`type${i}`) === "socket");
163
- if (await deviceStorage.has(`isSocket${i}`)) {
164
- console.log(`Device type ${isSocket ? "socket" : "light"} found in storage. --type parameter is ignored.`);
165
- }
166
- const deviceName = `Matter ${environment.vars.string(`type${i}`) ?? "light"} device ${i}`;
167
- const vendorName = "matter-node.js";
168
- const passcode =
169
- environment.vars.number(`passcode${i}`) ?? (await deviceStorage.get(`passcode${i}`, defaultPasscode++));
170
- const discriminator =
171
- environment.vars.number(`discriminator${i}`) ??
172
- (await deviceStorage.get(`discriminator${i}`, defaultDiscriminator++));
173
- // product name / id and vendor id should match what is in the device certificate
174
- const vendorId = environment.vars.number(`vendorid${i}`) ?? (await deviceStorage.get(`vendorid${i}`, 0xfff1));
175
- const productName = `node-matter OnOff-Device ${i}`;
176
- const productId =
177
- environment.vars.number(`productid${i}`) ?? (await deviceStorage.get(`productid${i}`, 0x8000));
178
-
179
- const port = environment.vars.number(`port${i}`) ?? defaultPort++;
180
-
181
- const uniqueId =
182
- environment.vars.string(`uniqueid${i}`) ??
183
- (await deviceStorage.get(`uniqueid${i}`, `${i}-${Time.nowMs()}`));
184
-
185
- // Persist basic data to keep them also on restart
186
- await deviceStorage.set(`passcode${i}`, passcode);
187
- await deviceStorage.set(`discriminator${i}`, discriminator);
188
- await deviceStorage.set(`vendorid${i}`, vendorId);
189
- await deviceStorage.set(`productid${i}`, productId);
190
- await deviceStorage.set(`isSocket${i}`, isSocket);
191
- await deviceStorage.set(`uniqueid${i}`, uniqueId);
192
-
193
- devices.push({
194
- isSocket,
195
- deviceName,
196
- vendorName,
197
- passcode,
198
- discriminator,
199
- vendorId,
200
- productName,
201
- productId,
202
- port,
203
- uniqueId,
204
- });
205
- }
206
-
207
- return devices;
208
- }
@@ -1,247 +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
-
8
- /**
9
- * This example shows how to create a simple Sensor Matter device as temperature or humidity device.
10
- * It can be used as CLI script and starting point for your own device node implementation.
11
- * This example is CJS conform and do not use top level await's.
12
- */
13
-
14
- /**
15
- * Import needed modules from @project-chip/matter-node.js
16
- */
17
- // Include this first to auto-register Crypto, Network and Time Node.js implementations
18
- import { requireMinNodeVersion } from "@project-chip/matter.js-nodejs";
19
-
20
- import { Time } from "@project-chip/matter.js-general";
21
- import { DeviceTypeId, VendorId } from "@project-chip/matter.js/datatype";
22
- import { logEndpoint } from "@project-chip/matter.js/device";
23
- import { HumiditySensorDevice } from "@project-chip/matter.js/devices/HumiditySensorDevice";
24
- import { TemperatureSensorDevice } from "@project-chip/matter.js/devices/TemperatureSensorDevice";
25
- import { Endpoint, EndpointServer } from "@project-chip/matter.js/endpoint";
26
- import { Environment, StorageService } from "@project-chip/matter.js/environment";
27
- import { ServerNode } from "@project-chip/matter.js/node";
28
- import { execSync } from "child_process";
29
-
30
- requireMinNodeVersion(16);
31
-
32
- async function main() {
33
- /** Initialize configuration values */
34
- const {
35
- isTemperature,
36
- interval,
37
- deviceName,
38
- vendorName,
39
- passcode,
40
- discriminator,
41
- vendorId,
42
- productName,
43
- productId,
44
- port,
45
- uniqueId,
46
- } = await getConfiguration();
47
-
48
- /**
49
- * Create a Matter ServerNode, which contains the Root Endpoint and all relevant data and configuration
50
- */
51
- const server = await ServerNode.create({
52
- // Required: Give the Node a unique ID which is used to store the state of this node
53
- id: uniqueId,
54
-
55
- // Provide Network relevant configuration like the port
56
- // Optional when operating only one device on a host, Default port is 5540
57
- network: {
58
- port,
59
- },
60
-
61
- // Provide Commissioning relevant settings
62
- // Optional for development/testing purposes
63
- commissioning: {
64
- passcode,
65
- discriminator,
66
- },
67
-
68
- // Provide Node announcement settings
69
- // Optional: If Ommitted some development defaults are used
70
- productDescription: {
71
- name: deviceName,
72
- deviceType: DeviceTypeId(
73
- isTemperature ? TemperatureSensorDevice.deviceType : HumiditySensorDevice.deviceType,
74
- ),
75
- },
76
-
77
- // Provide defaults for the BasicInformation cluster on the Root endpoint
78
- // Optional: If Omitted some development defaults are used
79
- basicInformation: {
80
- vendorName,
81
- vendorId: VendorId(vendorId),
82
- nodeLabel: productName,
83
- productName,
84
- productLabel: productName,
85
- productId,
86
- serialNumber: `matterjs-${uniqueId}`,
87
- uniqueId,
88
- },
89
- });
90
-
91
- /**
92
- * Matter Nodes are a composition of endpoints. Create and add a single endpoint to the node. This example uses the
93
- * OnOffLightDevice or OnOffPlugInUnitDevice depending on the value of the type parameter. It also assigns this Part a
94
- * unique ID to store the endpoint number for it in the storage to restore the device on restart.
95
- * In this case we directly use the default command implementation from matter.js. Check out the DeviceNodeFull example
96
- * to see how to customize the command handlers.
97
- */
98
- let endpoint: Endpoint<TemperatureSensorDevice | HumiditySensorDevice>;
99
- if (isTemperature) {
100
- endpoint = new Endpoint(TemperatureSensorDevice, {
101
- id: "tempsensor",
102
- temperatureMeasurement: {
103
- // Use this to initialize the measuredValue with the most uptodate value.
104
- // If you do not know the value and also cannot request it, best use "null" (if allowed by the cluster).
105
- measuredValue: getIntValueFromCommandOrRandom("value"),
106
- },
107
- });
108
- } else {
109
- endpoint = new Endpoint(HumiditySensorDevice, {
110
- id: "humsensor",
111
- relativeHumidityMeasurement: {
112
- // Use this to initialize the measuredValue with the most uptodate value.
113
- // If you do not know the value and also cannot request it, best use "null" (if allowed by the cluster).
114
- measuredValue: getIntValueFromCommandOrRandom("value", false),
115
- },
116
- });
117
- }
118
-
119
- await server.add(endpoint);
120
-
121
- /**
122
- * Log the endpoint structure for debugging reasons and to allow to verify anything is correct
123
- */
124
- logEndpoint(EndpointServer.forEndpoint(server));
125
-
126
- const updateInterval = setInterval(() => {
127
- let setter: Promise<void>;
128
- if (isTemperature) {
129
- setter = endpoint.set({
130
- temperatureMeasurement: {
131
- measuredValue: getIntValueFromCommandOrRandom("value"),
132
- },
133
- });
134
- } else {
135
- setter = endpoint.set({
136
- relativeHumidityMeasurement: {
137
- measuredValue: getIntValueFromCommandOrRandom("value", false),
138
- },
139
- });
140
- }
141
- setter.catch(error => console.error("Error updating measured value:", error));
142
- }, interval * 1000);
143
-
144
- // Cleanup our update interval when node goes offline
145
- server.lifecycle.offline.on(() => clearTimeout(updateInterval));
146
-
147
- /**
148
- * In order to start the node and announce it into the network we use the run method which resolves when the node goes
149
- * offline again because we do not need anything more here. See the Full example for other starting options.
150
- * The QR Code is printed automatically.
151
- */
152
- await server.run();
153
- }
154
-
155
- main().catch(error => console.error(error));
156
-
157
- /*********************************************************************************************************
158
- * Convenience Methods
159
- *********************************************************************************************************/
160
-
161
- /** Defined a shell command from an environment variable and execute it and log the response. */
162
-
163
- function getIntValueFromCommandOrRandom(scriptParamName: string, allowNegativeValues = true) {
164
- const script = Environment.default.vars.string(scriptParamName);
165
- if (script === undefined) {
166
- if (!allowNegativeValues) return Math.round(Math.random() * 100);
167
- return (Math.round(Math.random() * 100) - 50) * 100;
168
- }
169
- let result = execSync(script).toString().trim();
170
- if ((result.startsWith("'") && result.endsWith("'")) || (result.startsWith('"') && result.endsWith('"')))
171
- result = result.slice(1, -1);
172
- console.log(`Command result: ${result}`);
173
- let value = Math.round(parseFloat(result));
174
- if (!allowNegativeValues && value < 0) value = 0;
175
- return value;
176
- }
177
-
178
- async function getConfiguration() {
179
- /**
180
- * Collect all needed data
181
- *
182
- * This block collects all needed data from cli, environment or storage. Replace this with where ever your data come from.
183
- *
184
- * Note: This example uses the matter.js process storage system to store the device parameter data for convenience
185
- * and easy reuse. When you also do that be careful to not overlap with Matter-Server own storage contexts
186
- * (so maybe better not do it ;-)).
187
- */
188
- const environment = Environment.default;
189
-
190
- const storageService = environment.get(StorageService);
191
- console.log(`Storage location: ${storageService.location} (Directory)`);
192
- console.log(
193
- '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.',
194
- );
195
- const deviceStorage = (await storageService.open("device")).createContext("data");
196
-
197
- const isTemperature = await deviceStorage.get("isTemperature", environment.vars.get("type") !== "humidity");
198
- if (await deviceStorage.has("isTemperature")) {
199
- console.log(
200
- `Device type ${isTemperature ? "temperature" : "humidity"} found in storage. --type parameter is ignored.`,
201
- );
202
- }
203
- let interval = environment.vars.number("interval") ?? (await deviceStorage.get("interval", 60));
204
- if (interval < 1) {
205
- console.log(`Invalid Interval ${interval}, set to 60s`);
206
- interval = 60;
207
- }
208
-
209
- const deviceName = "Matter test device";
210
- const vendorName = "matter-node.js";
211
- const passcode = environment.vars.number("passcode") ?? (await deviceStorage.get("passcode", 20202021));
212
- const discriminator = environment.vars.number("discriminator") ?? (await deviceStorage.get("discriminator", 3840));
213
- // product name / id and vendor id should match what is in the device certificate
214
- const vendorId = environment.vars.number("vendorid") ?? (await deviceStorage.get("vendorid", 0xfff1));
215
- const productName = `node-matter OnOff ${isTemperature ? "Temperature" : "Humidity"}`;
216
- const productId = environment.vars.number("productid") ?? (await deviceStorage.get("productid", 0x8000));
217
-
218
- const port = environment.vars.number("port") ?? 5540;
219
-
220
- const uniqueId =
221
- environment.vars.string("uniqueid") ?? (await deviceStorage.get("uniqueid", Time.nowMs().toString()));
222
-
223
- // Persist basic data to keep them also on restart
224
- await deviceStorage.set({
225
- passcode,
226
- discriminator,
227
- vendorid: vendorId,
228
- productid: productId,
229
- interval,
230
- isTemperature,
231
- uniqueid: uniqueId,
232
- });
233
-
234
- return {
235
- isTemperature,
236
- interval,
237
- deviceName,
238
- vendorName,
239
- passcode,
240
- discriminator,
241
- vendorId,
242
- productName,
243
- productId,
244
- port,
245
- uniqueId,
246
- };
247
- }