@project-chip/matter-node.js-examples 0.6.1-alpha.0-20231031-f3417b3 → 0.6.1-alpha.0-20231101-4ef32c9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @license
4
+ * Copyright 2022 The node-matter Authors
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+ import { CommissioningServer, MatterServer } from "@project-chip/matter-node.js";
8
+ import { VendorId } from "@project-chip/matter-node.js/datatype";
9
+ import { Aggregator, DeviceTypes, OnOffLightDevice, OnOffPluginUnitDevice } from "@project-chip/matter-node.js/device";
10
+ import { Format, Level, Logger } from "@project-chip/matter-node.js/log";
11
+ import { QrCode } from "@project-chip/matter-node.js/schema";
12
+ import { StorageBackendDisk, StorageManager } from "@project-chip/matter-node.js/storage";
13
+ import { Time } from "@project-chip/matter-node.js/time";
14
+ import {
15
+ commandExecutor,
16
+ getIntParameter,
17
+ getParameter,
18
+ hasParameter,
19
+ requireMinNodeVersion
20
+ } from "@project-chip/matter-node.js/util";
21
+ const logger = Logger.get("Device");
22
+ requireMinNodeVersion(16);
23
+ switch (getParameter("loglevel")) {
24
+ case "fatal":
25
+ Logger.defaultLogLevel = Level.FATAL;
26
+ break;
27
+ case "error":
28
+ Logger.defaultLogLevel = Level.ERROR;
29
+ break;
30
+ case "warn":
31
+ Logger.defaultLogLevel = Level.WARN;
32
+ break;
33
+ case "info":
34
+ Logger.defaultLogLevel = Level.INFO;
35
+ break;
36
+ }
37
+ switch (getParameter("logformat")) {
38
+ case "plain":
39
+ Logger.format = Format.PLAIN;
40
+ break;
41
+ case "html":
42
+ Logger.format = Format.HTML;
43
+ break;
44
+ default:
45
+ if (process.stdin?.isTTY)
46
+ Logger.format = Format.ANSI;
47
+ }
48
+ const storageLocation = getParameter("store") ?? ".device-node";
49
+ const storage = new StorageBackendDisk(storageLocation, hasParameter("clearstorage"));
50
+ logger.info(`Storage location: ${storageLocation} (Directory)`);
51
+ logger.info(
52
+ 'Use the parameter "-store NAME" to specify a different storage location, use -clearstorage to start with an empty storage.'
53
+ );
54
+ class BridgedDevice {
55
+ async start() {
56
+ logger.info(`node-matter`);
57
+ const storageManager = new StorageManager(storage);
58
+ await storageManager.initialize();
59
+ const deviceStorage = storageManager.createContext("Device");
60
+ const deviceName = "Matter Bridge device";
61
+ const deviceType = DeviceTypes.AGGREGATOR.code;
62
+ const vendorName = "matter-node.js";
63
+ const passcode = getIntParameter("passcode") ?? deviceStorage.get("passcode", 20202021);
64
+ const discriminator = getIntParameter("discriminator") ?? deviceStorage.get("discriminator", 3840);
65
+ const vendorId = getIntParameter("vendorid") ?? deviceStorage.get("vendorid", 65521);
66
+ const productName = `node-matter OnOff-Bridge`;
67
+ const productId = getIntParameter("productid") ?? deviceStorage.get("productid", 32768);
68
+ const netAnnounceInterface = getParameter("announceinterface");
69
+ const port = getIntParameter("port") ?? 5540;
70
+ const uniqueId = getIntParameter("uniqueid") ?? deviceStorage.get("uniqueid", Time.nowMs());
71
+ deviceStorage.set("passcode", passcode);
72
+ deviceStorage.set("discriminator", discriminator);
73
+ deviceStorage.set("vendorid", vendorId);
74
+ deviceStorage.set("productid", productId);
75
+ deviceStorage.set("uniqueid", uniqueId);
76
+ this.matterServer = new MatterServer(storageManager, { mdnsAnnounceInterface: netAnnounceInterface });
77
+ const commissioningServer = new CommissioningServer({
78
+ port,
79
+ deviceName,
80
+ deviceType,
81
+ passcode,
82
+ discriminator,
83
+ basicInformation: {
84
+ vendorName,
85
+ vendorId: VendorId(vendorId),
86
+ nodeLabel: productName,
87
+ productName,
88
+ productLabel: productName,
89
+ productId,
90
+ serialNumber: `node-matter-${uniqueId}`
91
+ }
92
+ });
93
+ const aggregator = new Aggregator();
94
+ const numDevices = getIntParameter("num") || 2;
95
+ for (let i = 1; i <= numDevices; i++) {
96
+ const onOffDevice = getParameter(`type${i}`) === "socket" ? new OnOffPluginUnitDevice() : new OnOffLightDevice();
97
+ onOffDevice.addOnOffListener((on) => commandExecutor(on ? `on${i}` : `off${i}`)?.());
98
+ onOffDevice.addCommandHandler(
99
+ "identify",
100
+ async ({ request: { identifyTime } }) => console.log(
101
+ `Identify called for OnOffDevice ${onOffDevice.name} with id: ${i} and identifyTime: ${identifyTime}`
102
+ )
103
+ );
104
+ const name = `OnOff ${onOffDevice instanceof OnOffPluginUnitDevice ? "Socket" : "Light"} ${i}`;
105
+ aggregator.addBridgedDevice(onOffDevice, {
106
+ nodeLabel: name,
107
+ productName: name,
108
+ productLabel: name,
109
+ serialNumber: `node-matter-${uniqueId}-${i}`,
110
+ reachable: true
111
+ });
112
+ }
113
+ commissioningServer.addDevice(aggregator);
114
+ this.matterServer.addCommissioningServer(commissioningServer);
115
+ await this.matterServer.start();
116
+ logger.info("Listening");
117
+ if (!commissioningServer.isCommissioned()) {
118
+ const pairingData = commissioningServer.getPairingCode();
119
+ const { qrPairingCode, manualPairingCode } = pairingData;
120
+ console.log(QrCode.get(qrPairingCode));
121
+ console.log(
122
+ `QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`
123
+ );
124
+ console.log(`Manual pairing code: ${manualPairingCode}`);
125
+ } else {
126
+ console.log("Device is already commissioned. Waiting for controllers to connect ...");
127
+ }
128
+ }
129
+ async stop() {
130
+ await this.matterServer?.close();
131
+ }
132
+ }
133
+ const device = new BridgedDevice();
134
+ device.start().then(() => {
135
+ }).catch((err) => console.error(err));
136
+ process.on("SIGINT", () => {
137
+ device.stop().then(() => {
138
+ storage.close().then(() => process.exit(0)).catch((err) => console.error(err));
139
+ }).catch((err) => console.error(err));
140
+ });
141
+ //# sourceMappingURL=BridgedDevicesNode.js.map
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/examples/BridgedDevicesNode.ts"],
4
4
  "sourcesContent": ["#!/usr/bin/env node\n/**\n * @license\n * Copyright 2022 The node-matter Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * This example shows how to create a device bridge that exposed multiple devices.\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 { CommissioningServer, MatterServer } from \"@project-chip/matter-node.js\";\n\nimport { VendorId } from \"@project-chip/matter-node.js/datatype\";\nimport { Aggregator, DeviceTypes, OnOffLightDevice, OnOffPluginUnitDevice } from \"@project-chip/matter-node.js/device\";\nimport { Format, Level, Logger } from \"@project-chip/matter-node.js/log\";\nimport { QrCode } from \"@project-chip/matter-node.js/schema\";\nimport { StorageBackendDisk, StorageManager } from \"@project-chip/matter-node.js/storage\";\nimport { Time } from \"@project-chip/matter-node.js/time\";\nimport {\n commandExecutor,\n getIntParameter,\n getParameter,\n hasParameter,\n requireMinNodeVersion,\n} from \"@project-chip/matter-node.js/util\";\n\nconst logger = Logger.get(\"Device\");\n\nrequireMinNodeVersion(16);\n\n/** Configure logging */\nswitch (getParameter(\"loglevel\")) {\n case \"fatal\":\n Logger.defaultLogLevel = Level.FATAL;\n break;\n case \"error\":\n Logger.defaultLogLevel = Level.ERROR;\n break;\n case \"warn\":\n Logger.defaultLogLevel = Level.WARN;\n break;\n case \"info\":\n Logger.defaultLogLevel = Level.INFO;\n break;\n}\n\nswitch (getParameter(\"logformat\")) {\n case \"plain\":\n Logger.format = Format.PLAIN;\n break;\n case \"html\":\n Logger.format = Format.HTML;\n break;\n default:\n if (process.stdin?.isTTY) Logger.format = Format.ANSI;\n}\n\nconst storageLocation = getParameter(\"store\") ?? \".device-node\";\nconst storage = new StorageBackendDisk(storageLocation, hasParameter(\"clearstorage\"));\nlogger.info(`Storage location: ${storageLocation} (Directory)`);\nlogger.info(\n 'Use the parameter \"-store NAME\" to specify a different storage location, use -clearstorage to start with an empty storage.',\n);\n\nclass BridgedDevice {\n private matterServer: MatterServer | undefined;\n\n async start() {\n logger.info(`node-matter`);\n\n /**\n * Initialize the storage system.\n *\n * The storage manager is then also used by the Matter server, so this code block in general is required,\n * but you can choose a different storage backend as long as it implements the required API.\n */\n\n const storageManager = new StorageManager(storage);\n await storageManager.initialize();\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 deviceStorage = storageManager.createContext(\"Device\");\n\n const deviceName = \"Matter Bridge device\";\n const deviceType = DeviceTypes.AGGREGATOR.code;\n const vendorName = \"matter-node.js\";\n const passcode = getIntParameter(\"passcode\") ?? deviceStorage.get(\"passcode\", 20202021);\n const discriminator = getIntParameter(\"discriminator\") ?? deviceStorage.get(\"discriminator\", 3840);\n // product name / id and vendor id should match what is in the device certificate\n const vendorId = getIntParameter(\"vendorid\") ?? deviceStorage.get(\"vendorid\", 0xfff1);\n const productName = `node-matter OnOff-Bridge`;\n const productId = getIntParameter(\"productid\") ?? deviceStorage.get(\"productid\", 0x8000);\n\n const netAnnounceInterface = getParameter(\"announceinterface\");\n const port = getIntParameter(\"port\") ?? 5540;\n\n const uniqueId = getIntParameter(\"uniqueid\") ?? deviceStorage.get(\"uniqueid\", Time.nowMs());\n\n deviceStorage.set(\"passcode\", passcode);\n deviceStorage.set(\"discriminator\", discriminator);\n deviceStorage.set(\"vendorid\", vendorId);\n deviceStorage.set(\"productid\", productId);\n deviceStorage.set(\"uniqueid\", uniqueId);\n\n /**\n * Create Matter Server and CommissioningServer Node\n *\n * To allow the device to be announced, found, paired and operated we need a MatterServer instance and add a\n * commissioningServer to it and add the just created device instance to it.\n * The CommissioningServer 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 this.matterServer = new MatterServer(storageManager, { mdnsAnnounceInterface: netAnnounceInterface });\n\n const commissioningServer = new CommissioningServer({\n port,\n deviceName,\n deviceType,\n passcode,\n discriminator,\n basicInformation: {\n vendorName,\n vendorId: VendorId(vendorId),\n nodeLabel: productName,\n productName,\n productLabel: productName,\n productId,\n serialNumber: `node-matter-${uniqueId}`,\n },\n });\n\n /**\n * Create Device instance and add needed Listener\n *\n * Create an instance of the matter device class you want to use.\n * This example uses the OnOffLightDevice or OnOffPluginUnitDevice depending on the value of the type parameter.\n * To execute the on/off scripts defined as parameters a listener for the onOff attribute is registered via the\n * device specific API.\n *\n * The below logic also adds command handlers for commands of clusters that normally are handled device internally\n * like identify that can be implemented with the logic when these commands are called.\n */\n\n const aggregator = new Aggregator();\n\n const numDevices = getIntParameter(\"num\") || 2;\n for (let i = 1; i <= numDevices; i++) {\n const onOffDevice =\n getParameter(`type${i}`) === \"socket\" ? new OnOffPluginUnitDevice() : new OnOffLightDevice();\n\n onOffDevice.addOnOffListener(on => commandExecutor(on ? `on${i}` : `off${i}`)?.());\n onOffDevice.addCommandHandler(\"identify\", async ({ request: { identifyTime } }) =>\n console.log(\n `Identify called for OnOffDevice ${onOffDevice.name} with id: ${i} and identifyTime: ${identifyTime}`,\n ),\n );\n\n const name = `OnOff ${onOffDevice instanceof OnOffPluginUnitDevice ? \"Socket\" : \"Light\"} ${i}`;\n aggregator.addBridgedDevice(onOffDevice, {\n nodeLabel: name,\n productName: name,\n productLabel: name,\n serialNumber: `node-matter-${uniqueId}-${i}`,\n reachable: true,\n });\n }\n\n commissioningServer.addDevice(aggregator);\n\n this.matterServer.addCommissioningServer(commissioningServer);\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\n await this.matterServer.start();\n\n /**\n * Print Pairing Information\n *\n * If the device is not already commissioned (this info is stored in the storage system) then get and print the\n * pairing details. This includes the QR code that can be scanned by the Matter app to pair the device.\n */\n\n logger.info(\"Listening\");\n if (!commissioningServer.isCommissioned()) {\n const pairingData = commissioningServer.getPairingCode();\n const { qrPairingCode, manualPairingCode } = pairingData;\n\n console.log(QrCode.get(qrPairingCode));\n console.log(\n `QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`,\n );\n console.log(`Manual pairing code: ${manualPairingCode}`);\n } else {\n console.log(\"Device is already commissioned. Waiting for controllers to connect ...\");\n }\n }\n\n async stop() {\n await this.matterServer?.close();\n }\n}\n\nconst device = new BridgedDevice();\ndevice\n .start()\n .then(() => {\n /* done */\n })\n .catch(err => console.error(err));\n\nprocess.on(\"SIGINT\", () => {\n device\n .stop()\n .then(() => {\n // Pragmatic way to make sure the storage is correctly closed before the process ends.\n storage\n .close()\n .then(() => process.exit(0))\n .catch(err => console.error(err));\n })\n .catch(err => console.error(err));\n});\n"],
