inventoresed
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
229 lines (219 loc) • 5.88 kB
text/typescript
import { isObject } from "alcalzone-shared/typeguards";
import fs from "fs-extra";
import "reflect-metadata";
import yargs from "yargs";
import {
json500To700,
json700To500,
jsonToNVM,
jsonToNVM500,
migrateNVM,
nvm500ToJSON,
nvmToJSON,
} from "./convert";
import "./index";
void yargs
.env("NVMEDIT")
.strict()
.usage("Z-Wave JS NVM converter utility\n\nUsage: $0 [options]")
.alias("h", "help")
.alias("v", "version")
.wrap(Math.min(100, yargs.terminalWidth()))
.options({
verbose: {
alias: "vv",
describe: "Print verbose output",
type: "boolean",
},
})
.command(
"nvm2json",
"Convert an NVM backup to JSON",
(yargs) =>
yargs.usage("$0 nvm2json --in <input> --out <output>").options({
in: {
describe: "NVM backup filename",
type: "string",
required: true,
},
out: {
describe: "JSON output filename",
type: "string",
required: true,
},
}),
async (argv) => {
const buffer = await fs.readFile(argv.in);
let json: any;
try {
json = nvmToJSON(buffer, argv.verbose);
} catch (e) {
try {
json = nvm500ToJSON(buffer);
} catch (ee) {
console.error(e);
process.exit(1);
}
}
await fs.writeJSON(argv.out, json, { spaces: "\t" });
console.error(`NVM (JSON) written to ${argv.out}`);
process.exit(0);
},
)
.command(
"json2nvm",
"Convert the JSON representation of an NVM to binary",
(yargs) =>
yargs
.usage(
"$0 json2nvm --in <input> --out <output> --protocolVersion <version>",
)
.options({
in: {
describe: "JSON input filename",
type: "string",
required: true,
},
out: {
describe: "NVM output filename",
type: "string",
required: true,
},
protocolVersion: {
alias: "V",
describe:
"target protocol version, determines the NVM format",
type: "string",
required: true,
},
}),
async (argv) => {
const { protocolVersion } = argv;
const versionIs500 = /^\d\.\d+$/.test(protocolVersion);
const json = await fs.readJson(argv.in);
const jsonIs500 = json.format === 500;
if (versionIs500 && !jsonIs500) {
console.error(
`ERROR: Protocol version ${protocolVersion} looks like a 500-series version, but the JSON file does not belong to a 500-series NVM!
Convert it first using the 700to500 command.`,
);
process.exit(1);
} else if (jsonIs500 && !versionIs500) {
console.error(
`ERROR: Protocol version ${protocolVersion} looks like a 700-series version, but the JSON file belong to a 500-series NVM!
Convert it first using the 500to700 command.`,
);
process.exit(1);
}
if (!isObject(json.meta)) {
console.error(
`ERROR: The JSON file does not contain the meta section, which is required for the conversion to a binary NVM!
Create a backup of the target stick, use the nvm2json command to convert it to JSON and copy the meta section from there.`,
);
process.exit(1);
}
const nvm = versionIs500
? jsonToNVM500(json, protocolVersion)
: jsonToNVM(json, protocolVersion);
await fs.writeFile(argv.out, nvm);
console.error(`NVM (binary) written to ${argv.out}`);
process.exit(0);
},
)
.command(
"500to700",
"Convert a 500-series JSON file into a 700-series JSON file",
(yargs) =>
yargs
.usage("$0 500to700 --in <input> --out <output> [--truncate]")
.options({
in: {
describe: "500 series JSON input filename",
type: "string",
required: true,
},
out: {
describe: "700 series output filename",
type: "string",
required: true,
},
truncate: {
alias: "t",
describe:
"Truncate application data if it is too large (> 512 bytes)",
type: "boolean",
required: false,
default: false,
},
}),
async (argv) => {
const json500 = await fs.readJson(argv.in);
const json700 = json500To700(json500, argv.truncate);
await fs.writeJSON(argv.out, json700, { spaces: "\t" });
console.error(`700-series NVM (JSON) written to ${argv.out}`);
process.exit(0);
},
)
.command(
"700to500",
"Convert a 700-series JSON file into a 500-series JSON file",
(yargs) =>
yargs.usage("$0 700to500 --in <input> --out <output>").options({
in: {
describe: "700 series JSON input filename",
type: "string",
required: true,
},
out: {
describe: "500 series output filename",
type: "string",
required: true,
},
}),
async (argv) => {
const json700 = await fs.readJson(argv.in);
const json500 = json700To500(json700);
await fs.writeJSON(argv.out, json500, { spaces: "\t" });
console.error(`500-series NVM (JSON) written to ${argv.out}`);
process.exit(0);
},
)
.command(
"convert",
"Convert the format of an NVM backup between different Z-Wave modules",
(yargs) =>
yargs
.usage(
"$0 convert --source <source> --target <target> --out <output>",
)
.options({
source: {
describe:
"The source NVM filename. This file will be converted to match the target NVM.",
type: "string",
required: true,
},
target: {
describe:
"The target NVM filename. This file will used to determine how to convert the source NVM.",
type: "string",
required: true,
},
out: {
describe:
"The output filename where the convert NVM will be written.",
type: "string",
required: true,
},
}),
async (argv) => {
const source = await fs.readFile(argv.source);
const target = await fs.readFile(argv.target);
const output = migrateNVM(source, target);
await fs.writeFile(argv.out, output);
console.error(`Converted NVM written to ${argv.out}`);
process.exit(0);
},
)
.demandCommand(1, "Please specify a command")
.parseAsync();