@project-chip/matter-node.js-examples 0.11.0-alpha.0-20240909-b3b29745 → 0.11.0-alpha.0-20241006-eccb81ae1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +3 -271
  2. package/dist/esm/examples/BridgedDevicesNodeLegacy.js +14 -14
  3. package/dist/esm/examples/BridgedDevicesNodeLegacy.js.map +1 -2
  4. package/dist/esm/examples/ComposedDeviceNodeLegacy.js +15 -15
  5. package/dist/esm/examples/ComposedDeviceNodeLegacy.js.map +1 -2
  6. package/dist/esm/examples/ControllerNodeLegacy.js +22 -22
  7. package/dist/esm/examples/ControllerNodeLegacy.js.map +1 -2
  8. package/dist/esm/examples/DeviceNodeFullLegacy.js +16 -16
  9. package/dist/esm/examples/DeviceNodeFullLegacy.js.map +1 -2
  10. package/dist/esm/examples/LegacyStorageConverter.js +1 -2
  11. package/dist/esm/examples/LegacyStorageConverter.js.map +1 -2
  12. package/dist/esm/examples/MultiDeviceNodeLegacy.js +14 -14
  13. package/dist/esm/examples/MultiDeviceNodeLegacy.js.map +1 -2
  14. package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.js +16 -13
  15. package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.js.map +1 -2
  16. package/dist/esm/package.json +3 -0
  17. package/package.json +16 -36
  18. package/src/examples/BridgedDevicesNodeLegacy.ts +14 -14
  19. package/src/examples/ComposedDeviceNodeLegacy.ts +15 -15
  20. package/src/examples/ControllerNodeLegacy.ts +24 -24
  21. package/src/examples/DeviceNodeFullLegacy.ts +17 -17
  22. package/src/examples/LegacyStorageConverter.ts +2 -2
  23. package/src/examples/MultiDeviceNodeLegacy.ts +14 -14
  24. package/src/examples/cluster/DummyWifiNetworkCommissioningServerLegacy.ts +16 -13
  25. package/src/tsconfig.json +13 -13
  26. package/dist/esm/examples/BridgedDevicesNode.js +0 -145
  27. package/dist/esm/examples/BridgedDevicesNode.js.map +0 -7
  28. package/dist/esm/examples/ComposedDeviceNode.js +0 -124
  29. package/dist/esm/examples/ComposedDeviceNode.js.map +0 -7
  30. package/dist/esm/examples/ControllerNode.js +0 -197
  31. package/dist/esm/examples/ControllerNode.js.map +0 -7
  32. package/dist/esm/examples/DeviceNode.js +0 -128
  33. package/dist/esm/examples/DeviceNode.js.map +0 -7
  34. package/dist/esm/examples/DeviceNodeFull.js +0 -257
  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 -141
  41. package/dist/esm/examples/MultiDeviceNode.js.map +0 -7
  42. package/dist/esm/examples/SensorDeviceNode.js +0 -176
  43. package/dist/esm/examples/SensorDeviceNode.js.map +0 -7
  44. package/dist/esm/examples/cluster/DummyThreadNetworkCommissioningServer.js +0 -118
  45. package/dist/esm/examples/cluster/DummyThreadNetworkCommissioningServer.js.map +0 -7
  46. package/dist/esm/examples/cluster/DummyWifiNetworkCommissioningServer.js +0 -117
  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 -260
  61. package/src/examples/ComposedDeviceNode.ts +0 -197
  62. package/src/examples/ControllerNode.ts +0 -318
  63. package/src/examples/DeviceNode.ts +0 -202
  64. package/src/examples/DeviceNodeFull.ts +0 -445
  65. package/src/examples/IlluminatedRollerShade.ts +0 -96
  66. package/src/examples/LightDevice.ts +0 -61
  67. package/src/examples/MultiDeviceNode.ts +0 -209
  68. package/src/examples/SensorDeviceNode.ts +0 -248
  69. package/src/examples/cluster/DummyThreadNetworkCommissioningServer.ts +0 -153
  70. package/src/examples/cluster/DummyWifiNetworkCommissioningServer.ts +0 -150
  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,445 +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 is not optimized for simplicity, but to show all the advanced use cases for matter.js.