5
- "mappings": "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",
5
+ "mappings": ";AACA;AAAA;AAAA;AAAA;AAAA;AAeA,SAAS,qBAAqB,oBAAoB;AAElD,SAAS,gBAAgB;AACzB,SAAS,YAAY,aAAa,kBAAkB,6BAA6B;AACjF,SAAS,QAAQ,OAAO,cAAc;AACtC,SAAS,cAAc;AACvB,SAAS,oBAAoB,sBAAsB;AACnD,SAAS,YAAY;AACrB;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAEP,MAAM,SAAS,OAAO,IAAI,QAAQ;AAElC,sBAAsB,EAAE;AAGxB,QAAQ,aAAa,UAAU,GAAG;AAAA,EAC9B,KAAK;AACD,WAAO,kBAAkB,MAAM;AAC/B;AAAA,EACJ,KAAK;AACD,WAAO,kBAAkB,MAAM;AAC/B;AAAA,EACJ,KAAK;AACD,WAAO,kBAAkB,MAAM;AAC/B;AAAA,EACJ,KAAK;AACD,WAAO,kBAAkB,MAAM;AAC/B;AACR;AAEA,QAAQ,aAAa,WAAW,GAAG;AAAA,EAC/B,KAAK;AACD,WAAO,SAAS,OAAO;AACvB;AAAA,EACJ,KAAK;AACD,WAAO,SAAS,OAAO;AACvB;AAAA,EACJ;AACI,QAAI,QAAQ,OAAO;AAAO,aAAO,SAAS,OAAO;AACzD;AAEA,MAAM,kBAAkB,aAAa,OAAO,KAAK;AACjD,MAAM,UAAU,IAAI,mBAAmB,iBAAiB,aAAa,cAAc,CAAC;AACpF,OAAO,KAAK,qBAAqB,eAAe,cAAc;AAC9D,OAAO;AAAA,EACH;AACJ;AAEA,MAAM,cAAc;AAAA,EAGhB,MAAM,QAAQ;AACV,WAAO,KAAK,aAAa;AASzB,UAAM,iBAAiB,IAAI,eAAe,OAAO;AACjD,UAAM,eAAe,WAAW;AAahC,UAAM,gBAAgB,eAAe,cAAc,QAAQ;AAE3D,UAAM,aAAa;AACnB,UAAM,aAAa,YAAY,WAAW;AAC1C,UAAM,aAAa;AACnB,UAAM,WAAW,gBAAgB,UAAU,KAAK,cAAc,IAAI,YAAY,QAAQ;AACtF,UAAM,gBAAgB,gBAAgB,eAAe,KAAK,cAAc,IAAI,iBAAiB,IAAI;AAEjG,UAAM,WAAW,gBAAgB,UAAU,KAAK,cAAc,IAAI,YAAY,KAAM;AACpF,UAAM,cAAc;AACpB,UAAM,YAAY,gBAAgB,WAAW,KAAK,cAAc,IAAI,aAAa,KAAM;AAEvF,UAAM,uBAAuB,aAAa,mBAAmB;AAC7D,UAAM,OAAO,gBAAgB,MAAM,KAAK;AAExC,UAAM,WAAW,gBAAgB,UAAU,KAAK,cAAc,IAAI,YAAY,KAAK,MAAM,CAAC;AAE1F,kBAAc,IAAI,YAAY,QAAQ;AACtC,kBAAc,IAAI,iBAAiB,aAAa;AAChD,kBAAc,IAAI,YAAY,QAAQ;AACtC,kBAAc,IAAI,aAAa,SAAS;AACxC,kBAAc,IAAI,YAAY,QAAQ;AAetC,SAAK,eAAe,IAAI,aAAa,gBAAgB,EAAE,uBAAuB,qBAAqB,CAAC;AAEpG,UAAM,sBAAsB,IAAI,oBAAoB;AAAA,MAChD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,QACd;AAAA,QACA,UAAU,SAAS,QAAQ;AAAA,QAC3B,WAAW;AAAA,QACX;AAAA,QACA,cAAc;AAAA,QACd;AAAA,QACA,cAAc,eAAe,QAAQ;AAAA,MACzC;AAAA,IACJ,CAAC;AAcD,UAAM,aAAa,IAAI,WAAW;AAElC,UAAM,aAAa,gBAAgB,KAAK,KAAK;AAC7C,aAAS,IAAI,GAAG,KAAK,YAAY,KAAK;AAClC,YAAM,cACF,aAAa,OAAO,CAAC,EAAE,MAAM,WAAW,IAAI,sBAAsB,IAAI,IAAI,iBAAiB;AAE/F,kBAAY,iBAAiB,QAAM,gBAAgB,KAAK,KAAK,CAAC,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC;AACjF,kBAAY;AAAA,QAAkB;AAAA,QAAY,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MACzE,QAAQ;AAAA,UACJ,mCAAmC,YAAY,IAAI,aAAa,CAAC,sBAAsB,YAAY;AAAA,QACvG;AAAA,MACJ;AAEA,YAAM,OAAO,SAAS,uBAAuB,wBAAwB,WAAW,OAAO,IAAI,CAAC;AAC5F,iBAAW,iBAAiB,aAAa;AAAA,QACrC,WAAW;AAAA,QACX,aAAa;AAAA,QACb,cAAc;AAAA,QACd,cAAc,eAAe,QAAQ,IAAI,CAAC;AAAA,QAC1C,WAAW;AAAA,MACf,CAAC;AAAA,IACL;AAEA,wBAAoB,UAAU,UAAU;AAExC,SAAK,aAAa,uBAAuB,mBAAmB;AAS5D,UAAM,KAAK,aAAa,MAAM;AAS9B,WAAO,KAAK,WAAW;AACvB,QAAI,CAAC,oBAAoB,eAAe,GAAG;AACvC,YAAM,cAAc,oBAAoB,eAAe;AACvD,YAAM,EAAE,eAAe,kBAAkB,IAAI;AAE7C,cAAQ,IAAI,OAAO,IAAI,aAAa,CAAC;AACrC,cAAQ;AAAA,QACJ,gFAAgF,aAAa;AAAA,MACjG;AACA,cAAQ,IAAI,wBAAwB,iBAAiB,EAAE;AAAA,IAC3D,OAAO;AACH,cAAQ,IAAI,wEAAwE;AAAA,IACxF;AAAA,EACJ;AAAA,EAEA,MAAM,OAAO;AACT,UAAM,KAAK,cAAc,MAAM;AAAA,EACnC;AACJ;AAEA,MAAM,SAAS,IAAI,cAAc;AACjC,OACK,MAAM,EACN,KAAK,MAAM;AAEZ,CAAC,EACA,MAAM,SAAO,QAAQ,MAAM,GAAG,CAAC;AAEpC,QAAQ,GAAG,UAAU,MAAM;AACvB,SACK,KAAK,EACL,KAAK,MAAM;AAER,YACK,MAAM,EACN,KAAK,MAAM,QAAQ,KAAK,CAAC,CAAC,EAC1B,MAAM,SAAO,QAAQ,MAAM,GAAG,CAAC;AAAA,EACxC,CAAC,EACA,MAAM,SAAO,QAAQ,MAAM,GAAG,CAAC;AACxC,CAAC;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @license
4
+ * Copyright 2022 The node-matter Authors
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+ import { CommissioningServer, MatterServer } from "@project-chip/matter-node.js";
8
+ import { VendorId } from "@project-chip/matter-node.js/datatype";
9
+ import { DeviceTypes, OnOffLightDevice, OnOffPluginUnitDevice } from "@project-chip/matter-node.js/device";
10
+ import { Format, Level, Logger } from "@project-chip/matter-node.js/log";
11
+ import { QrCode } from "@project-chip/matter-node.js/schema";
12
+ import { StorageBackendDisk, StorageManager } from "@project-chip/matter-node.js/storage";
13
+ import { Time } from "@project-chip/matter-node.js/time";
14
+ import {
15
+ commandExecutor,
16
+ getIntParameter,
17
+ getParameter,
18
+ hasParameter,
19
+ requireMinNodeVersion
20
+ } from "@project-chip/matter-node.js/util";
21
+ const logger = Logger.get("Device");
22
+ requireMinNodeVersion(16);
23
+ switch (getParameter("loglevel")) {
24
+ case "fatal":
25
+ Logger.defaultLogLevel = Level.FATAL;
26
+ break;
27
+ case "error":
28
+ Logger.defaultLogLevel = Level.ERROR;
29
+ break;
30
+ case "warn":
31
+ Logger.defaultLogLevel = Level.WARN;
32
+ break;
33
+ case "info":
34
+ Logger.defaultLogLevel = Level.INFO;
35
+ break;
36
+ }
37
+ switch (getParameter("logformat")) {
38
+ case "plain":
39
+ Logger.format = Format.PLAIN;
40
+ break;
41
+ case "html":
42
+ Logger.format = Format.HTML;
43
+ break;
44
+ default:
45
+ if (process.stdin?.isTTY)
46
+ Logger.format = Format.ANSI;
47
+ }
48
+ const storageLocation = getParameter("store") ?? ".device-node";
49
+ const storage = new StorageBackendDisk(storageLocation, hasParameter("clearstorage"));
50
+ logger.info(`Storage location: ${storageLocation} (Directory)`);
51
+ logger.info(
52
+ 'Use the parameter "-store NAME" to specify a different storage location, use -clearstorage to start with an empty storage.'
53
+ );
54
+ class ComposedDevice {
55
+ async start() {
56
+ logger.info(`node-matter`);
57
+ const storageManager = new StorageManager(storage);
58
+ await storageManager.initialize();
59
+ const deviceStorage = storageManager.createContext("Device");
60
+ if (deviceStorage.has("isSocket")) {
61
+ logger.info("Device type found in storage. -type parameter is ignored.");
62
+ }
63
+ const isSocket = deviceStorage.get("isSocket", getParameter("type") === "socket");
64
+ const deviceName = "Matter composed device";
65
+ const deviceType = getParameter("type") === "socket" ? DeviceTypes.ON_OFF_PLUGIN_UNIT.code : DeviceTypes.ON_OFF_LIGHT.code;
66
+ const vendorName = "matter-node.js";
67
+ const passcode = getIntParameter("passcode") ?? deviceStorage.get("passcode", 20202021);
68
+ const discriminator = getIntParameter("discriminator") ?? deviceStorage.get("discriminator", 3840);
69
+ const vendorId = getIntParameter("vendorid") ?? deviceStorage.get("vendorid", 65521);
70
+ const productName = `node-matter OnOff-Bridge`;
71
+ const productId = getIntParameter("productid") ?? deviceStorage.get("productid", 32768);
72
+ const netAnnounceInterface = getParameter("announceinterface");
73
+ const port = getIntParameter("port") ?? 5540;
74
+ const uniqueId = getIntParameter("uniqueid") ?? deviceStorage.get("uniqueid", Time.nowMs());
75
+ deviceStorage.set("passcode", passcode);
76
+ deviceStorage.set("discriminator", discriminator);
77
+ deviceStorage.set("vendorid", vendorId);
78
+ deviceStorage.set("productid", productId);
79
+ deviceStorage.set("isSocket", isSocket);
80
+ deviceStorage.set("uniqueid", uniqueId);
81
+ this.matterServer = new MatterServer(storageManager, { mdnsAnnounceInterface: netAnnounceInterface });
82
+ const commissioningServer = new CommissioningServer({
83
+ port,
84
+ deviceName,
85
+ deviceType,
86
+ passcode,
87
+ discriminator,
88
+ basicInformation: {
89
+ vendorName,
90
+ vendorId: VendorId(vendorId),
91
+ nodeLabel: productName,
92
+ productName,
93
+ productLabel: productName,
94
+ productId,
95
+ serialNumber: `node-matter-${uniqueId}`
96
+ }
97
+ });
98
+ const numDevices = getIntParameter("num") || 2;
99
+ for (let i = 1; i <= numDevices; i++) {
100
+ const onOffDevice = getParameter(`type${i}`) === "socket" ? new OnOffPluginUnitDevice() : new OnOffLightDevice();
101
+ onOffDevice.addFixedLabel("orientation", getParameter(`orientation${i}`) ?? `orientation ${i}`);
102
+ onOffDevice.addOnOffListener((on) => commandExecutor(on ? `on${i}` : `off${i}`)?.());
103
+ onOffDevice.addCommandHandler(
104
+ "identify",
105
+ async ({ request: { identifyTime } }) => console.log(
106
+ `Identify called for OnOffDevice ${onOffDevice.name} with id: ${i} and identifyTime: ${identifyTime}`
107
+ )
108
+ );
109
+ commissioningServer.addDevice(onOffDevice);
110
+ }
111
+ this.matterServer.addCommissioningServer(commissioningServer);
112
+ await this.matterServer.start();
113
+ logger.info("Listening");
114
+ if (!commissioningServer.isCommissioned()) {
115
+ const pairingData = commissioningServer.getPairingCode();
116
+ const { qrPairingCode, manualPairingCode } = pairingData;
117
+ console.log(QrCode.get(qrPairingCode));
118
+ console.log(
119
+ `QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`
120
+ );
121
+ console.log(`Manual pairing code: ${manualPairingCode}`);
122
+ } else {
123
+ console.log("Device is already commissioned. Waiting for controllers to connect ...");
124
+ }
125
+ }
126
+ async stop() {
127
+ await this.matterServer?.close();
128
+ }
129
+ }
130
+ const device = new ComposedDevice();
131
+ device.start().then(() => {
132
+ }).catch((err) => console.error(err));
133
+ process.on("SIGINT", () => {
134
+ device.stop().then(() => {
135
+ storage.close().then(() => process.exit(0)).catch((err) => console.error(err));
136
+ }).catch((err) => console.error(err));
137
+ });
138
+ //# sourceMappingURL=ComposedDeviceNode.js.map
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/examples/ComposedDeviceNode.ts"],
4
4
  "sourcesContent": ["#!/usr/bin/env node\n/**\n * @license\n * Copyright 2022 The node-matter 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. When you want to add a composed devices to a Aggregator you need to\n * add all endpoints of the composed device to an \"ComposedDevice\" instance! (not shown in this 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 { CommissioningServer, MatterServer } from \"@project-chip/matter-node.js\";\n\nimport { VendorId } from \"@project-chip/matter-node.js/datatype\";\nimport { DeviceTypes, OnOffLightDevice, OnOffPluginUnitDevice } from \"@project-chip/matter-node.js/device\";\nimport { Format, Level, Logger } from \"@project-chip/matter-node.js/log\";\nimport { QrCode } from \"@project-chip/matter-node.js/schema\";\nimport { StorageBackendDisk, StorageManager } from \"@project-chip/matter-node.js/storage\";\nimport { Time } from \"@project-chip/matter-node.js/time\";\nimport {\n commandExecutor,\n getIntParameter,\n getParameter,\n hasParameter,\n requireMinNodeVersion,\n} from \"@project-chip/matter-node.js/util\";\n\nconst logger = Logger.get(\"Device\");\n\nrequireMinNodeVersion(16);\n\n/** Configure logging */\nswitch (getParameter(\"loglevel\")) {\n case \"fatal\":\n Logger.defaultLogLevel = Level.FATAL;\n break;\n case \"error\":\n Logger.defaultLogLevel = Level.ERROR;\n break;\n case \"warn\":\n Logger.defaultLogLevel = Level.WARN;\n break;\n case \"info\":\n Logger.defaultLogLevel = Level.INFO;\n break;\n}\n\nswitch (getParameter(\"logformat\")) {\n case \"plain\":\n Logger.format = Format.PLAIN;\n break;\n case \"html\":\n Logger.format = Format.HTML;\n break;\n default:\n if (process.stdin?.isTTY) Logger.format = Format.ANSI;\n}\n\nconst storageLocation = getParameter(\"store\") ?? \".device-node\";\nconst storage = new StorageBackendDisk(storageLocation, hasParameter(\"clearstorage\"));\nlogger.info(`Storage location: ${storageLocation} (Directory)`);\nlogger.info(\n 'Use the parameter \"-store NAME\" to specify a different storage location, use -clearstorage to start with an empty storage.',\n);\n\nclass ComposedDevice {\n private matterServer: MatterServer | undefined;\n\n async start() {\n logger.info(`node-matter`);\n\n /**\n * Initialize the storage system.\n *\n * The storage manager is then also used by the Matter server, so this code block in general is required,\n * but you can choose a different storage backend as long as it implements the required API.\n */\n\n const storageManager = new StorageManager(storage);\n await storageManager.initialize();\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 deviceStorage = storageManager.createContext(\"Device\");\n\n if (deviceStorage.has(\"isSocket\")) {\n logger.info(\"Device type found in storage. -type parameter is ignored.\");\n }\n const isSocket = deviceStorage.get(\"isSocket\", getParameter(\"type\") === \"socket\");\n const deviceName = \"Matter composed device\";\n const deviceType =\n getParameter(\"type\") === \"socket\" ? DeviceTypes.ON_OFF_PLUGIN_UNIT.code : DeviceTypes.ON_OFF_LIGHT.code;\n const vendorName = \"matter-node.js\";\n const passcode = getIntParameter(\"passcode\") ?? deviceStorage.get(\"passcode\", 20202021);\n const discriminator = getIntParameter(\"discriminator\") ?? deviceStorage.get(\"discriminator\", 3840);\n // product name / id and vendor id should match what is in the device certificate\n const vendorId = getIntParameter(\"vendorid\") ?? deviceStorage.get(\"vendorid\", 0xfff1);\n const productName = `node-matter OnOff-Bridge`;\n const productId = getIntParameter(\"productid\") ?? deviceStorage.get(\"productid\", 0x8000);\n\n const netAnnounceInterface = getParameter(\"announceinterface\");\n const port = getIntParameter(\"port\") ?? 5540;\n\n const uniqueId = getIntParameter(\"uniqueid\") ?? deviceStorage.get(\"uniqueid\", Time.nowMs());\n\n deviceStorage.set(\"passcode\", passcode);\n deviceStorage.set(\"discriminator\", discriminator);\n deviceStorage.set(\"vendorid\", vendorId);\n deviceStorage.set(\"productid\", productId);\n deviceStorage.set(\"isSocket\", isSocket);\n deviceStorage.set(\"uniqueid\", uniqueId);\n\n /**\n * Create Matter Server and CommissioningServer Node\n *\n * To allow the device to be announced, found, paired and operated we need a MatterServer instance and add a\n * commissioningServer to it and add the just created device instance to it.\n * The CommissioningServer 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 this.matterServer = new MatterServer(storageManager, { mdnsAnnounceInterface: netAnnounceInterface });\n\n const commissioningServer = new CommissioningServer({\n port,\n deviceName,\n deviceType,\n passcode,\n discriminator,\n basicInformation: {\n vendorName,\n vendorId: VendorId(vendorId),\n nodeLabel: productName,\n productName,\n productLabel: productName,\n productId,\n serialNumber: `node-matter-${uniqueId}`,\n },\n });\n\n /**\n * Create Device instance and add needed Listener\n *\n * Create an instance of the matter device class you want to use.\n * This example uses the OnOffLightDevice or OnOffPluginUnitDevice depending on the value of the type parameter.\n * To execute the on/off scripts defined as parameters a listener for the onOff attribute is registered via the\n * device specific API.\n *\n * The below logic also adds command handlers for commands of clusters that normally are handled device internally\n * like identify that can be implemented with the logic when these commands are called.\n */\n\n const numDevices = getIntParameter(\"num\") || 2;\n for (let i = 1; i <= numDevices; i++) {\n const onOffDevice =\n getParameter(`type${i}`) === \"socket\" ? new OnOffPluginUnitDevice() : new OnOffLightDevice();\n onOffDevice.addFixedLabel(\"orientation\", getParameter(`orientation${i}`) ?? `orientation ${i}`);\n\n onOffDevice.addOnOffListener(on => commandExecutor(on ? `on${i}` : `off${i}`)?.());\n onOffDevice.addCommandHandler(\"identify\", async ({ request: { identifyTime } }) =>\n console.log(\n `Identify called for OnOffDevice ${onOffDevice.name} with id: ${i} and identifyTime: ${identifyTime}`,\n ),\n );\n\n commissioningServer.addDevice(onOffDevice);\n }\n\n this.matterServer.addCommissioningServer(commissioningServer);\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\n await this.matterServer.start();\n\n /**\n * Print Pairing Information\n *\n * If the device is not already commissioned (this info is stored in the storage system) then get and print the\n * pairing details. This includes the QR code that can be scanned by the Matter app to pair the device.\n */\n\n logger.info(\"Listening\");\n if (!commissioningServer.isCommissioned()) {\n const pairingData = commissioningServer.getPairingCode();\n const { qrPairingCode, manualPairingCode } = pairingData;\n\n console.log(QrCode.get(qrPairingCode));\n console.log(\n `QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`,\n );\n console.log(`Manual pairing code: ${manualPairingCode}`);\n } else {\n console.log(\"Device is already commissioned. Waiting for controllers to connect ...\");\n }\n }\n\n async stop() {\n await this.matterServer?.close();\n }\n}\n\nconst device = new ComposedDevice();\ndevice\n .start()\n .then(() => {\n /* done */\n })\n .catch(err => console.error(err));\n\nprocess.on(\"SIGINT\", () => {\n device\n .stop()\n .then(() => {\n // Pragmatic way to make sure the storage is correctly closed before the process ends.\n storage\n .close()\n .then(() => process.exit(0))\n .catch(err => console.error(err));\n })\n .catch(err => console.error(err));\n});\n"],
