@project-chip/matter-node.js-examples 0.5.0 → 0.5.1-alpha.0-20231006-78029b2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. package/README.md +7 -1
  2. package/dist/cjs/examples/BridgedDevicesNode.d.ts +8 -0
  3. package/dist/cjs/examples/BridgedDevicesNode.d.ts.map +1 -0
  4. package/dist/cjs/examples/BridgedDevicesNode.js +135 -0
  5. package/dist/cjs/examples/BridgedDevicesNode.js.map +7 -0
  6. package/dist/cjs/examples/ComposedDeviceNode.d.ts +8 -0
  7. package/dist/cjs/examples/ComposedDeviceNode.d.ts.map +1 -0
  8. package/dist/cjs/examples/ComposedDeviceNode.js +132 -0
  9. package/dist/cjs/examples/ComposedDeviceNode.js.map +7 -0
  10. package/dist/cjs/examples/ControllerNode.d.ts +8 -0
  11. package/dist/cjs/examples/ControllerNode.d.ts.map +1 -0
  12. package/dist/cjs/examples/ControllerNode.js +172 -0
  13. package/dist/cjs/examples/ControllerNode.js.map +7 -0
  14. package/dist/cjs/examples/DeviceNode.d.ts +8 -0
  15. package/dist/cjs/examples/DeviceNode.d.ts.map +1 -0
  16. package/dist/cjs/examples/DeviceNode.js +174 -0
  17. package/dist/cjs/examples/DeviceNode.js.map +7 -0
  18. package/dist/cjs/examples/MultiDeviceNode.d.ts +8 -0
  19. package/dist/cjs/examples/MultiDeviceNode.d.ts.map +1 -0
  20. package/dist/cjs/examples/MultiDeviceNode.js +140 -0
  21. package/dist/cjs/examples/MultiDeviceNode.js.map +7 -0
  22. package/dist/cjs/examples/cluster/DummyWifiNetworkCommissioningClusterServer.d.ts +18 -0
  23. package/dist/cjs/examples/cluster/DummyWifiNetworkCommissioningClusterServer.d.ts.map +1 -0
  24. package/dist/cjs/examples/cluster/DummyWifiNetworkCommissioningClusterServer.js +166 -0
  25. package/dist/cjs/examples/cluster/DummyWifiNetworkCommissioningClusterServer.js.map +7 -0
  26. package/dist/cjs/package.json +1 -0
  27. package/package.json +21 -25
  28. package/src/examples/BridgedDevicesNode.ts +247 -0
  29. package/src/examples/ComposedDeviceNode.ts +245 -0
  30. package/src/examples/ControllerNode.ts +294 -0
  31. package/src/examples/DeviceNode.ts +288 -0
  32. package/src/examples/MultiDeviceNode.ts +260 -0
  33. package/src/examples/cluster/DummyWifiNetworkCommissioningClusterServer.ts +181 -0
  34. package/dist/examples/BridgedDevicesNode.js +0 -218
  35. package/dist/examples/BridgedDevicesNode.js.map +0 -1
  36. package/dist/examples/ComposedDeviceNode.js +0 -217
  37. package/dist/examples/ComposedDeviceNode.js.map +0 -1
  38. package/dist/examples/ControllerNode.js +0 -261
  39. package/dist/examples/ControllerNode.js.map +0 -1
  40. package/dist/examples/DeviceNode.js +0 -358
  41. package/dist/examples/DeviceNode.js.map +0 -1
  42. package/dist/examples/MultiDeviceNode.js +0 -228
  43. package/dist/examples/MultiDeviceNode.js.map +0 -1