10
- * If you want to see a simple minimalistic and more standard example please look at DeviceNode.ts or the other examples.
11
- *
12
- * This example shows how to create a simple on-off Matter device as a light or as a socket.
13
- * It can be used as CLI script and starting point for your own device node implementation.
14
- * Additional to this it shows the following:
15
- * * How to modify the existing clusters on Root and also Device Endpoints
16
- * * How to add own Cluster implementations for Standard clusters
17
- * * How to add a custom Cluster to an Endpoint
18
- * * Which events are available to get status information from the Node aon commissioning and session/subscription changes
19
- * * How to get cluster state values
20
- * * How to set one or multiple state values in a transaction.
21
- */
22
-
23
- /**
24
- * Import needed modules from @project-chip/matter-node.js
25
- */
26
- // Include this first to auto-register Crypto, Network and Time Node.js implementations
27
- import "@project-chip/matter-node.js";
28
-
29
- import { BleNode } from "@project-chip/matter-node-ble.js/ble";
30
- import { GeneralDiagnostics } from "@project-chip/matter-node.js/cluster";
31
- import { createFileLogger } from "@project-chip/matter-node.js/log";
32
- import { requireMinNodeVersion } from "@project-chip/matter-node.js/util";
33
- import { NetworkCommissioningServer } from "@project-chip/matter.js/behavior/definitions/network-commissioning";
34
- import { OnOffServer } from "@project-chip/matter.js/behavior/definitions/on-off";
35
- import { Ble } from "@project-chip/matter.js/ble";
36
- import { NetworkCommissioning } from "@project-chip/matter.js/cluster";
37
- import { DeviceTypeId, VendorId } from "@project-chip/matter.js/datatype";
38
- import { logEndpoint } from "@project-chip/matter.js/device";
39
- import { OnOffLightDevice } from "@project-chip/matter.js/devices/OnOffLightDevice";
40
- import { OnOffPlugInUnitDevice } from "@project-chip/matter.js/devices/OnOffPlugInUnitDevice";
41
- import { Endpoint, EndpointServer } from "@project-chip/matter.js/endpoint";
42
- import { RootRequirements } from "@project-chip/matter.js/endpoint/definitions";
43
- import { Environment, StorageService } from "@project-chip/matter.js/environment";
44
- import { FabricAction } from "@project-chip/matter.js/fabric";
45
- import { Level, Logger, levelFromString } from "@project-chip/matter.js/log";
46
- import { ServerNode } from "@project-chip/matter.js/node";
47
- import { QrCode } from "@project-chip/matter.js/schema";
48
- import { Time } from "@project-chip/matter.js/time";
49
- import { ByteArray, singleton } from "@project-chip/matter.js/util";
50
- import { execSync } from "child_process";
51
- import { DummyThreadNetworkCommissioningServer } from "./cluster/DummyThreadNetworkCommissioningServer.js";
52
- import { DummyWifiNetworkCommissioningServer } from "./cluster/DummyWifiNetworkCommissioningServer.js";
53
- import {
54
- MyFancyCommandRequest,
55
- MyFancyCommandResponse,
56
- MyFancyOwnFunctionalityBehavior,
57
- } from "./cluster/MyFancyOwnFunctionality.js";
58
-
59
- /**
60
- * The following code brings some convenience to the CLI script. It allows to set the log level and format via
61
- * command line parameters. It also initializes the BLE stack if the `--ble` parameter is present.
62
- * Some of these parameters can also be replaced by generically accepted parameters or even environment variables. See the comments in the relevant places for information.
63
- * When using this code as basis for your own device node implementation, you can remove this part or hard code it.
64
- */
65
-
66
- requireMinNodeVersion(16);
67
-
68
- // To configure Logging use
69
- // * "--log-level" or environment variable "MATTER_LOG_LEVEL" or "environment.vars.set('log.level', Level.DEBUG)"
70
- // Allowed values are: Level.FATAL, Level.ERROR, Level.WARN, Level.NOTICE, Level.INFO, Level.DEBUG
71
- // * "--log-format" or environment variable "MATTER_LOG_FORMAT" or "environment.vars.set('log.format', Format.PLAIN)"
72
- // Allowed values are: Format.PLAIN, Format.HTML, Format.ANSI,
73
-
74
- const environment = Environment.default;
75
-
76
- // Alternatively "--ble-enable" or environment variable "BLE_ENABLED"
77
- // Alternatively "--ble-hciId" or environment variable "BLE_HCIID"
78
- if (environment.vars.get("ble.enable")) {
79
- // Initialize Ble
80
- Ble.get = singleton(
81
- () =>
82
- new BleNode({
83
- hciId: environment.vars.number("ble.hciId"),
84
- }),
85
- );
86
- }
87
-
88
- function executeCommand(scriptParamName: string) {
89
- const script = environment.vars.string(scriptParamName);
90
- if (script === undefined) return undefined;
91
- console.log(`${scriptParamName}: ${execSync(script).toString().slice(0, -1)}`);
92
- }
93
-
94
- /**
95
- * Collect all needed data
96
- *
97
- * This block collects all needed data from cli or storage. Replace this with where ever your data come from.
98
- *
99
- * Note: This example uses the matter.js process storage system to store the device parameter data for convenience
100
- * and easy reuse. When you also do that be careful to not overlap with Matter-Server own storage contexts
101
- * (so maybe better not do it ;-)).
102
- */
103
-
104
- const logFile = environment.vars.string("logfile.filename");
105
- if (logFile !== undefined) {
106
- Logger.addLogger("filelogger", await createFileLogger(logFile), {
107
- defaultLogLevel: levelFromString(environment.vars.string("logfile.loglevel")) ?? Level.DEBUG,
108
- });
109
- }
110
-
111
- const storageService = environment.get(StorageService);
112
- console.log(`Storage location: ${storageService.location} (Directory)`);
113
- console.log(
114
- '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.',
115
- );
116
-
117
- const deviceStorage = (await storageService.open("device")).createContext("data");
118
-
119
- if (await deviceStorage.has("isSocket")) {
120
- console.log("Device type found in storage. --type parameter is ignored.");
121
- }
122
- const isSocket = await deviceStorage.get("isSocket", environment.vars.string("type") === "socket");
123
- const deviceName = "Matter test device";
124
- const vendorName = "matter-node.js";
125
- const passcode = environment.vars.number("passcode") ?? (await deviceStorage.get("passcode", 20202021));
126
- const discriminator = environment.vars.number("discriminator") ?? (await deviceStorage.get("discriminator", 3840));
127
- // product name / id and vendor id should match what is in the device certificate
128
- const vendorId = environment.vars.number("vendorid") ?? (await deviceStorage.get("vendorid", 0xfff1));
129
- const productName = `node-matter OnOff ${isSocket ? "Socket" : "Light"}`;
130
- const productId = environment.vars.number("productid") ?? (await deviceStorage.get("productid", 0x8000));
131
-
132
- const port = environment.vars.number("port") ?? 5540;
133
-
134
- const uniqueId = environment.vars.string("uniqueid") ?? (await deviceStorage.get("uniqueid", Time.nowMs().toString()));
135
-
136
- await deviceStorage.set({
137
- passcode,
138
- discriminator,
139
- vendorid: vendorId,
140
- productid: productId,
141
- isSocket,
142
- uniqueid: uniqueId,
143
- });
144
-
145
- // Matter exposes functionality in groups called "clusters". For this example device we override the matter.js "On/Off"
146
- // cluster implementation to print status to the console.
147
- class OnOffShellExecServer extends OnOffServer {
148
- // Intercept the "on" command to the Matter On/Off cluster to print a log message.
149
- override async on() {
150
- executeCommand("on");
151
- await super.on();
152
- }
153
-
154
- // This is the functional inverse of on() above.
155
- //
156
- // For demonstration purposes we update state ourselves rather than deferring to matter.js's default "off" handler
157
- // via super.off().
158
- override async off() {
159
- executeCommand("off");
160
- this.state.onOff = false;
161
- }
162
-
163
- // Use event handlers to log on/off state reactively, after it changes.
164
- override initialize() {
165
- this.events.onOff$Changed.on(value => {
166
- console.log(`Light is now ${value ? "ON" : "OFF"}`);
167
- });
168
- }
169
- }
170
-
171
- class TestGeneralDiagnosticsServer extends RootRequirements.GeneralDiagnosticsServer {
172
- override initialize() {
173
- this.state.testEventTriggersEnabled = true; // set to true if you support test triggers ...
174
- super.initialize();
175
- }
176
-
177
- override testEventTrigger({ enableKey, eventTrigger }: GeneralDiagnostics.TestEventTriggerRequest) {
178
- console.log(`testEventTrigger called on GeneralDiagnostic cluster: ${enableKey} ${eventTrigger}`);
179
- }
180
- }
181
-
182
- class MyFancyOwnFunctionalityServer extends MyFancyOwnFunctionalityBehavior {
183
- /** We return the incoming value and store the length of the string in our attribute and send it out as event */
184
- override myFancyCommand(request: MyFancyCommandRequest): MyFancyCommandResponse {
185
- const { value } = request;
186
- this.state.myFancyValue = value.length;
187
-
188
- this.events.myFancyEvent.emit({ eventValue: value }, this.context);
189
-
190
- return { response: value };
191
- }
192
-
193
- override initialize() {
194
- this.state.myFancyValue = -1; // Always initialize with -1
195
- }
196
- }
197
-
198
- /**
199
- * Create Device instance and add needed Listener
200
- *
201
- * Create an instance of the matter device class you want to use.
202
- * This example uses the OnOffLightDevice or OnOffPluginUnitDevice depending on the value of the type parameter.
203
- * To execute the on/off scripts defined as parameters a listener for the onOff attribute is registered via the
204
- * device specific API.
205
- *
206
- * The below logic also adds command handlers for commands of clusters that normally are handled device internally
207
- * like identify that can be implemented with the logic when these commands are called.
208
- */
209
-
210
- // Devices are compositions of behaviors like OnOffServer above. To extend an existing device you use builder methods.
211
- //
212
- // In this case we are using with() to install our On/Off cluster behavior.
213
- // .with("Lighting") not needed because we always have it in by default because we have default implementation
214
- const OnOffDevice = isSocket
215
- ? vendorId === 0xfff4
216
- ? OnOffPlugInUnitDevice.with(OnOffShellExecServer, MyFancyOwnFunctionalityServer)
217
- : OnOffPlugInUnitDevice.with(OnOffShellExecServer)
218
- : vendorId === 0xfff4
219
- ? OnOffLightDevice.with(OnOffShellExecServer, MyFancyOwnFunctionalityServer)
220
- : OnOffLightDevice.with(OnOffShellExecServer);
221
-
222
- /**
223
- * Modify automatically added clusters of the Root endpoint if needed
224
- * In this example we change the networkCommissioning cluster into one for "Wifi only" devices when BLE is used
225
- * for commissioning, to demonstrate how to do this.
226
- * If you want to implement Ethernet only devices that get connected to the network via LAN/Ethernet cable,
227
- * then all this is not needed.
228
- * The same as shown here for Wi-Fi is also possible theoretical for Thread only or combined devices.
229
- */
230
-
231
- // We use the Basic Root Endpoint without a NetworkCommissioning cluster
232
- let RootEndpoint = ServerNode.RootEndpoint.with(TestGeneralDiagnosticsServer);
233
-
234
- let wifiOrThreadAdded = false;
235
- let threadAdded = false;
236
- if (Ble.enabled) {
237
- // matter.js will create a Ethernet-only device by default when ut comes to Network Commissioning Features.
238
- // To offer e.g. a "Wi-Fi only device" (or any other combination) we need to override the Network Commissioning
239
- // cluster and implement all the need handling here. This is a "static implementation" for pure demonstration
240
- // purposes and just "simulates" the actions to be done. In a real world implementation this would be done by
241
- // the device implementor based on the relevant networking stack.
242
- // The NetworkCommissioningCluster and all logics are described in Matter Core Specifications section 11.8
243
- if (environment.vars.has("ble.wifi.fake")) {
244
- RootEndpoint = RootEndpoint.with(DummyWifiNetworkCommissioningServer);
245
- wifiOrThreadAdded = true;
246
- } else if (environment.vars.has("ble.thread.fake")) {
247
- RootEndpoint = RootEndpoint.with(DummyThreadNetworkCommissioningServer);
248
- wifiOrThreadAdded = true;
249
- threadAdded = true;
250
- }
251
- } else {
252
- RootEndpoint = RootEndpoint.with(
253
- NetworkCommissioningServer.with(NetworkCommissioning.Feature.EthernetNetworkInterface),
254
- );
255
- }
256
-
257
- const networkId = new ByteArray(32);
258
- // Physical devices appear as "nodes" on a Matter network. As a device implementer you use a NodeServer to bring a
259
- // device online.
260
- //
261
- // Note there are a large number of options to NodeServer that we are allowing to take default values here. See
262
- // CompositeWindowCovering.ts for a more detailed example.
263
- const server = await ServerNode.create(RootEndpoint, {
264
- id: uniqueId,
265
- network: {
266
- port,
267
- discoveryCapabilities: {
268
- onIpNetwork: !environment.vars.has("ble.enable"),
269
- ble: environment.vars.has("ble.enable"),
270
- },
271
- ble: environment.vars.has("ble.enable"), // TODO remove when state init is fixed
272
- },
273
- commissioning: {
274
- passcode,
275
- discriminator,
276
- },
277
- productDescription: {
278
- name: deviceName,
279
- deviceType: DeviceTypeId(OnOffDevice.deviceType),
280
- },
281
- basicInformation: {
282
- vendorName,
283
- vendorId: VendorId(vendorId),
284
- nodeLabel: productName,
285
- productName,
286
- productLabel: productName,
287
- productId,
288
- serialNumber: `node-matter-${uniqueId}`,
289
- uniqueId,
290
- },
291
-
292
- // @ts-expect-error ... TS do not see the types because both next clusters was added conditionally
293
- networkCommissioning: {
294
- maxNetworks: 1,
295
- interfaceEnabled: true,
296
- lastConnectErrorValue: 0,
297
- lastNetworkId: wifiOrThreadAdded ? null : networkId,
298
- lastNetworkingStatus: wifiOrThreadAdded ? null : NetworkCommissioning.NetworkCommissioningStatus.Success,
299
- networks: [{ networkId: networkId, connected: !wifiOrThreadAdded }],
300
- scanMaxTimeSeconds: wifiOrThreadAdded ? 3 : undefined,
301
- connectMaxTimeSeconds: wifiOrThreadAdded ? 3 : undefined,
302
- supportedWifiBands: wifiOrThreadAdded && !threadAdded ? [NetworkCommissioning.WiFiBand["2G4"]] : undefined,
303
- supportedThreadFeatures: wifiOrThreadAdded && threadAdded ? { isFullThreadDevice: true } : undefined,
304
- threadVersion: wifiOrThreadAdded && threadAdded ? 4 : undefined, // means: Thread 1.3
305
- },
306
- myFancyFunctionality: {
307
- myFancyValue: 0,
308
- },
309
- });
310
-
311
- // Nodes are a composition of endpoints. Add a single endpoint to the node, our example light device.
312
- const endpoint = new Endpoint(OnOffDevice, { id: "onoff" });
313
- await server.add(endpoint);
314
-
315
- /**
316
- * This event is triggered when the device is initially commissioned successfully.
317
- * This means: It is added to the first fabric.
318
- */
319
- server.lifecycle.commissioned.on(() => console.log("Server was initially commissioned successfully!"));
320
-
321
- /** This event is triggered when all fabrics are removed from the device, usually it also does a factory reset then. */
322
- server.lifecycle.decommissioned.on(() => console.log("Server was fully decommissioned successfully!"));
323
-
324
- /** This event is triggered when the device went online. This means that it is discoverable in the network. */
325
- server.lifecycle.online.on(() => console.log("Server is online"));
326
-
327
- /** This event is triggered when the device went offline. it is not longer discoverable or connectable in the network. */
328
- server.lifecycle.offline.on(() => console.log("Server is offline"));
329
-
330
- /**
331
- * This event is triggered when a fabric is added, removed or updated on the device. Use this if more granular
332
- * information is needed.
333
- */
334
- server.events.commissioning.fabricsChanged.on((fabricIndex, fabricAction) => {
335
- let action = "";
336
- switch (fabricAction) {
337
- case FabricAction.Added:
338
- action = "added";
339
- break;
340
- case FabricAction.Removed:
341
- action = "removed";
342
- break;
343
- case FabricAction.Updated:
344
- action = "updated";
345
- break;
346
- }
347
- console.log(`Commissioned Fabrics changed event (${action}) for ${fabricIndex} triggered`);
348
- console.log(server.state.commissioning.fabrics[fabricIndex]);
349
- });
350
-
351
- /**
352
- * This event is triggered when an operative new session was opened by a Controller.
353
- * It is not triggered for the initial commissioning process, just afterwards for real connections.
354
- */
355
- server.events.sessions.opened.on(session => console.log(`Session opened`, session));
356
-
357
- /**
358
- * This event is triggered when an operative session is closed by a Controller or because the Device goes offline.
359
- */
360
- server.events.sessions.closed.on(session => console.log(`Session closed`, session));
361
-
362
- /** This event is triggered when a subscription gets added or removed on an operative session. */
363
- server.events.sessions.subscriptionsChanged.on(session => {
364
- console.log(`Session subscriptions changed`, session);
365
- console.log(`Status of all sessions`, server.state.sessions.sessions);
366
- });
367
-
368
- // React on a change of identificationTime to do Identify stuff for the own device
369
- endpoint.events.identify.startIdentifying.on(() => {
370
- console.log(`Run identify logic, ideally blink a light every 0.5s ...`);
371
- });
372
-
373
- endpoint.events.identify.stopIdentifying.on(() => {
374
- console.log(`Stop identify logic ...`);
375
- });
376
-
377
- // Our device is now built and we can bring the node online.
378
- //
379
- // Note that you may serve multiple nodes from a single process. We only have one, however, so we can use the run()
380
- // method of the node.
381
-
382
- logEndpoint(EndpointServer.forEndpoint(server));
383
-
384
- /**
385
- * In order to start the node and announce it into the network we start the node. This method resolves when the Matter
386
- * node enters his online state. Alternatively, we could also use `await server.run()` which
387
- * resolves when the node goes offline again, but we want to execute code afterwards, so we use start() here
388
- */
389
- await server.start();
390
-
391
- console.log("Initial Fabrics", server.state.operationalCredentials.fabrics);
392
-
393
- /**
394
- * If the node is not commissioned already we display the QR code on console. The QR code is also logged
395
- */
396
- if (!server.lifecycle.isCommissioned) {
397
- const { qrPairingCode, manualPairingCode } = server.state.commissioning.pairingCodes;
398
-
399
- console.log(QrCode.get(qrPairingCode));
400
- console.log(`QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`);
401
- console.log(`Manual pairing code: ${manualPairingCode}`);
402
- } else {
403
- console.log("Device is already commissioned. Waiting for controllers to connect ...");
404
-
405
- /**
406
- * Sometimes reading or writing attributes is required. The following code shows how this works.
407
- * For read it is basically `endpoint.state.clustername.attributename`.
408
- * The set method allows to set one or multiple values via the structure of also clustername.attributename. When multiple values are set they are considered being one transaction which would be rolled back completely if one value fails to be set.
409
- */
410
-
411
- // Read onOff attribute from onOff cluster
412
- const onOffValue = endpoint.state.onOff.onOff;
413
- console.log(`current OnOff attribute: ${onOffValue}`);
414
-
415
- if (vendorId === 0xfff4) {
416
- // Set onOff attribute from OnOff cluster AND the myFancyValue of the MyFancyOwnFunctionality cluster together
417
- await endpoint.set({
418
- onOff: {
419
- onOff: !onOffValue,
420
- },
421
- // @ts-expect-error Needed because the Fancy cluster is added conditionally, so TS do not get that it's there.
422
- myFancyOwnFunctionality: {
423
- myFancyValue: 36,
424
- },
425
- });
426
- } else {
427
- // Set onOff attribute from OnOff cluster only
428
- await endpoint.set({
429
- onOff: {
430
- onOff: !onOffValue,
431
- },
432
- });
433
- }
434
- }
435
-
436
- /**
437
- * To correctly tear down the server we can use server.close().
438
- */
439
- process.on("SIGINT", () => {
440
- // Clean up on CTRL-C
441
- server
442
- .close()
443
- .then(() => process.exit(0))
444
- .catch(err => console.error(err));
445
- });
@@ -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-node.js";
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-node.js";
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();