5
- "mappings": ";;AAkBA,yBAAkD;AAElD,sBAAyB;AACzB,oBAAqE;AACrE,iBAAsC;AACtC,oBAAuB;AACvB,qBAAmD;AACnD,kBAAqB;AACrB,kBAMO;AA/BP;AAAA;AAAA;AAAA;AAAA;AAiCA,MAAM,SAAS,kBAAO,IAAI,QAAQ;AAAA,IAElC,mCAAsB,EAAE;AAGxB,YAAQ,0BAAa,UAAU,GAAG;AAAA,EAC9B,KAAK;AACD,sBAAO,kBAAkB,iBAAM;AAC/B;AAAA,EACJ,KAAK;AACD,sBAAO,kBAAkB,iBAAM;AAC/B;AAAA,EACJ,KAAK;AACD,sBAAO,kBAAkB,iBAAM;AAC/B;AAAA,EACJ,KAAK;AACD,sBAAO,kBAAkB,iBAAM;AAC/B;AACR;AAEA,YAAQ,0BAAa,WAAW,GAAG;AAAA,EAC/B,KAAK;AACD,sBAAO,SAAS,kBAAO;AACvB;AAAA,EACJ,KAAK;AACD,sBAAO,SAAS,kBAAO;AACvB;AAAA,EACJ;AACI,QAAI,QAAQ,OAAO;AAAO,wBAAO,SAAS,kBAAO;AACzD;AAEA,MAAM,sBAAkB,0BAAa,OAAO,KAAK;AACjD,MAAM,UAAU,IAAI,kCAAmB,qBAAiB,0BAAa,cAAc,CAAC;AACpF,OAAO,KAAK,qBAAqB,eAAe,cAAc;AAC9D,OAAO;AAAA,EACH;AACJ;AAEA,MAAM,eAAe;AAAA,EAGjB,MAAM,QAAQ;AACV,WAAO,KAAK,aAAa;AASzB,UAAM,iBAAiB,IAAI,8BAAe,OAAO;AACjD,UAAM,eAAe,WAAW;AAahC,UAAM,gBAAgB,eAAe,cAAc,QAAQ;AAE3D,QAAI,cAAc,IAAI,UAAU,GAAG;AAC/B,aAAO,KAAK,2DAA2D;AAAA,IAC3E;AACA,UAAM,WAAW,cAAc,IAAI,gBAAY,0BAAa,MAAM,MAAM,QAAQ;AAChF,UAAM,aAAa;AACnB,UAAM,iBACF,0BAAa,MAAM,MAAM,WAAW,0BAAY,mBAAmB,OAAO,0BAAY,aAAa;AACvG,UAAM,aAAa;AACnB,UAAM,eAAW,6BAAgB,UAAU,KAAK,cAAc,IAAI,YAAY,QAAQ;AACtF,UAAM,oBAAgB,6BAAgB,eAAe,KAAK,cAAc,IAAI,iBAAiB,IAAI;AAEjG,UAAM,eAAW,6BAAgB,UAAU,KAAK,cAAc,IAAI,YAAY,KAAM;AACpF,UAAM,cAAc;AACpB,UAAM,gBAAY,6BAAgB,WAAW,KAAK,cAAc,IAAI,aAAa,KAAM;AAEvF,UAAM,2BAAuB,0BAAa,mBAAmB;AAC7D,UAAM,WAAO,6BAAgB,MAAM,KAAK;AAExC,UAAM,eAAW,6BAAgB,UAAU,KAAK,cAAc,IAAI,YAAY,iBAAK,MAAM,CAAC;AAE1F,kBAAc,IAAI,YAAY,QAAQ;AACtC,kBAAc,IAAI,iBAAiB,aAAa;AAChD,kBAAc,IAAI,YAAY,QAAQ;AACtC,kBAAc,IAAI,aAAa,SAAS;AACxC,kBAAc,IAAI,YAAY,QAAQ;AACtC,kBAAc,IAAI,YAAY,QAAQ;AAetC,SAAK,eAAe,IAAI,gCAAa,gBAAgB,EAAE,uBAAuB,qBAAqB,CAAC;AAEpG,UAAM,sBAAsB,IAAI,uCAAoB;AAAA,MAChD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,QACd;AAAA,QACA,cAAU,0BAAS,QAAQ;AAAA,QAC3B,WAAW;AAAA,QACX;AAAA,QACA,cAAc;AAAA,QACd;AAAA,QACA,cAAc,eAAe,QAAQ;AAAA,MACzC;AAAA,IACJ,CAAC;AAcD,UAAM,iBAAa,6BAAgB,KAAK,KAAK;AAC7C,aAAS,IAAI,GAAG,KAAK,YAAY,KAAK;AAClC,YAAM,kBACF,0BAAa,OAAO,CAAC,EAAE,MAAM,WAAW,IAAI,oCAAsB,IAAI,IAAI,+BAAiB;AAC/F,kBAAY,cAAc,mBAAe,0BAAa,cAAc,CAAC,EAAE,KAAK,eAAe,CAAC,EAAE;AAE9F,kBAAY,iBAAiB,YAAM,6BAAgB,KAAK,KAAK,CAAC,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC;AACjF,kBAAY;AAAA,QAAkB;AAAA,QAAY,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MACzE,QAAQ;AAAA,UACJ,mCAAmC,YAAY,IAAI,aAAa,CAAC,sBAAsB,YAAY;AAAA,QACvG;AAAA,MACJ;AAEA,0BAAoB,UAAU,WAAW;AAAA,IAC7C;AAEA,SAAK,aAAa,uBAAuB,mBAAmB;AAS5D,UAAM,KAAK,aAAa,MAAM;AAS9B,WAAO,KAAK,WAAW;AACvB,QAAI,CAAC,oBAAoB,eAAe,GAAG;AACvC,YAAM,cAAc,oBAAoB,eAAe;AACvD,YAAM,EAAE,eAAe,kBAAkB,IAAI;AAE7C,cAAQ,IAAI,qBAAO,IAAI,aAAa,CAAC;AACrC,cAAQ;AAAA,QACJ,gFAAgF,aAAa;AAAA,MACjG;AACA,cAAQ,IAAI,wBAAwB,iBAAiB,EAAE;AAAA,IAC3D,OAAO;AACH,cAAQ,IAAI,wEAAwE;AAAA,IACxF;AAAA,EACJ;AAAA,EAEA,MAAM,OAAO;AACT,UAAM,KAAK,cAAc,MAAM;AAAA,EACnC;AACJ;AAEA,MAAM,SAAS,IAAI,eAAe;AAClC,OACK,MAAM,EACN,KAAK,MAAM;AAEZ,CAAC,EACA,MAAM,SAAO,QAAQ,MAAM,GAAG,CAAC;AAEpC,QAAQ,GAAG,UAAU,MAAM;AACvB,SACK,KAAK,EACL,KAAK,MAAM;AAER,YACK,MAAM,EACN,KAAK,MAAM,QAAQ,KAAK,CAAC,CAAC,EAC1B,MAAM,SAAO,QAAQ,MAAM,GAAG,CAAC;AAAA,EACxC,CAAC,EACA,MAAM,SAAO,QAAQ,MAAM,GAAG,CAAC;AACxC,CAAC;",
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,55 +1,65 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- var import_matter_node = require("@project-chip/matter-node.js");
4
- var import_ble = require("@project-chip/matter-node-ble.js/ble");
5
- var import_ble2 = require("@project-chip/matter-node.js/ble");
6
- var import_cluster = require("@project-chip/matter-node.js/cluster");
7
- var import_datatype = require("@project-chip/matter-node.js/datatype");
8
- var import_log = require("@project-chip/matter-node.js/log");
9
- var import_schema = require("@project-chip/matter-node.js/schema");
10
- var import_storage = require("@project-chip/matter-node.js/storage");
11
- var import_util = require("@project-chip/matter-node.js/util");
12
2
  /**
13
3
  * @license
14
4
  * Copyright 2022-2023 Project CHIP Authors
15
5
  * SPDX-License-Identifier: Apache-2.0
16
6
  */
