@matter/nodejs-shell 0.16.0-alpha.0-20251112-dba1973d5 → 0.16.0-alpha.0-20251125-16883ca92
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.
- package/README.md +210 -5
- package/dist/cjs/MatterNode.js +18 -0
- package/dist/cjs/MatterNode.js.map +1 -1
- package/dist/cjs/shell/Shell.js +8 -0
- package/dist/cjs/shell/Shell.js.map +2 -2
- package/dist/cjs/shell/cmd_cert.js +154 -0
- package/dist/cjs/shell/cmd_cert.js.map +6 -0
- package/dist/cjs/shell/cmd_config.js +62 -1
- package/dist/cjs/shell/cmd_config.js.map +1 -1
- package/dist/cjs/shell/cmd_dcl.js +198 -0
- package/dist/cjs/shell/cmd_dcl.js.map +6 -0
- package/dist/cjs/shell/cmd_nodes.js +160 -0
- package/dist/cjs/shell/cmd_nodes.js.map +1 -1
- package/dist/cjs/shell/cmd_ota.js +449 -0
- package/dist/cjs/shell/cmd_ota.js.map +6 -0
- package/dist/cjs/shell/cmd_vendor.js +118 -0
- package/dist/cjs/shell/cmd_vendor.js.map +6 -0
- package/package.json +10 -10
- package/src/MatterNode.ts +30 -1
- package/src/shell/Shell.ts +8 -0
- package/src/shell/cmd_cert.ts +156 -0
- package/src/shell/cmd_config.ts +80 -1
- package/src/shell/cmd_dcl.ts +221 -0
- package/src/shell/cmd_nodes.ts +192 -1
- package/src/shell/cmd_ota.ts +550 -0
- package/src/shell/cmd_vendor.ts +108 -0
package/src/shell/cmd_nodes.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { capitalize, decamelize, Diagnostic } from "#general";
|
|
8
|
-
import { NodeId } from "#types";
|
|
8
|
+
import { NodeId, VendorId } from "#types";
|
|
9
9
|
import { CommissioningControllerNodeOptions, NodeStateInformation } from "@project-chip/matter.js/device";
|
|
10
10
|
import type { Argv } from "yargs";
|
|
11
11
|
import { MatterNode } from "../MatterNode";
|
|
@@ -240,6 +240,197 @@ export default function commands(theNode: MatterNode) {
|
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
},
|
|
243
|
+
)
|
|
244
|
+
.command(
|
|
245
|
+
"ota",
|
|
246
|
+
"OTA update operations for nodes",
|
|
247
|
+
yargs =>
|
|
248
|
+
yargs
|
|
249
|
+
.command(
|
|
250
|
+
"check <node-id>",
|
|
251
|
+
"Check for OTA updates for a commissioned node",
|
|
252
|
+
yargs => {
|
|
253
|
+
return yargs
|
|
254
|
+
.positional("node-id", {
|
|
255
|
+
describe: "Node ID to check for updates",
|
|
256
|
+
type: "string",
|
|
257
|
+
demandOption: true,
|
|
258
|
+
})
|
|
259
|
+
.option("mode", {
|
|
260
|
+
describe: "DCL mode (prod or test)",
|
|
261
|
+
type: "string",
|
|
262
|
+
choices: ["prod", "test"],
|
|
263
|
+
default: "prod",
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
async argv => {
|
|
267
|
+
const { nodeId: nodeIdStr, mode } = argv;
|
|
268
|
+
const isProduction = mode === "prod";
|
|
269
|
+
|
|
270
|
+
await theNode.start();
|
|
271
|
+
if (theNode.commissioningController === undefined) {
|
|
272
|
+
throw new Error("CommissioningController not initialized");
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const nodeId = NodeId(BigInt(nodeIdStr));
|
|
276
|
+
const nodeDetails = theNode.commissioningController
|
|
277
|
+
.getCommissionedNodesDetails()
|
|
278
|
+
.find(nd => nd.nodeId === nodeId);
|
|
279
|
+
const basicInfo = nodeDetails?.deviceData?.basicInformation;
|
|
280
|
+
if (!basicInfo) {
|
|
281
|
+
throw new Error(`Node ${nodeIdStr} has no basic information available`);
|
|
282
|
+
}
|
|
283
|
+
if (
|
|
284
|
+
basicInfo.vendorId === undefined ||
|
|
285
|
+
basicInfo.productId === undefined ||
|
|
286
|
+
basicInfo.softwareVersion === undefined
|
|
287
|
+
) {
|
|
288
|
+
throw new Error(
|
|
289
|
+
`Node ${nodeIdStr} is missing required basic information for OTA check`,
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
console.log(`Checking for OTA updates for node ${nodeIdStr}...`);
|
|
294
|
+
console.log(
|
|
295
|
+
` Vendor ID: ${Diagnostic.hex(basicInfo.vendorId as VendorId, 4).toUpperCase()}`,
|
|
296
|
+
);
|
|
297
|
+
console.log(
|
|
298
|
+
` Product ID: ${Diagnostic.hex(basicInfo.productId as number, 4).toUpperCase()}`,
|
|
299
|
+
);
|
|
300
|
+
console.log(
|
|
301
|
+
` Current Software Version: ${basicInfo.softwareVersion} (${basicInfo.softwareVersionString})`,
|
|
302
|
+
);
|
|
303
|
+
console.log(` DCL Mode: ${isProduction ? "production" : "test"}\n`);
|
|
304
|
+
|
|
305
|
+
const updateInfo = await theNode.otaService.checkForUpdate(
|
|
306
|
+
basicInfo.vendorId as VendorId,
|
|
307
|
+
basicInfo.productId as number,
|
|
308
|
+
basicInfo.softwareVersion as number,
|
|
309
|
+
isProduction,
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
if (updateInfo) {
|
|
313
|
+
console.log("✓ Update available!");
|
|
314
|
+
console.log(
|
|
315
|
+
` New Version: ${updateInfo.softwareVersion} (${updateInfo.softwareVersionString})`,
|
|
316
|
+
);
|
|
317
|
+
console.log(` OTA URL: ${updateInfo.otaUrl}`);
|
|
318
|
+
if (updateInfo.otaFileSize) {
|
|
319
|
+
const sizeKB = Number(updateInfo.otaFileSize) / 1024;
|
|
320
|
+
console.log(` File Size: ${sizeKB.toFixed(2)} KB`);
|
|
321
|
+
}
|
|
322
|
+
if (updateInfo.releaseNotesUrl) {
|
|
323
|
+
console.log(` Release Notes: ${updateInfo.releaseNotesUrl}`);
|
|
324
|
+
}
|
|
325
|
+
console.log(
|
|
326
|
+
`\nRun "nodes ota download ${nodeIdStr}${mode === "test" ? " --mode test" : ""}" to download this update.`,
|
|
327
|
+
);
|
|
328
|
+
} else {
|
|
329
|
+
console.log("✓ No updates available. Device is up to date.");
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
)
|
|
333
|
+
.command(
|
|
334
|
+
"download <node-id>",
|
|
335
|
+
"Download OTA update for a commissioned node",
|
|
336
|
+
yargs => {
|
|
337
|
+
return yargs
|
|
338
|
+
.positional("node-id", {
|
|
339
|
+
describe: "Node ID to download update for",
|
|
340
|
+
type: "string",
|
|
341
|
+
demandOption: true,
|
|
342
|
+
})
|
|
343
|
+
.option("mode", {
|
|
344
|
+
describe: "DCL mode (prod or test)",
|
|
345
|
+
type: "string",
|
|
346
|
+
choices: ["prod", "test"],
|
|
347
|
+
default: "prod",
|
|
348
|
+
})
|
|
349
|
+
.option("force", {
|
|
350
|
+
describe: "Force download even if update is already stored locally",
|
|
351
|
+
type: "boolean",
|
|
352
|
+
default: false,
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
async argv => {
|
|
356
|
+
const { nodeId: nodeIdStr, mode, force } = argv;
|
|
357
|
+
const isProduction = mode === "prod";
|
|
358
|
+
const forceDownload = force === true;
|
|
359
|
+
|
|
360
|
+
await theNode.start();
|
|
361
|
+
if (theNode.commissioningController === undefined) {
|
|
362
|
+
throw new Error("CommissioningController not initialized");
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const nodeId = NodeId(BigInt(nodeIdStr));
|
|
366
|
+
const nodeDetails = theNode.commissioningController
|
|
367
|
+
.getCommissionedNodesDetails()
|
|
368
|
+
.find(nd => nd.nodeId === nodeId);
|
|
369
|
+
const basicInfo = nodeDetails?.deviceData?.basicInformation;
|
|
370
|
+
if (!basicInfo) {
|
|
371
|
+
throw new Error(`Node ${nodeIdStr} has no basic information available`);
|
|
372
|
+
}
|
|
373
|
+
if (
|
|
374
|
+
basicInfo.vendorId === undefined ||
|
|
375
|
+
basicInfo.productId === undefined ||
|
|
376
|
+
basicInfo.softwareVersion === undefined
|
|
377
|
+
) {
|
|
378
|
+
throw new Error(
|
|
379
|
+
`Node ${nodeIdStr} is missing required basic information for OTA check`,
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
console.log(`Checking for OTA updates for node ${nodeIdStr}...`);
|
|
384
|
+
console.log(
|
|
385
|
+
` Vendor ID: ${Diagnostic.hex(basicInfo.vendorId as VendorId, 4).toUpperCase()}`,
|
|
386
|
+
);
|
|
387
|
+
console.log(
|
|
388
|
+
` Product ID: ${Diagnostic.hex(basicInfo.productId as number, 4).toUpperCase()}`,
|
|
389
|
+
);
|
|
390
|
+
console.log(
|
|
391
|
+
` Current Software Version: ${basicInfo.softwareVersion} (${basicInfo.softwareVersionString})`,
|
|
392
|
+
);
|
|
393
|
+
console.log(` DCL Mode: ${isProduction ? "production" : "test"}\n`);
|
|
394
|
+
|
|
395
|
+
const updateInfo = await theNode.otaService.checkForUpdate(
|
|
396
|
+
basicInfo.vendorId as VendorId,
|
|
397
|
+
basicInfo.productId as number,
|
|
398
|
+
basicInfo.softwareVersion as number,
|
|
399
|
+
isProduction,
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
if (!updateInfo) {
|
|
403
|
+
console.log("No updates available. Device is up to date.");
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
console.log("Update found:");
|
|
408
|
+
console.log(
|
|
409
|
+
` New Version: ${updateInfo.softwareVersion} (${updateInfo.softwareVersionString})`,
|
|
410
|
+
);
|
|
411
|
+
console.log(` OTA URL: ${updateInfo.otaUrl}`);
|
|
412
|
+
if (updateInfo.otaFileSize) {
|
|
413
|
+
const sizeKB = Number(updateInfo.otaFileSize) / 1024;
|
|
414
|
+
console.log(` File Size: ${sizeKB.toFixed(2)} KB`);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
console.log("\nDownloading update...");
|
|
418
|
+
const fd = await theNode.otaService.downloadUpdate(
|
|
419
|
+
updateInfo,
|
|
420
|
+
isProduction,
|
|
421
|
+
forceDownload,
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
console.log(`✓ Update downloaded and stored successfully: ${fd.text}`);
|
|
425
|
+
console.log(
|
|
426
|
+
`\nYou can now apply this update to the device using your device's OTA mechanism.`,
|
|
427
|
+
);
|
|
428
|
+
},
|
|
429
|
+
)
|
|
430
|
+
.demandCommand(1, "Please specify an OTA subcommand"),
|
|
431
|
+
async (argv: any) => {
|
|
432
|
+
argv.unhandled = true;
|
|
433
|
+
},
|
|
243
434
|
),
|
|
244
435
|
handler: async (argv: any) => {
|
|
245
436
|
argv.unhandled = true;
|