@@ -0,0 +1,260 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @license
4
+ * Copyright 2022 The node-matter 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. When you want to add a composed devices to a Aggregator you need to
11
+ * add all endpoints of the composed device to an "ComposedDevice" instance! (not shown in this 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 { CommissioningServer, MatterServer } from "@project-chip/matter-node.js";
20
+
21
+ import { DeviceTypes, OnOffLightDevice, OnOffPluginUnitDevice } from "@project-chip/matter-node.js/device";
22
+ import { Format, Level, Logger } from "@project-chip/matter-node.js/log";
23
+ import { StorageBackendDisk, StorageManager } from "@project-chip/matter-node.js/storage";
24
+ import { Time } from "@project-chip/matter-node.js/time";
25
+ import {
26
+ commandExecutor,
27
+ getIntParameter,
28
+ getParameter,
29
+ hasParameter,
30
+ requireMinNodeVersion,
31
+ } from "@project-chip/matter-node.js/util";
32
+ import { VendorId } from "@project-chip/matter.js/datatype";
33
+
34
+ const logger = Logger.get("MultiDevice");
35
+
36
+ requireMinNodeVersion(16);
37
+
38
+ /** Configure logging */
39
+ switch (getParameter("loglevel")) {
40
+ case "fatal":
41
+ Logger.defaultLogLevel = Level.FATAL;
42
+ break;
43
+ case "error":
44
+ Logger.defaultLogLevel = Level.ERROR;
45
+ break;
46
+ case "warn":
47
+ Logger.defaultLogLevel = Level.WARN;
48
+ break;
49
+ case "info":
50
+ Logger.defaultLogLevel = Level.INFO;
51
+ break;
52
+ }
53
+
54
+ switch (getParameter("logformat")) {
55
+ case "plain":
56
+ Logger.format = Format.PLAIN;
57
+ break;
58
+ case "html":
59
+ Logger.format = Format.HTML;
60
+ break;
61
+ default:
62
+ if (process.stdin?.isTTY) Logger.format = Format.ANSI;
63
+ }
64
+
65
+ const storageLocation = getParameter("store") ?? ".device-node";
66
+ const storage = new StorageBackendDisk(storageLocation, hasParameter("clearstorage"));
67
+ logger.info(`Storage location: ${storageLocation} (Directory)`);
68
+ logger.info(
69
+ 'Use the parameter "-store NAME" to specify a different storage location, use -clearstorage to start with an empty storage.',
70
+ );
71
+
72
+ class Device {
73
+ private matterServer: MatterServer | undefined;
74
+
75
+ async start() {
76
+ logger.info(`node-matter`);
77
+
78
+ /**
79
+ * Initialize the storage system.
80
+ *
81
+ * The storage manager is then also used by the Matter server, so this code block in general is required,
82
+ * but you can choose a different storage backend as long as it implements the required API.
83
+ */
84
+
85
+ const storageManager = new StorageManager(storage);
86
+ await storageManager.initialize();
87
+
88
+ /**
89
+ * Collect all needed data
90
+ *
91
+ * This block makes sure to collect all needed data from cli or storage. Replace this with where ever your data
92
+ * come from.
93
+ *
94
+ * Note: This example also uses the initialized storage system to store the device parameter data for convenience
95
+ * and easy reuse. When you also do that be careful to not overlap with Matter-Server own contexts
96
+ * (so maybe better not ;-)).
97
+ */
98
+ const netAnnounceInterface = getParameter("announceinterface");
99
+
100
+ const deviceStorage = storageManager.createContext("Device");
101
+
102
+ /**
103
+ * Create Matter Server and CommissioningServer Node
104
+ *
105
+ * To allow the device to be announced, found, paired and operated we need a MatterServer instance and add a
106
+ * commissioningServer to it and add the just created device instance to it.
107
+ * The CommissioningServer node defines the port where the server listens for the UDP packages of the Matter protocol
108
+ * and initializes deice specific certificates and such.
109
+ *
110
+ * The below logic also adds command handlers for commands of clusters that normally are handled internally
111
+ * like testEventTrigger (General Diagnostic Cluster) that can be implemented with the logic when these commands
112
+ * are called.
113
+ */
114
+
115
+ this.matterServer = new MatterServer(storageManager, { mdnsAnnounceInterface: netAnnounceInterface });
116
+
117
+ /**
118
+ * Create Device instance and add needed Listener
119
+ *
120
+ * Create an instance of the matter device class you want to use.
121
+ * This example uses the OnOffLightDevice or OnOffPluginUnitDevice depending on the value of the type parameter.
122
+ * To execute the on/off scripts defined as parameters a listener for the onOff attribute is registered via the
123
+ * device specific API.
124
+ *
125
+ * The below logic also adds command handlers for commands of clusters that normally are handled device internally
126
+ * like identify that can be implemented with the logic when these commands are called.
127
+ */
128
+
129
+ const commissioningServers = new Array<CommissioningServer>();
130
+
131
+ let defaultPasscode = 20202021;
132
+ let defaultDiscriminator = 3840;
133
+ let defaultPort = 5550;
134
+
135
+ const numDevices = getIntParameter("num") || 2;
136
+ for (let i = 1; i <= numDevices; i++) {
137
+ if (deviceStorage.has(`isSocket${i}`)) {
138
+ logger.info("Device type found in storage. -type parameter is ignored.");
139
+ }
140
+ const isSocket = deviceStorage.get(`isSocket${i}`, getParameter(`type${i}`) === "socket");
141
+ const deviceName = `Matter ${getParameter(`type${i}`) ?? "light"} device ${i}`;
142
+ const deviceType =
143
+ getParameter(`type${i}`) === "socket"
144
+ ? DeviceTypes.ON_OFF_PLUGIN_UNIT.code
145
+ : DeviceTypes.ON_OFF_LIGHT.code;
146
+ const vendorName = "matter-node.js";
147
+ const passcode = getIntParameter(`passcode${i}`) ?? deviceStorage.get(`passcode${i}`, defaultPasscode++);
148
+ const discriminator =
149
+ getIntParameter(`discriminator${i}`) ?? deviceStorage.get(`discriminator${i}`, defaultDiscriminator++);
150
+ // product name / id and vendor id should match what is in the device certificate
151
+ const vendorId = getIntParameter(`vendorid${i}`) ?? deviceStorage.get(`vendorid${i}`, 0xfff1);
152
+ const productName = `node-matter OnOff-Device ${i}`;
153
+ const productId = getIntParameter(`productid${i}`) ?? deviceStorage.get(`productid${i}`, 0x8000);
154
+
155
+ const port = getIntParameter(`port${i}`) ?? defaultPort++;
156
+
157
+ const uniqueId =
158
+ getIntParameter(`uniqueid${i}`) ?? deviceStorage.get(`uniqueid${i}`, `${i}-${Time.nowMs()}`);
159
+
160
+ deviceStorage.set(`passcode${i}`, passcode);
161
+ deviceStorage.set(`discriminator${i}`, discriminator);
162
+ deviceStorage.set(`vendorid${i}`, vendorId);
163
+ deviceStorage.set(`productid${i}`, productId);
164
+ deviceStorage.set(`isSocket${i}`, isSocket);
165
+ deviceStorage.set(`uniqueid${i}`, uniqueId);
166
+
167
+ const commissioningServer = new CommissioningServer({
168
+ port,
169
+ deviceName,
170
+ deviceType,
171
+ passcode,
172
+ discriminator,
173
+ basicInformation: {
174
+ vendorName,
175
+ vendorId: VendorId(vendorId),
176
+ nodeLabel: productName,
177
+ productName,
178
+ productLabel: productName,
179
+ productId,
180
+ serialNumber: `node-matter-${uniqueId}`,
181
+ },
182
+ });
183
+
184
+ console.log(
185
+ `Added device ${i} on port ${port} and unique id ${uniqueId}: Passcode: ${passcode}, Discriminator: ${discriminator}`,
186
+ );
187
+
188
+ const onOffDevice =
189
+ getParameter(`type${i}`) === "socket" ? new OnOffPluginUnitDevice() : new OnOffLightDevice();
190
+ onOffDevice.addFixedLabel("orientation", getParameter(`orientation${i}`) ?? `orientation ${i}`);
191
+ onOffDevice.addOnOffListener(on => commandExecutor(on ? `on${i}` : `off${i}`)?.());
192
+ commissioningServer.addDevice(onOffDevice);
193
+
194
+ this.matterServer.addCommissioningServer(commissioningServer);
195
+
196
+ commissioningServers.push(commissioningServer);
197
+ }
198
+
199
+ /**
200
+ * Start the Matter Server
201
+ *
202
+ * After everything was plugged together we can start the server. When not delayed announcement is set for the
203
+ * CommissioningServer node then this command also starts the announcement of the device into the network.
204
+ */
205
+
206
+ await this.matterServer.start();
207
+
208
+ /**
209
+ * Print Pairing Information
210
+ *
211
+ * If the device is not already commissioned (this info is stored in the storage system) then get and print the
212
+ * pairing details. This includes the QR code that can be scanned by the Matter app to pair the device.
213
+ */
214
+
215
+ logger.info("Listening");
216
+ console.log();
217
+ commissioningServers.forEach((commissioningServer, index) => {
218
+ console.log("----------------------------");
219
+ console.log(`Device ${index + 1}:`);
220
+ if (!commissioningServer.isCommissioned()) {
221
+ const pairingData = commissioningServer.getPairingCode();
222
+ const { qrCode, qrPairingCode, manualPairingCode } = pairingData;
223
+
224
+ console.log(qrCode);
225
+ console.log(
226
+ `QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`,
227
+ );
228
+ console.log(`Manual pairing code: ${manualPairingCode}`);
229
+ } else {
230
+ console.log("Device is already commissioned. Waiting for controllers to connect ...");
231
+ }
232
+ console.log();
233
+ });
234
+ }
235
+
236
+ async stop() {
237
+ await this.matterServer?.close();
238
+ }
239
+ }
240
+
241
+ const device = new Device();
242
+ device
243
+ .start()
244
+ .then(() => {
245
+ /* done */
246
+ })
247
+ .catch(err => console.error(err));
248
+
249
+ process.on("SIGINT", () => {
250
+ device
251
+ .stop()
252
+ .then(() => {
253
+ // Pragmatic way to make sure the storage is correctly closed before the process ends.
254
+ storage
255
+ .close()
256
+ .then(() => process.exit(0))
257
+ .catch(err => console.error(err));
258
+ })
259
+ .catch(err => console.error(err));
260
+ });
@@ -0,0 +1,181 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 The node-matter Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import {
8
+ ClusterServer,
9
+ ClusterServerObjForCluster,
10
+ GeneralCommissioningCluster,
11
+ NetworkCommissioning,
12
+ } from "@project-chip/matter-node.js/cluster";
13
+ import { ByteArray, getParameter } from "@project-chip/matter-node.js/util";
14
+
15
+ const firstNetworkId = new ByteArray(32);
16
+
17
+ const WifiNetworkCluster = NetworkCommissioning.Cluster.with(NetworkCommissioning.Feature.WiFiNetworkInterface);
18
+
19
+ /**
20
+ * This represents a Dummy version of a Wifi Network Commissioning Cluster Server without real Wifi related logic, beside
21
+ * returning some values provided as CLI parameters. This dummy implementation is only there for tests/as showcase for BLE
22
+ * commissioning of a device.
23
+ */
24
+ export default ClusterServer(
25
+ NetworkCommissioning.Cluster.with(NetworkCommissioning.Feature.WiFiNetworkInterface),
26
+ {
27
+ maxNetworks: 1,
28
+ interfaceEnabled: true,
29
+ lastConnectErrorValue: 0,
30
+ lastNetworkId: null,
31
+ lastNetworkingStatus: null,
32
+ networks: [{ networkId: firstNetworkId, connected: false }],
33
+ scanMaxTimeSeconds: 3,
34
+ connectMaxTimeSeconds: 3,
35
+ },
36
+ {
37
+ scanNetworks: async ({ request: { ssid, breadcrumb }, attributes: { lastNetworkingStatus }, endpoint }) => {
38
+ console.log(`---> scanNetworks called on NetworkCommissioning cluster: ${ssid?.toHex()} ${breadcrumb}`);
39
+
40
+ // Simulate successful scan
41
+ if (breadcrumb !== undefined) {
42
+ const generalCommissioningCluster = endpoint.getClusterServer(GeneralCommissioningCluster);
43
+ generalCommissioningCluster?.setBreadcrumbAttribute(breadcrumb);
44
+ }
45
+
46
+ const networkingStatus = NetworkCommissioning.NetworkCommissioningStatus.Success;
47
+ lastNetworkingStatus?.setLocal(networkingStatus);
48
+
49
+ return {
50
+ networkingStatus,
51
+ wiFiScanResults: [
52
+ {
53
+ security: {
54
+ unencrypted: false,
55
+ wep: false,
56
+ wpaPersonal: false,
57
+ wpa2Personal: true,
58
+ wpa3Personal: true,
59
+ },
60
+ ssid: ssid || ByteArray.fromString(getParameter("ble-wifi-scan-ssid") ?? "TestSSID"), // Set a valid existing local Wi-Fi SSID here
61
+ bssid: ByteArray.fromString(getParameter("ble-wifi-scan-bssid") ?? "00:00:00:00:00:00"),
62
+ channel: 1,
63
+ },
64
+ ],
65
+ };
66
+ },
67
+ addOrUpdateWiFiNetwork: async ({
68
+ request: { ssid, credentials, breadcrumb },
69
+ attributes: { lastNetworkingStatus, lastNetworkId },
70
+ endpoint,
71
+ session,
72
+ }) => {
73
+ console.log(
74
+ `---> addOrUpdateWiFiNetwork called on NetworkCommissioning cluster: ${ssid.toHex()} ${credentials.toHex()} ${breadcrumb}`,
75
+ );
76
+
77
+ session.getContext().assertFailSafeArmed("Failsafe timer needs to be armed to add or update networks.");
78
+
79
+ // Simulate successful add or update
80
+ if (breadcrumb !== undefined) {
81
+ const generalCommissioningCluster = endpoint.getClusterServer(GeneralCommissioningCluster);
82
+ generalCommissioningCluster?.setBreadcrumbAttribute(breadcrumb);
83
+ }
84
+
85
+ const networkingStatus = NetworkCommissioning.NetworkCommissioningStatus.Success;
86
+ lastNetworkingStatus?.setLocal(networkingStatus);
87
+ lastNetworkId?.setLocal(firstNetworkId);
88
+
89
+ return {
90
+ networkingStatus: NetworkCommissioning.NetworkCommissioningStatus.Success,
91
+ networkIndex: 0,
92
+ };
93
+ },
94
+ removeNetwork: async ({
95
+ request: { networkId, breadcrumb },
96
+ attributes: { lastNetworkingStatus, lastNetworkId },
97
+ endpoint,
98
+ session,
99
+ }) => {
100
+ console.log(
101
+ `---> removeNetwork called on NetworkCommissioning cluster: ${networkId.toHex()} ${breadcrumb}`,
102
+ );
103
+
104
+ session.getContext().assertFailSafeArmed("Failsafe timer needs to be armed to add or update networks.");
105
+
106
+ // Simulate successful add or update
107
+ if (breadcrumb !== undefined) {
108
+ const generalCommissioningCluster = endpoint.getClusterServer(GeneralCommissioningCluster);
109
+ generalCommissioningCluster?.setBreadcrumbAttribute(breadcrumb);
110
+ }
111
+
112
+ const networkingStatus = NetworkCommissioning.NetworkCommissioningStatus.Success;
113
+ lastNetworkingStatus?.setLocal(networkingStatus);
114
+ lastNetworkId?.setLocal(firstNetworkId);
115
+
116
+ return {
117
+ networkingStatus: NetworkCommissioning.NetworkCommissioningStatus.Success,
118
+ networkIndex: 0,
119
+ };
120
+ },
121
+ connectNetwork: async ({
122
+ request: { networkId, breadcrumb },
123
+ attributes: { lastNetworkingStatus, lastNetworkId, lastConnectErrorValue, networks },
124
+ endpoint,
125
+ session,
126
+ }) => {
127
+ console.log(
128
+ `---> connectNetwork called on NetworkCommissioning cluster: ${networkId.toHex()} ${breadcrumb}`,
129
+ );
130
+
131
+ session.getContext().assertFailSafeArmed("Failsafe timer needs to be armed to add or update networks.");
132
+
133
+ // Simulate successful connection
134
+ if (breadcrumb !== undefined) {
135
+ const generalCommissioningCluster = endpoint.getClusterServer(GeneralCommissioningCluster);
136
+ generalCommissioningCluster?.setBreadcrumbAttribute(breadcrumb);
137
+ }
138
+
139
+ const networkList = networks.getLocal();
140
+ networkList[0].connected = true;
141
+ networks.setLocal(networkList);
142
+
143
+ const networkingStatus = NetworkCommissioning.NetworkCommissioningStatus.Success;
144
+ lastNetworkingStatus?.setLocal(networkingStatus);
145
+ lastNetworkId?.setLocal(firstNetworkId);
146
+ lastConnectErrorValue?.setLocal(null);
147
+
148
+ // Announce operational in IP network
149
+ const device = session.getContext();
150
+ await device.startAnnouncement();
151
+
152
+ return {
153
+ networkingStatus: NetworkCommissioning.NetworkCommissioningStatus.Success,
154
+ errorValue: null,
155
+ };
156
+ },
157
+ reorderNetwork: async ({
158
+ request: { networkId, networkIndex, breadcrumb },
159
+ attributes: { lastNetworkingStatus },
160
+ endpoint,
161
+ }) => {
162
+ console.log(
163
+ `---> reorderNetwork called on NetworkCommissioning cluster: ${networkId.toHex()} ${networkIndex} ${breadcrumb}`,
164
+ );
165
+
166
+ // Simulate successful connection
167
+ if (breadcrumb !== undefined) {
168
+ const generalCommissioningCluster = endpoint.getClusterServer(GeneralCommissioningCluster);
169
+ generalCommissioningCluster?.setBreadcrumbAttribute(breadcrumb);
170
+ }
171
+
172
+ const networkingStatus = NetworkCommissioning.NetworkCommissioningStatus.Success;
173
+ lastNetworkingStatus?.setLocal(networkingStatus);
174
+
175
+ return {
176
+ networkingStatus: NetworkCommissioning.NetworkCommissioningStatus.Success,
177
+ networkIndex: 0,
178
+ };
179
+ },
180
+ },
181
+ ) as ClusterServerObjForCluster<typeof WifiNetworkCluster>;
@@ -1,218 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * @license
5
- * Copyright 2022 The node-matter Authors
6
- * SPDX-License-Identifier: Apache-2.0
7
- */
8
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
- return new (P || (P = Promise))(function (resolve, reject) {
11
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
- step((generator = generator.apply(thisArg, _arguments || [])).next());
15
- });
16
- };
17
- var _a, _b;
18
- Object.defineProperty(exports, "__esModule", { value: true });
19
- /**
20
- * This example shows how to create a device bridge that exposed multiple devices.
21
- * It can be used as CLI script and starting point for your own device node implementation.
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
- const matter_node_js_1 = require("@project-chip/matter-node.js");
28
- const device_1 = require("@project-chip/matter-node.js/device");
29
- const log_1 = require("@project-chip/matter-node.js/log");
30
- const storage_1 = require("@project-chip/matter-node.js/storage");
31
- const time_1 = require("@project-chip/matter-node.js/time");
32
- const util_1 = require("@project-chip/matter-node.js/util");
33
- const datatype_1 = require("@project-chip/matter.js/datatype");
34
- const logger = log_1.Logger.get("Device");
35
- (0, util_1.requireMinNodeVersion)(16);
36
- /** Configure logging */
37
- switch ((0, util_1.getParameter)("loglevel")) {
38
- case "fatal":
39
- log_1.Logger.defaultLogLevel = log_1.Level.FATAL;
40
- break;
41
- case "error":
42
- log_1.Logger.defaultLogLevel = log_1.Level.ERROR;
43
- break;
44
- case "warn":
45
- log_1.Logger.defaultLogLevel = log_1.Level.WARN;
46
- break;
47
- case "info":
48
- log_1.Logger.defaultLogLevel = log_1.Level.INFO;
49
- break;
50
- }
51
- switch ((0, util_1.getParameter)("logformat")) {
52
- case "plain":
53
- log_1.Logger.format = log_1.Format.PLAIN;
54
- break;
55
- case "html":
56
- log_1.Logger.format = log_1.Format.HTML;
57
- break;
58
- default:
59
- if ((_a = process.stdin) === null || _a === void 0 ? void 0 : _a.isTTY)
60
- log_1.Logger.format = log_1.Format.ANSI;
61
- }
62
- const storageLocation = (_b = (0, util_1.getParameter)("store")) !== null && _b !== void 0 ? _b : ".device-node";
63
- const storage = new storage_1.StorageBackendDisk(storageLocation, (0, util_1.hasParameter)("clearstorage"));
64
- logger.info(`Storage location: ${storageLocation} (Directory)`);
65
- logger.info('Use the parameter "-store NAME" to specify a different storage location, use -clearstorage to start with an empty storage.');
66
- class BridgedDevice {
67
- start() {
68
- var _a, _b, _c, _d, _e, _f;
69
- return __awaiter(this, void 0, void 0, function* () {
70
- logger.info(`node-matter`);
71
- /**
72
- * Initialize the storage system.
73
- *
74
- * The storage manager is then also used by the Matter server, so this code block in general is required,
75
- * but you can choose a different storage backend as long as it implements the required API.
76
- */
77
- const storageManager = new storage_1.StorageManager(storage);
78
- yield storageManager.initialize();
79
- /**
80
- * Collect all needed data
81
- *
82
- * This block makes sure to collect all needed data from cli or storage. Replace this with where ever your data
83
- * come from.
84
- *
85
- * Note: This example also uses the initialized storage system to store the device parameter data for convenience
86
- * and easy reuse. When you also do that be careful to not overlap with Matter-Server own contexts
87
- * (so maybe better not ;-)).
88
- */
89
- const deviceStorage = storageManager.createContext("Device");
90
- const deviceName = "Matter Bridge device";
91
- const deviceType = device_1.DeviceTypes.AGGREGATOR.code;
92
- const vendorName = "matter-node.js";
93
- const passcode = (_a = (0, util_1.getIntParameter)("passcode")) !== null && _a !== void 0 ? _a : deviceStorage.get("passcode", 20202021);
94
- const discriminator = (_b = (0, util_1.getIntParameter)("discriminator")) !== null && _b !== void 0 ? _b : deviceStorage.get("discriminator", 3840);
95
- // product name / id and vendor id should match what is in the device certificate
96
- const vendorId = (_c = (0, util_1.getIntParameter)("vendorid")) !== null && _c !== void 0 ? _c : deviceStorage.get("vendorid", 0xfff1);
97
- const productName = `node-matter OnOff-Bridge`;
98
- const productId = (_d = (0, util_1.getIntParameter)("productid")) !== null && _d !== void 0 ? _d : deviceStorage.get("productid", 0x8000);
99
- const netAnnounceInterface = (0, util_1.getParameter)("announceinterface");
100
- const port = (_e = (0, util_1.getIntParameter)("port")) !== null && _e !== void 0 ? _e : 5540;
101
- const uniqueId = (_f = (0, util_1.getIntParameter)("uniqueid")) !== null && _f !== void 0 ? _f : deviceStorage.get("uniqueid", time_1.Time.nowMs());
102
- deviceStorage.set("passcode", passcode);
103
- deviceStorage.set("discriminator", discriminator);
104
- deviceStorage.set("vendorid", vendorId);
105
- deviceStorage.set("productid", productId);
106
- deviceStorage.set("uniqueid", uniqueId);
107
- /**
108
- * Create Matter Server and CommissioningServer Node
109
- *
110
- * To allow the device to be announced, found, paired and operated we need a MatterServer instance and add a
111
- * commissioningServer to it and add the just created device instance to it.
112
- * The CommissioningServer node defines the port where the server listens for the UDP packages of the Matter protocol
113
- * and initializes deice specific certificates and such.
114
- *
115
- * The below logic also adds command handlers for commands of clusters that normally are handled internally
116
- * like testEventTrigger (General Diagnostic Cluster) that can be implemented with the logic when these commands
117
- * are called.
118
- */
119
- this.matterServer = new matter_node_js_1.MatterServer(storageManager, netAnnounceInterface);
120
- const commissioningServer = new matter_node_js_1.CommissioningServer({
121
- port,
122
- deviceName,
123
- deviceType,
124
- passcode,
125
- discriminator,
126
- basicInformation: {
127
- vendorName,
128
- vendorId: (0, datatype_1.VendorId)(vendorId),
129
- nodeLabel: productName,
130
- productName,
131
- productLabel: productName,
132
- productId,
133
- serialNumber: `node-matter-${uniqueId}`,
134
- },
135
- });
136
- /**
137
- * Create Device instance and add needed Listener
138
- *
139
- * Create an instance of the matter device class you want to use.
140
- * This example uses the OnOffLightDevice or OnOffPluginUnitDevice depending on the value of the type parameter.
141
- * To execute the on/off scripts defined as parameters a listener for the onOff attribute is registered via the
142
- * device specific API.
143
- *
144
- * The below logic also adds command handlers for commands of clusters that normally are handled device internally
145
- * like identify that can be implemented with the logic when these commands are called.
146
- */
147
- const aggregator = new device_1.Aggregator();
148
- const numDevices = (0, util_1.getIntParameter)("num") || 2;
149
- for (let i = 1; i <= numDevices; i++) {
150
- const onOffDevice = (0, util_1.getParameter)(`type${i}`) === "socket" ? new device_1.OnOffPluginUnitDevice() : new device_1.OnOffLightDevice();
151
- onOffDevice.addOnOffListener(on => { var _a; return (_a = (0, util_1.commandExecutor)(on ? `on${i}` : `off${i}`)) === null || _a === void 0 ? void 0 : _a(); });
152
- onOffDevice.addCommandHandler("identify", ({ request: { identifyTime } }) => __awaiter(this, void 0, void 0, function* () {
153
- return console.log(`Identify called for OnOffDevice ${onOffDevice.name} with id: ${i} and identifyTime: ${identifyTime}`);
154
- }));
155
- const name = `OnOff ${onOffDevice instanceof device_1.OnOffPluginUnitDevice ? "Socket" : "Light"} ${i}`;
156
- aggregator.addBridgedDevice(onOffDevice, {
157
- nodeLabel: name,
158
- productName: name,
159
- productLabel: name,
160
- serialNumber: `node-matter-${uniqueId}-${i}`,
161
- reachable: true,
162
- });
163
- }
164
- commissioningServer.addDevice(aggregator);
165
- this.matterServer.addCommissioningServer(commissioningServer);
166
- /**
167
- * Start the Matter Server
168
- *
169
- * After everything was plugged together we can start the server. When not delayed announcement is set for the
170
- * CommissioningServer node then this command also starts the announcement of the device into the network.
171
- */
172
- yield this.matterServer.start();
173
- /**
174
- * Print Pairing Information
175
- *
176
- * If the device is not already commissioned (this info is stored in the storage system) then get and print the
177
- * pairing details. This includes the QR code that can be scanned by the Matter app to pair the device.
178
- */
179
- logger.info("Listening");
180
- if (!commissioningServer.isCommissioned()) {
181
- const pairingData = commissioningServer.getPairingCode();
182
- const { qrCode, qrPairingCode, manualPairingCode } = pairingData;
183
- console.log(qrCode);
184
- console.log(`QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`);
185
- console.log(`Manual pairing code: ${manualPairingCode}`);
186
- }
187
- else {
188
- console.log("Device is already commissioned. Waiting for controllers to connect ...");
189
- }
190
- });
191
- }
192
- stop() {
193
- var _a;
194
- return __awaiter(this, void 0, void 0, function* () {
195
- yield ((_a = this.matterServer) === null || _a === void 0 ? void 0 : _a.close());
196
- });
197
- }
198
- }
199
- const device = new BridgedDevice();
200
- device
201
- .start()
202
- .then(() => {
203
- /* done */
204
- })
205
- .catch(err => console.error(err));
206
- process.on("SIGINT", () => {
207
- device
208
- .stop()
209
- .then(() => {
210
- // Pragmatic way to make sure the storage is correctly closed before the process ends.
211
- storage
212
- .close()
213
- .then(() => process.exit(0))
214
- .catch(err => console.error(err));
215
- })
216
- .catch(err => console.error(err));
217
- });
218
- //# sourceMappingURL=BridgedDevicesNode.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BridgedDevicesNode.js","sourceRoot":"","sources":["../../src/examples/BridgedDevicesNode.ts"],"names":[],"mappings":"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"}