17
- const logger = import_log.Logger.get("Controller");
18
- (0, import_util.requireMinNodeVersion)(16);
19
- switch ((0, import_util.getParameter)("loglevel")) {
7
+ import { CommissioningController, MatterServer } from "@project-chip/matter-node.js";
8
+ import { BleNode } from "@project-chip/matter-node-ble.js/ble";
9
+ import { Ble } from "@project-chip/matter-node.js/ble";
10
+ import {
11
+ BasicInformationCluster,
12
+ DescriptorCluster,
13
+ GeneralCommissioning,
14
+ OnOffCluster
15
+ } from "@project-chip/matter-node.js/cluster";
16
+ import { NodeId } from "@project-chip/matter-node.js/datatype";
17
+ import { Format, Level, Logger } from "@project-chip/matter-node.js/log";
18
+ import { ManualPairingCodeCodec } from "@project-chip/matter-node.js/schema";
19
+ import { StorageBackendDisk, StorageManager } from "@project-chip/matter-node.js/storage";
20
+ import {
21
+ getIntParameter,
22
+ getParameter,
23
+ hasParameter,
24
+ requireMinNodeVersion,
25
+ singleton
26
+ } from "@project-chip/matter-node.js/util";
27
+ const logger = Logger.get("Controller");
28
+ requireMinNodeVersion(16);
29
+ switch (getParameter("loglevel")) {
20
30
  case "fatal":
21
- import_log.Logger.defaultLogLevel = import_log.Level.FATAL;
31
+ Logger.defaultLogLevel = Level.FATAL;
22
32
  break;
23
33
  case "error":
24
- import_log.Logger.defaultLogLevel = import_log.Level.ERROR;
34
+ Logger.defaultLogLevel = Level.ERROR;
25
35
  break;
26
36
  case "warn":
27
- import_log.Logger.defaultLogLevel = import_log.Level.WARN;
37
+ Logger.defaultLogLevel = Level.WARN;
28
38
  break;
29
39
  case "info":
30
- import_log.Logger.defaultLogLevel = import_log.Level.INFO;
40
+ Logger.defaultLogLevel = Level.INFO;
31
41
  break;
32
42
  }
33
- switch ((0, import_util.getParameter)("logformat")) {
43
+ switch (getParameter("logformat")) {
34
44
  case "plain":
35
- import_log.Logger.format = import_log.Format.PLAIN;
45
+ Logger.format = Format.PLAIN;
36
46
  break;
37
47
  case "html":
38
- import_log.Logger.format = import_log.Format.HTML;
48
+ Logger.format = Format.HTML;
39
49
  break;
40
50
  default:
41
51
  if (process.stdin?.isTTY)
42
- import_log.Logger.format = import_log.Format.ANSI;
52
+ Logger.format = Format.ANSI;
43
53
  }
44
- if ((0, import_util.hasParameter)("ble")) {
45
- import_ble2.Ble.get = (0, import_util.singleton)(
46
- () => new import_ble.BleNode({
47
- hciId: (0, import_util.getIntParameter)("ble-hci-id")
54
+ if (hasParameter("ble")) {
55
+ Ble.get = singleton(
56
+ () => new BleNode({
57
+ hciId: getIntParameter("ble-hci-id")
48
58
  })
49
59
  );
50
60
  }
51
- const storageLocation = (0, import_util.getParameter)("store") ?? ".controller-node";
52
- const storage = new import_storage.StorageBackendDisk(storageLocation, (0, import_util.hasParameter)("clearstorage"));
61
+ const storageLocation = getParameter("store") ?? ".controller-node";
62
+ const storage = new StorageBackendDisk(storageLocation, hasParameter("clearstorage"));
53
63
  logger.info(`Storage location: ${storageLocation} (Directory)`);
54
64
  logger.info(
55
65
  'Use the parameter "-store NAME" to specify a different storage location, use -clearstorage to start with an empty storage.'
@@ -57,24 +67,24 @@ logger.info(
57
67
  class ControllerNode {
58
68
  async start() {
59
69
  logger.info(`node-matter Controller started`);
60
- const storageManager = new import_storage.StorageManager(storage);
70
+ const storageManager = new StorageManager(storage);
61
71
  await storageManager.initialize();
62
72
  const controllerStorage = storageManager.createContext("Controller");
63
- const ip = controllerStorage.has("ip") ? controllerStorage.get("ip") : (0, import_util.getParameter)("ip");
64
- const port = controllerStorage.has("port") ? controllerStorage.get("port") : (0, import_util.getIntParameter)("port");
65
- const pairingCode = (0, import_util.getParameter)("pairingcode");
73
+ const ip = controllerStorage.has("ip") ? controllerStorage.get("ip") : getParameter("ip");
74
+ const port = controllerStorage.has("port") ? controllerStorage.get("port") : getIntParameter("port");
75
+ const pairingCode = getParameter("pairingcode");
66
76
  let longDiscriminator, setupPin, shortDiscriminator;
67
77
  if (pairingCode !== void 0) {
68
- const pairingCodeCodec = import_schema.ManualPairingCodeCodec.decode(pairingCode);
78
+ const pairingCodeCodec = ManualPairingCodeCodec.decode(pairingCode);
69
79
  shortDiscriminator = pairingCodeCodec.shortDiscriminator;
70
80
  longDiscriminator = void 0;
71
81
  setupPin = pairingCodeCodec.passcode;
72
- logger.debug(`Data extracted from pairing code: ${import_log.Logger.toJSON(pairingCodeCodec)}`);
82
+ logger.debug(`Data extracted from pairing code: ${Logger.toJSON(pairingCodeCodec)}`);
73
83
  } else {
74
- longDiscriminator = (0, import_util.getIntParameter)("longDiscriminator") ?? controllerStorage.get("longDiscriminator", 3840);
84
+ longDiscriminator = getIntParameter("longDiscriminator") ?? controllerStorage.get("longDiscriminator", 3840);
75
85
  if (longDiscriminator > 4095)
76
86
  throw new Error("Discriminator value must be less than 4096");
77
- setupPin = (0, import_util.getIntParameter)("pin") ?? controllerStorage.get("pin", 20202021);
87
+ setupPin = getIntParameter("pin") ?? controllerStorage.get("pin", 20202021);
78
88
  }
79
89
  if (shortDiscriminator === void 0 && longDiscriminator === void 0 || setupPin === void 0) {
80
90
  throw new Error(
@@ -82,14 +92,14 @@ class ControllerNode {
82
92
  );
83
93
  }
84
94
  const commissioningOptions = {
85
- regulatoryLocation: import_cluster.GeneralCommissioning.RegulatoryLocationType.IndoorOutdoor,
95
+ regulatoryLocation: GeneralCommissioning.RegulatoryLocationType.IndoorOutdoor,
86
96
  regulatoryCountryCode: "XX"
87
97
  };
88
- if ((0, import_util.hasParameter)("ble")) {
89
- const wifiSsid = (0, import_util.getParameter)("ble-wifi-ssid");
90
- const wifiCredentials = (0, import_util.getParameter)("ble-wifi-credentials");
91
- const threadNetworkName = (0, import_util.getParameter)("ble-thread-networkname");
92
- const threadOperationalDataset = (0, import_util.getParameter)("ble-thread-operationaldataset");
98
+ if (hasParameter("ble")) {
99
+ const wifiSsid = getParameter("ble-wifi-ssid");
100
+ const wifiCredentials = getParameter("ble-wifi-credentials");
101
+ const threadNetworkName = getParameter("ble-thread-networkname");
102
+ const threadOperationalDataset = getParameter("ble-thread-operationaldataset");
93
103
  if (wifiSsid !== void 0 && wifiCredentials !== void 0) {
94
104
  logger.info(`Registering Commissioning over BLE with WiFi: ${wifiSsid}`);
95
105
  commissioningOptions.wifiNetwork = {
@@ -105,8 +115,8 @@ class ControllerNode {
105
115
  };
106
116
  }
107
117
  }
108
- const matterServer = new import_matter_node.MatterServer(storageManager);
109
- const commissioningController = new import_matter_node.CommissioningController({
118
+ const matterServer = new MatterServer(storageManager);
119
+ const commissioningController = new CommissioningController({
110
120
  autoConnect: false
111
121
  });
112
122
  matterServer.addCommissioningController(commissioningController);
@@ -126,21 +136,21 @@ class ControllerNode {
126
136
  }
127
137
  try {
128
138
  const nodes = commissioningController.getCommissionedNodes();
129
- console.log("Found commissioned nodes:", import_log.Logger.toJSON(nodes));
130
- const nodeId = (0, import_datatype.NodeId)((0, import_util.getIntParameter)("nodeid") ?? nodes[0]);
139
+ console.log("Found commissioned nodes:", Logger.toJSON(nodes));
140
+ const nodeId = NodeId(getIntParameter("nodeid") ?? nodes[0]);
131
141
  if (!nodes.includes(nodeId)) {
132
142
  throw new Error(`Node ${nodeId} not found in commissioned nodes`);
133
143
  }
134
144
  const node = await commissioningController.connectNode(nodeId);
135
145
  node.logStructure();
136
- const descriptor = node.getRootClusterClient(import_cluster.DescriptorCluster);
146
+ const descriptor = node.getRootClusterClient(DescriptorCluster);
137
147
  if (descriptor !== void 0) {
138
148
  console.log(await descriptor.attributes.deviceTypeList.get());
139
149
  console.log(await descriptor.getServerListAttribute());
140
150
  } else {
141
151
  console.log("No Descriptor Cluster found. This should never happen!");
142
152
  }
143
- const info = node.getRootClusterClient(import_cluster.BasicInformationCluster);
153
+ const info = node.getRootClusterClient(BasicInformationCluster);
144
154
  if (info !== void 0) {
145
155
  console.log(await info.getProductNameAttribute());
146
156
  } else {
@@ -148,7 +158,7 @@ class ControllerNode {
148
158
  }
149
159
  const devices = node.getDevices();
150
160
  if (devices[0] && devices[0].id === 1) {
151
- const onOff = devices[0].getClusterClient(import_cluster.OnOffCluster);
161
+ const onOff = devices[0].getClusterClient(OnOffCluster);
152
162
  if (onOff !== void 0) {
153
163
  let onOffStatus = await onOff.getOnOffAttribute();
154
164
  console.log("initial onOffStatus", onOffStatus);
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/examples/ControllerNode.ts"],
4
4
  "sourcesContent": ["#!/usr/bin/env node\n\n/**\n * @license\n * Copyright 2022-2023 Project CHIP 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 { CommissioningController, MatterServer, NodeCommissioningOptions } from \"@project-chip/matter-node.js\";\n\nimport { BleNode } from \"@project-chip/matter-node-ble.js/ble\";\nimport { Ble } from \"@project-chip/matter-node.js/ble\";\nimport {\n BasicInformationCluster,\n DescriptorCluster,\n GeneralCommissioning,\n OnOffCluster,\n} from \"@project-chip/matter-node.js/cluster\";\nimport { NodeId } from \"@project-chip/matter-node.js/datatype\";\nimport { Format, Level, Logger } from \"@project-chip/matter-node.js/log\";\nimport { CommissioningOptions } from \"@project-chip/matter-node.js/protocol\";\nimport { ManualPairingCodeCodec } from \"@project-chip/matter-node.js/schema\";\nimport { StorageBackendDisk, StorageManager } from \"@project-chip/matter-node.js/storage\";\nimport {\n getIntParameter,\n getParameter,\n hasParameter,\n requireMinNodeVersion,\n singleton,\n} from \"@project-chip/matter-node.js/util\";\n\nconst logger = Logger.get(\"Controller\");\n\nrequireMinNodeVersion(16);\n\n/** Configure logging */\nswitch (getParameter(\"loglevel\")) {\n case \"fatal\":\n Logger.defaultLogLevel = Level.FATAL;\n break;\n case \"error\":\n Logger.defaultLogLevel = Level.ERROR;\n break;\n case \"warn\":\n Logger.defaultLogLevel = Level.WARN;\n break;\n case \"info\":\n Logger.defaultLogLevel = Level.INFO;\n break;\n}\n\nswitch (getParameter(\"logformat\")) {\n case \"plain\":\n Logger.format = Format.PLAIN;\n break;\n case \"html\":\n Logger.format = Format.HTML;\n break;\n default:\n if (process.stdin?.isTTY) Logger.format = Format.ANSI;\n}\n\nif (hasParameter(\"ble\")) {\n // Initialize Ble\n Ble.get = singleton(\n () =>\n new BleNode({\n hciId: getIntParameter(\"ble-hci-id\"),\n }),\n );\n}\n\nconst storageLocation = getParameter(\"store\") ?? \".controller-node\";\nconst storage = new StorageBackendDisk(storageLocation, hasParameter(\"clearstorage\"));\nlogger.info(`Storage location: ${storageLocation} (Directory)`);\nlogger.info(\n 'Use the parameter \"-store NAME\" to specify a different storage location, use -clearstorage to start with an empty storage.',\n);\n\nclass ControllerNode {\n async start() {\n logger.info(`node-matter Controller started`);\n\n /**\n * Initialize the storage system.\n *\n * The storage manager is then also used by the Matter server, so this code block in general is required,\n * but you can choose a different storage backend as long as it implements the required API.\n */\n\n const storageManager = new StorageManager(storage);\n await storageManager.initialize();\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 = storageManager.createContext(\"Controller\");\n const ip = controllerStorage.has(\"ip\") ? controllerStorage.get<string>(\"ip\") : getParameter(\"ip\");\n const port = controllerStorage.has(\"port\") ? controllerStorage.get<number>(\"port\") : getIntParameter(\"port\");\n\n const pairingCode = getParameter(\"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 getIntParameter(\"longDiscriminator\") ?? controllerStorage.get(\"longDiscriminator\", 3840);\n if (longDiscriminator > 4095) throw new Error(\"Discriminator value must be less than 4096\");\n setupPin = getIntParameter(\"pin\") ?? 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 if (hasParameter(\"ble\")) {\n const wifiSsid = getParameter(\"ble-wifi-ssid\");\n const wifiCredentials = getParameter(\"ble-wifi-credentials\");\n const threadNetworkName = getParameter(\"ble-thread-networkname\");\n const threadOperationalDataset = getParameter(\"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 matterServer = new MatterServer(storageManager);\n const commissioningController = new CommissioningController({\n autoConnect: false,\n });\n matterServer.addCommissioningController(commissioningController);\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\n await matterServer.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 },\n passcode: setupPin,\n } as NodeCommissioningOptions;\n logger.info(`Commissioning ... ${JSON.stringify(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(getIntParameter(\"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\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].id === 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 = devices[0].getClusterClient(OnOffCluster);\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\nprocess.on(\"SIGINT\", () => {\n // Pragmatic way to make sure the storage is correctly closed before the process ends.\n storage\n .close()\n .then(() => process.exit(0))\n .catch(() => process.exit(1));\n});\n"],
5
- "mappings": "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",
6
- "names": ["import_ble"]
5
+ "mappings": "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",
6
+ "names": []
7
7
  }