@zwave-js/nvmedit 15.15.3 → 15.17.0
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/build/cjs/convert.d.ts +6 -5
- package/build/cjs/convert.js.map +2 -2
- package/build/cjs/lib/NVM3.d.ts +6 -5
- package/build/cjs/lib/NVM3.js.map +2 -2
- package/build/cjs/lib/NVM500.js +1 -1
- package/build/cjs/lib/NVM500.js.map +2 -2
- package/build/cjs/lib/common/definitions.d.ts +5 -5
- package/build/cjs/lib/common/definitions.js.map +1 -1
- package/build/cjs/lib/common/routeCache.d.ts +2 -2
- package/build/cjs/lib/common/routeCache.js.map +2 -2
- package/build/cjs/lib/common/sucUpdateEntry.d.ts +2 -2
- package/build/cjs/lib/common/sucUpdateEntry.js.map +2 -2
- package/build/cjs/lib/common/utils.d.ts +3 -2
- package/build/cjs/lib/common/utils.js.map +2 -2
- package/build/cjs/lib/io/BufferedNVMReader.d.ts +3 -2
- package/build/cjs/lib/io/BufferedNVMReader.js.map +2 -2
- package/build/cjs/lib/io/NVMFileIO.d.ts +3 -2
- package/build/cjs/lib/io/NVMFileIO.js.map +2 -2
- package/build/cjs/lib/io/NVMMemoryIO.d.ts +4 -3
- package/build/cjs/lib/io/NVMMemoryIO.js.map +2 -2
- package/build/cjs/lib/nvm3/adapter.js.map +2 -2
- package/build/cjs/lib/nvm3/files/ApplicationCCsFile.js +1 -1
- package/build/cjs/lib/nvm3/files/ApplicationCCsFile.js.map +1 -1
- package/build/cjs/lib/nvm3/files/ApplicationRFConfigFile.js +1 -1
- package/build/cjs/lib/nvm3/files/ApplicationRFConfigFile.js.map +1 -1
- package/build/cjs/lib/nvm3/files/ApplicationTypeFile.js +1 -1
- package/build/cjs/lib/nvm3/files/ApplicationTypeFile.js.map +1 -1
- package/build/cjs/lib/nvm3/files/ControllerInfoFile.d.ts +3 -3
- package/build/cjs/lib/nvm3/files/ControllerInfoFile.js +1 -1
- package/build/cjs/lib/nvm3/files/ControllerInfoFile.js.map +2 -2
- package/build/cjs/lib/nvm3/files/NVMFile.d.ts +2 -2
- package/build/cjs/lib/nvm3/files/NVMFile.js.map +2 -2
- package/build/cjs/lib/nvm3/files/NodeInfoFiles.js +3 -3
- package/build/cjs/lib/nvm3/files/NodeInfoFiles.js.map +2 -2
- package/build/cjs/lib/nvm3/files/ProtocolNodeMaskFiles.js +2 -2
- package/build/cjs/lib/nvm3/files/ProtocolNodeMaskFiles.js.map +1 -1
- package/build/cjs/lib/nvm3/files/RouteCacheFiles.js +2 -2
- package/build/cjs/lib/nvm3/files/RouteCacheFiles.js.map +1 -1
- package/build/cjs/lib/nvm3/files/SUCUpdateEntriesFile.js +2 -2
- package/build/cjs/lib/nvm3/files/SUCUpdateEntriesFile.js.map +1 -1
- package/build/cjs/lib/nvm3/files/VersionFiles.js +1 -1
- package/build/cjs/lib/nvm3/files/VersionFiles.js.map +1 -1
- package/build/cjs/lib/nvm3/object.d.ts +3 -2
- package/build/cjs/lib/nvm3/object.js.map +2 -2
- package/build/cjs/lib/nvm3/page.d.ts +2 -1
- package/build/cjs/lib/nvm3/page.js.map +2 -2
- package/build/cjs/lib/nvm500/EntryParsers.d.ts +4 -4
- package/build/cjs/lib/nvm500/EntryParsers.js.map +2 -2
- package/build/cjs/lib/nvm500/adapter.js +4 -2
- package/build/cjs/lib/nvm500/adapter.js.map +2 -2
- package/build/cjs/lib/nvm500/shared.d.ts +2 -1
- package/build/cjs/lib/nvm500/shared.js.map +2 -2
- package/build/esm/convert.d.ts +6 -5
- package/build/esm/convert.d.ts.map +1 -1
- package/build/esm/convert.js +1 -1
- package/build/esm/convert.js.map +1 -1
- package/build/esm/lib/NVM3.d.ts +6 -5
- package/build/esm/lib/NVM3.d.ts.map +1 -1
- package/build/esm/lib/NVM3.js +1 -1
- package/build/esm/lib/NVM3.js.map +1 -1
- package/build/esm/lib/NVM500.js +1 -1
- package/build/esm/lib/NVM500.js.map +1 -1
- package/build/esm/lib/common/definitions.d.ts +5 -5
- package/build/esm/lib/common/definitions.d.ts.map +1 -1
- package/build/esm/lib/common/routeCache.d.ts +2 -2
- package/build/esm/lib/common/routeCache.d.ts.map +1 -1
- package/build/esm/lib/common/routeCache.js.map +1 -1
- package/build/esm/lib/common/sucUpdateEntry.d.ts +2 -2
- package/build/esm/lib/common/sucUpdateEntry.d.ts.map +1 -1
- package/build/esm/lib/common/sucUpdateEntry.js.map +1 -1
- package/build/esm/lib/common/utils.d.ts +3 -2
- package/build/esm/lib/common/utils.d.ts.map +1 -1
- package/build/esm/lib/common/utils.js.map +1 -1
- package/build/esm/lib/io/BufferedNVMReader.d.ts +3 -2
- package/build/esm/lib/io/BufferedNVMReader.d.ts.map +1 -1
- package/build/esm/lib/io/BufferedNVMReader.js.map +1 -1
- package/build/esm/lib/io/NVMFileIO.d.ts +3 -2
- package/build/esm/lib/io/NVMFileIO.d.ts.map +1 -1
- package/build/esm/lib/io/NVMFileIO.js.map +1 -1
- package/build/esm/lib/io/NVMMemoryIO.d.ts +4 -3
- package/build/esm/lib/io/NVMMemoryIO.d.ts.map +1 -1
- package/build/esm/lib/io/NVMMemoryIO.js.map +1 -1
- package/build/esm/lib/nvm3/adapter.d.ts.map +1 -1
- package/build/esm/lib/nvm3/adapter.js.map +1 -1
- package/build/esm/lib/nvm3/files/ApplicationCCsFile.js +1 -1
- package/build/esm/lib/nvm3/files/ApplicationCCsFile.js.map +1 -1
- package/build/esm/lib/nvm3/files/ApplicationRFConfigFile.js +1 -1
- package/build/esm/lib/nvm3/files/ApplicationRFConfigFile.js.map +1 -1
- package/build/esm/lib/nvm3/files/ApplicationTypeFile.js +1 -1
- package/build/esm/lib/nvm3/files/ApplicationTypeFile.js.map +1 -1
- package/build/esm/lib/nvm3/files/ControllerInfoFile.d.ts +3 -3
- package/build/esm/lib/nvm3/files/ControllerInfoFile.d.ts.map +1 -1
- package/build/esm/lib/nvm3/files/ControllerInfoFile.js +1 -1
- package/build/esm/lib/nvm3/files/ControllerInfoFile.js.map +1 -1
- package/build/esm/lib/nvm3/files/NVMFile.d.ts +2 -2
- package/build/esm/lib/nvm3/files/NVMFile.d.ts.map +1 -1
- package/build/esm/lib/nvm3/files/NVMFile.js.map +1 -1
- package/build/esm/lib/nvm3/files/NodeInfoFiles.d.ts.map +1 -1
- package/build/esm/lib/nvm3/files/NodeInfoFiles.js +3 -3
- package/build/esm/lib/nvm3/files/NodeInfoFiles.js.map +1 -1
- package/build/esm/lib/nvm3/files/ProtocolNodeMaskFiles.js +2 -2
- package/build/esm/lib/nvm3/files/ProtocolNodeMaskFiles.js.map +1 -1
- package/build/esm/lib/nvm3/files/RouteCacheFiles.js +2 -2
- package/build/esm/lib/nvm3/files/RouteCacheFiles.js.map +1 -1
- package/build/esm/lib/nvm3/files/SUCUpdateEntriesFile.js +2 -2
- package/build/esm/lib/nvm3/files/SUCUpdateEntriesFile.js.map +1 -1
- package/build/esm/lib/nvm3/files/VersionFiles.js +1 -1
- package/build/esm/lib/nvm3/files/VersionFiles.js.map +1 -1
- package/build/esm/lib/nvm3/object.d.ts +3 -2
- package/build/esm/lib/nvm3/object.d.ts.map +1 -1
- package/build/esm/lib/nvm3/object.js.map +1 -1
- package/build/esm/lib/nvm3/page.d.ts +2 -1
- package/build/esm/lib/nvm3/page.d.ts.map +1 -1
- package/build/esm/lib/nvm3/page.js.map +1 -1
- package/build/esm/lib/nvm500/EntryParsers.d.ts +4 -4
- package/build/esm/lib/nvm500/EntryParsers.d.ts.map +1 -1
- package/build/esm/lib/nvm500/EntryParsers.js.map +1 -1
- package/build/esm/lib/nvm500/adapter.d.ts.map +1 -1
- package/build/esm/lib/nvm500/adapter.js +7 -2
- package/build/esm/lib/nvm500/adapter.js.map +1 -1
- package/build/esm/lib/nvm500/shared.d.ts +2 -1
- package/build/esm/lib/nvm500/shared.d.ts.map +1 -1
- package/build/esm/lib/nvm500/shared.js.map +1 -1
- package/package.json +7 -9
package/build/cjs/convert.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type CommandClasses, NodeIDType, type NodeProtocolInfo, RFRegion } from "@zwave-js/core";
|
|
2
|
+
import { type BytesView } from "@zwave-js/shared";
|
|
2
3
|
import { type NVM3Meta } from "./lib/NVM3.js";
|
|
3
4
|
import { type Route } from "./lib/common/routeCache.js";
|
|
4
5
|
import type { SUCUpdateEntry } from "./lib/common/sucUpdateEntry.js";
|
|
@@ -95,14 +96,14 @@ export declare function nodeHasInfo(node: NVMJSONNode): node is NVMJSONNodeWithI
|
|
|
95
96
|
/** Converts a compressed set of NVM objects to a JSON representation */
|
|
96
97
|
export declare function nvmObjectsToJSON(objects: ReadonlyMap<number, NVM3Object>): NVMJSON;
|
|
97
98
|
/** Reads an NVM buffer of a 700+ series stick and returns its JSON representation */
|
|
98
|
-
export declare function nvmToJSON(buffer:
|
|
99
|
+
export declare function nvmToJSON(buffer: BytesView, debugLogs?: boolean): Promise<NVMJSONWithMeta>;
|
|
99
100
|
/** Reads an NVM buffer of a 500-series stick and returns its JSON representation */
|
|
100
|
-
export declare function nvm500ToJSON(buffer:
|
|
101
|
-
export declare function jsonToNVM(json: NVMJSON, targetSDKVersion: string): Promise<
|
|
101
|
+
export declare function nvm500ToJSON(buffer: BytesView): Promise<Required<NVM500JSON>>;
|
|
102
|
+
export declare function jsonToNVM(json: NVMJSON, targetSDKVersion: string): Promise<BytesView>;
|
|
102
103
|
/** Takes a JSON represented 500 series NVM and converts it to binary */
|
|
103
|
-
export declare function jsonToNVM500(json: Required<NVM500JSON>, protocolVersion: string): Promise<
|
|
104
|
+
export declare function jsonToNVM500(json: Required<NVM500JSON>, protocolVersion: string): Promise<BytesView>;
|
|
104
105
|
export declare function json500To700(json: NVM500JSON, truncateApplicationData?: boolean): NVMJSON;
|
|
105
106
|
export declare function json700To500(json: NVMJSON): NVM500JSON;
|
|
106
107
|
/** Converts the given source NVM into a format that is compatible with the given target NVM */
|
|
107
|
-
export declare function migrateNVM(sourceNVM:
|
|
108
|
+
export declare function migrateNVM(sourceNVM: BytesView, targetNVM: BytesView, options?: MigrateNVMOptions): Promise<BytesView>;
|
|
108
109
|
//# sourceMappingURL=convert.d.ts.map
|
package/build/cjs/convert.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/convert.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\ttype CommandClasses,\n\tControllerCapabilityFlags,\n\tMAX_NODES,\n\tNodeIDType,\n\ttype NodeProtocolInfo,\n\tNodeType,\n\tRFRegion,\n\tstripUndefined,\n} from \"@zwave-js/core\";\nimport {\n\tZWaveError,\n\tZWaveErrorCodes,\n\tisZWaveError,\n} from \"@zwave-js/core/error\";\nimport { Bytes, buffer2hex, cloneDeep, num2hex, pick } from \"@zwave-js/shared\";\nimport { isObject } from \"alcalzone-shared/typeguards\";\nimport type { SemVer } from \"semver\";\nimport semverGte from \"semver/functions/gte.js\";\nimport semverLt from \"semver/functions/lt.js\";\nimport semverLte from \"semver/functions/lte.js\";\nimport semverParse from \"semver/functions/parse.js\";\nimport { MAX_PROTOCOL_FILE_FORMAT, SUC_MAX_UPDATES } from \"./consts.js\";\nimport { NVM3, type NVM3Meta } from \"./lib/NVM3.js\";\nimport { NVM500 } from \"./lib/NVM500.js\";\nimport {\n\ttype Route,\n\ttype RouteCache,\n\tgetEmptyRoute,\n} from \"./lib/common/routeCache.js\";\nimport type { SUCUpdateEntry } from \"./lib/common/sucUpdateEntry.js\";\nimport { NVMMemoryIO } from \"./lib/io/NVMMemoryIO.js\";\nimport { NVM3Adapter } from \"./lib/nvm3/adapter.js\";\nimport {\n\tZWAVE_APPLICATION_NVM_SIZE,\n\tZWAVE_PROTOCOL_NVM_SIZE,\n\tZWAVE_SHARED_NVM_SIZE,\n} from \"./lib/nvm3/consts.js\";\nimport {\n\ttype ApplicationNameFile,\n\tApplicationNameFileID,\n} from \"./lib/nvm3/files/ApplicationNameFile.js\";\nimport {\n\tApplicationCCsFile,\n\tApplicationCCsFileID,\n\ttype ApplicationDataFile,\n\tApplicationDataFileID,\n\tApplicationRFConfigFile,\n\tApplicationRFConfigFileID,\n\tApplicationTypeFile,\n\tApplicationTypeFileID,\n\tApplicationVersionFile,\n\tApplicationVersionFile800,\n\tApplicationVersionFile800ID,\n\tApplicationVersionFileID,\n\tControllerInfoFile,\n\tControllerInfoFileID,\n\ttype ControllerInfoFileOptions,\n\ttype LRNodeInfo,\n\ttype LRNodeInfoFileV5,\n\tNVMFile,\n\ttype NodeInfo,\n\ttype NodeInfoFileV0,\n\ttype NodeInfoFileV1,\n\ttype ProtocolAppRouteLockNodeMaskFile,\n\tProtocolAppRouteLockNodeMaskFileID,\n\ttype ProtocolLRNodeListFile,\n\tProtocolLRNodeListFileID,\n\ttype ProtocolNodeListFile,\n\tProtocolNodeListFileID,\n\ttype ProtocolPendingDiscoveryNodeMaskFile,\n\tProtocolPendingDiscoveryNodeMaskFileID,\n\ttype ProtocolPreferredRepeatersFile,\n\tProtocolPreferredRepeatersFileID,\n\tProtocolRouteCacheExistsNodeMaskFile,\n\tProtocolRouteCacheExistsNodeMaskFileID,\n\ttype ProtocolRouteSlaveSUCNodeMaskFile,\n\tProtocolRouteSlaveSUCNodeMaskFileID,\n\ttype ProtocolSUCPendingUpdateNodeMaskFile,\n\tProtocolSUCPendingUpdateNodeMaskFileID,\n\tProtocolVersionFile,\n\tProtocolVersionFileID,\n\ttype ProtocolVirtualNodeMaskFile,\n\tProtocolVirtualNodeMaskFileID,\n\ttype RouteCacheFileV0,\n\ttype RouteCacheFileV1,\n\tSUCUpdateEntriesFileIDV0,\n\ttype SUCUpdateEntriesFileV0,\n\ttype SUCUpdateEntriesFileV5,\n\tSUC_UPDATES_PER_FILE_V5,\n\tnodeIdToLRNodeInfoFileIDV5,\n\tnodeIdToNodeInfoFileIDV0,\n\tnodeIdToNodeInfoFileIDV1,\n\tnodeIdToRouteCacheFileIDV0,\n\tnodeIdToRouteCacheFileIDV1,\n\tsucUpdateIndexToSUCUpdateEntriesFileIDV5,\n} from \"./lib/nvm3/files/index.js\";\nimport type { NVM3Object } from \"./lib/nvm3/object.js\";\nimport { dumpNVM, mapToObject } from \"./lib/nvm3/utils.js\";\nimport { NVM500Adapter } from \"./lib/nvm500/adapter.js\";\nimport { nvm500Impls } from \"./lib/nvm500/impls/index.js\";\nimport { resolveLayout } from \"./lib/nvm500/shared.js\";\nimport type {\n\tNVM500JSON,\n\tNVM500JSONController,\n\tNVM500JSONNode,\n\tNVM500Meta,\n} from \"./nvm500/NVMParser.js\";\n\nexport interface NVMJSON {\n\tformat: number; // protocol file format\n\tapplicationFileFormat?: number;\n\tmeta?: NVM3Meta;\n\tcontroller: NVMJSONController;\n\tnodes: Record<number, NVMJSONNode>;\n\tlrNodes?: Record<number, NVMJSONLRNode>;\n}\n\nexport type NVMJSONWithMeta = NVMJSON & { meta: NVM3Meta };\n\nexport interface NVMJSONController {\n\tprotocolVersion: string;\n\tapplicationVersion: string;\n\thomeId: string;\n\tnodeId: number;\n\tlastNodeId: number;\n\tstaticControllerNodeId: number;\n\tsucLastIndex: number;\n\tcontrollerConfiguration: number;\n\tsucUpdateEntries: SUCUpdateEntry[];\n\tsucAwarenessPushNeeded?: number | null;\n\tmaxNodeId: number;\n\treservedId: number;\n\tsystemState: number;\n\tlastNodeIdLR?: number | null;\n\tmaxNodeIdLR?: number | null;\n\treservedIdLR?: number | null;\n\tprimaryLongRangeChannelId?: number | null;\n\tdcdcConfig?: number | null;\n\trfConfig?: NVMJSONControllerRFConfig | null;\n\tpreferredRepeaters?: number[] | null;\n\n\tisListening: boolean;\n\toptionalFunctionality: boolean;\n\tgenericDeviceClass: number;\n\tspecificDeviceClass: number;\n\n\tcommandClasses: {\n\t\tincludedInsecurely: CommandClasses[];\n\t\tincludedSecurelyInsecureCCs: CommandClasses[];\n\t\tincludedSecurelySecureCCs: CommandClasses[];\n\t};\n\n\tapplicationData?: string | null;\n\tapplicationName?: string | null;\n}\n\nexport interface NVMJSONControllerRFConfig {\n\trfRegion: RFRegion;\n\ttxPower: number;\n\tmeasured0dBm: number;\n\tenablePTI: number | null;\n\tmaxTXPower: number | null;\n\tnodeIdType: NodeIDType | null;\n}\n\nexport interface NVMJSONNodeWithInfo\n\textends Omit<NodeProtocolInfo, \"hasSpecificDeviceClass\">\n{\n\tisVirtual: boolean;\n\n\tgenericDeviceClass: number;\n\tspecificDeviceClass: number | null;\n\tneighbors: number[];\n\tsucUpdateIndex: number;\n\n\tappRouteLock: boolean;\n\trouteSlaveSUC: boolean;\n\tsucPendingUpdate: boolean;\n\tpendingDiscovery: boolean;\n\n\tlwr?: Route | null;\n\tnlwr?: Route | null;\n}\n\n// Unlike NVMJSONNodeWithInfo this does not carry any node information\nexport interface NVMJSONVirtualNode {\n\tisVirtual: true;\n}\n\nexport interface NVMJSONLRNode\n\textends Omit<NodeProtocolInfo, \"hasSpecificDeviceClass\">\n{\n\tgenericDeviceClass: number;\n\tspecificDeviceClass?: number | null;\n}\n\nexport type NVMJSONNode = NVMJSONNodeWithInfo | NVMJSONVirtualNode;\n\ntype ParsedNVM =\n\t| {\n\t\ttype: 500;\n\t\tjson: Required<NVM500JSON>;\n\t}\n\t| {\n\t\ttype: 700;\n\t\tjson: NVMJSONWithMeta;\n\t}\n\t| {\n\t\ttype: \"unknown\";\n\t};\n\n/**\n * Options influencing how NVM contents should be migrated.\n * By default, all data will be preserved.\n */\nexport interface MigrateNVMOptions {\n\t/** Whether application data will be preserved */\n\tpreserveApplicationData?: boolean;\n\t/** Whether SUC update entries will be preserved */\n\tpreserveSUCUpdateEntries?: boolean;\n\t/** Whether LWR, NLWR and the priority route flag will be preserved */\n\tpreserveRoutes?: boolean;\n\t/** Whether the neighbor table will be preserved */\n\tpreserveNeighbors?: boolean;\n}\n\nexport function nodeHasInfo(node: NVMJSONNode): node is NVMJSONNodeWithInfo {\n\treturn !node.isVirtual || Object.keys(node).length > 1;\n}\n\nfunction createEmptyPhysicalNode(): NVMJSONNodeWithInfo {\n\treturn {\n\t\tisVirtual: false,\n\t\tisListening: false,\n\t\tisFrequentListening: false,\n\t\tisRouting: false,\n\t\tsupportedDataRates: [],\n\t\tprotocolVersion: 0,\n\t\toptionalFunctionality: false,\n\t\tnodeType: NodeType[\"End Node\"],\n\t\tsupportsSecurity: false,\n\t\tsupportsBeaming: false,\n\t\tgenericDeviceClass: 0,\n\t\tspecificDeviceClass: null,\n\t\tneighbors: [],\n\t\tsucUpdateIndex: 0,\n\t\tappRouteLock: false,\n\t\trouteSlaveSUC: false,\n\t\tsucPendingUpdate: false,\n\t\tpendingDiscovery: false,\n\t\tlwr: null,\n\t\tnlwr: null,\n\t};\n}\n\nfunction createEmptyLRNode(): NVMJSONLRNode {\n\treturn {\n\t\tisListening: false,\n\t\tisFrequentListening: false,\n\t\tisRouting: false,\n\t\tsupportedDataRates: [],\n\t\tprotocolVersion: 3,\n\t\toptionalFunctionality: false,\n\t\tnodeType: NodeType[\"End Node\"],\n\t\tsupportsSecurity: true,\n\t\tsupportsBeaming: false,\n\t\tgenericDeviceClass: 0,\n\t\tspecificDeviceClass: null,\n\t};\n}\n\n/** Converts a compressed set of NVM objects to a JSON representation */\nexport function nvmObjectsToJSON(\n\tobjects: ReadonlyMap<number, NVM3Object>,\n): NVMJSON {\n\tconst nodes = new Map<number, NVMJSONNode>();\n\tconst getNode = (id: number): NVMJSONNode => {\n\t\tif (!nodes.has(id)) nodes.set(id, createEmptyPhysicalNode());\n\t\treturn nodes.get(id)!;\n\t};\n\n\tconst lrNodes = new Map<number, NVMJSONLRNode>();\n\tconst getLRNode = (id: number): NVMJSONLRNode => {\n\t\tif (!lrNodes.has(id)) lrNodes.set(id, createEmptyLRNode());\n\t\treturn lrNodes.get(id)!;\n\t};\n\n\tconst getObject = (\n\t\tid: number | ((id: number) => boolean),\n\t): NVM3Object | undefined => {\n\t\tif (typeof id === \"number\") {\n\t\t\treturn objects.get(id);\n\t\t} else {\n\t\t\tfor (const [key, obj] of objects) {\n\t\t\t\tif (id(key)) return obj;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst getObjectOrThrow = (\n\t\tid: number | ((id: number) => boolean),\n\t): NVM3Object => {\n\t\tconst ret = getObject(id);\n\t\tif (ret) return ret;\n\t\tthrow new ZWaveError(\n\t\t\t`Object${\n\t\t\t\ttypeof id === \"number\" ? ` ${num2hex(id)} (${id})` : \"\"\n\t\t\t} not found!`,\n\t\t\tZWaveErrorCodes.NVM_ObjectNotFound,\n\t\t);\n\t};\n\n\tconst getFileOrThrow = <T extends NVMFile>(\n\t\tid: number | ((id: number) => boolean),\n\t\tfileVersion: string,\n\t): T => {\n\t\tconst obj = getObjectOrThrow(id);\n\t\treturn NVMFile.from(obj.key, obj.data!, fileVersion) as T;\n\t};\n\n\tconst getFile = <T extends NVMFile>(\n\t\tid: number | ((id: number) => boolean),\n\t\tfileVersion: string,\n\t): T | undefined => {\n\t\tconst obj = getObject(id);\n\t\tif (!obj || !obj.data) return undefined;\n\t\treturn NVMFile.from(obj.key, obj.data, fileVersion) as T;\n\t};\n\n\t// === Protocol NVM files ===\n\n\t// Figure out how to parse the individual files\n\tconst protocolVersionFile = getFileOrThrow<ProtocolVersionFile>(\n\t\tProtocolVersionFileID,\n\t\t\"7.0.0\", // We don't know the version here yet\n\t);\n\tconst protocolFileFormat = protocolVersionFile.format;\n\tconst protocolVersion =\n\t\t`${protocolVersionFile.major}.${protocolVersionFile.minor}.${protocolVersionFile.patch}`;\n\n\t// Bail early if the NVM uses a protocol file format that's newer than we support\n\tif (protocolFileFormat > MAX_PROTOCOL_FILE_FORMAT) {\n\t\tthrow new ZWaveError(\n\t\t\t`Unsupported protocol file format: ${protocolFileFormat}`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t\t{ protocolFileFormat },\n\t\t);\n\t}\n\n\t// Figure out which nodes exist\n\tconst nodeIds = getFileOrThrow<ProtocolNodeListFile>(\n\t\tProtocolNodeListFileID,\n\t\tprotocolVersion,\n\t).nodeIds;\n\n\t// Read all flags for all nodes\n\tconst appRouteLock = new Set(\n\t\tgetFileOrThrow<ProtocolAppRouteLockNodeMaskFile>(\n\t\t\tProtocolAppRouteLockNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst routeSlaveSUC = new Set(\n\t\tgetFileOrThrow<ProtocolRouteSlaveSUCNodeMaskFile>(\n\t\t\tProtocolRouteSlaveSUCNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst sucPendingUpdate = new Set(\n\t\tgetFileOrThrow<ProtocolSUCPendingUpdateNodeMaskFile>(\n\t\t\tProtocolSUCPendingUpdateNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst isVirtual = new Set(\n\t\tgetFileOrThrow<ProtocolVirtualNodeMaskFile>(\n\t\t\tProtocolVirtualNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst pendingDiscovery = new Set(\n\t\tgetFileOrThrow<ProtocolPendingDiscoveryNodeMaskFile>(\n\t\t\tProtocolPendingDiscoveryNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst routeCacheExists = new Set(\n\t\tgetFileOrThrow<ProtocolRouteCacheExistsNodeMaskFile>(\n\t\t\tProtocolRouteCacheExistsNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\n\t// And create each node entry, including virtual ones\n\tfor (const id of nodeIds) {\n\t\tconst node = getNode(id) as NVMJSONNodeWithInfo;\n\n\t\tconst rememberOnlyVirtual = () => {\n\t\t\tnodes.set(id, {\n\t\t\t\tisVirtual: true,\n\t\t\t});\n\t\t};\n\n\t\t// Find node info\n\t\tlet nodeInfo: NodeInfo;\n\t\ttry {\n\t\t\tif (protocolFileFormat === 0) {\n\t\t\t\tconst fileId = nodeIdToNodeInfoFileIDV0(id);\n\t\t\t\tconst file = getFileOrThrow<NodeInfoFileV0>(\n\t\t\t\t\tfileId,\n\t\t\t\t\tprotocolVersion,\n\t\t\t\t);\n\t\t\t\tnodeInfo = file.nodeInfo;\n\t\t\t} else {\n\t\t\t\tconst fileId = nodeIdToNodeInfoFileIDV1(id);\n\t\t\t\tconst file = getFileOrThrow<NodeInfoFileV1>(\n\t\t\t\t\tfileId,\n\t\t\t\t\tprotocolVersion,\n\t\t\t\t);\n\t\t\t\tnodeInfo = file.nodeInfos.find((i) => i.nodeId === id)!;\n\t\t\t}\n\t\t} catch (e: any) {\n\t\t\tif (e.message.includes(\"Object not found\")) {\n\t\t\t\trememberOnlyVirtual();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\n\t\tObject.assign(node, nodeInfo);\n\n\t\t// Evaluate flags\n\t\tnode.isVirtual = isVirtual.has(id);\n\t\tnode.appRouteLock = appRouteLock.has(id);\n\t\tnode.routeSlaveSUC = routeSlaveSUC.has(id);\n\t\tnode.sucPendingUpdate = sucPendingUpdate.has(id);\n\t\tnode.pendingDiscovery = pendingDiscovery.has(id);\n\t\tif (routeCacheExists.has(id)) {\n\t\t\tlet routeCache: RouteCache | undefined;\n\t\t\tif (protocolFileFormat === 0) {\n\t\t\t\tconst fileId = nodeIdToRouteCacheFileIDV0(id);\n\t\t\t\tconst file = getFile<RouteCacheFileV0>(fileId, protocolVersion);\n\t\t\t\trouteCache = file?.routeCache;\n\t\t\t} else {\n\t\t\t\tconst fileId = nodeIdToRouteCacheFileIDV1(id);\n\t\t\t\tconst file = getFile<RouteCacheFileV1>(fileId, protocolVersion);\n\t\t\t\trouteCache = file?.routeCaches.find((i) => i.nodeId === id);\n\t\t\t}\n\t\t\tif (routeCache) {\n\t\t\t\tnode.lwr = routeCache.lwr;\n\t\t\t\tnode.nlwr = routeCache.nlwr;\n\t\t\t}\n\t\t}\n\n\t\t// @ts-expect-error Some fields include a nodeId, but we don't need it\n\t\tdelete node.nodeId;\n\t}\n\n\t// If they exist, read info about LR nodes\n\tconst lrNodeIds = getFile<ProtocolLRNodeListFile>(\n\t\tProtocolLRNodeListFileID,\n\t\tprotocolVersion,\n\t)?.nodeIds;\n\tif (lrNodeIds) {\n\t\tfor (const id of lrNodeIds) {\n\t\t\tconst node = getLRNode(id);\n\n\t\t\t// Find node info\n\t\t\tconst fileId = nodeIdToLRNodeInfoFileIDV5(id);\n\t\t\tconst file = getFileOrThrow<LRNodeInfoFileV5>(\n\t\t\t\tfileId,\n\t\t\t\tprotocolVersion,\n\t\t\t);\n\t\t\tconst { nodeId, ...nodeInfo } = file.nodeInfos.find((i) =>\n\t\t\t\ti.nodeId === id\n\t\t\t)!;\n\n\t\t\tObject.assign(node, nodeInfo);\n\t\t}\n\t}\n\n\t// Now read info about the controller\n\tconst controllerInfoFile = getFileOrThrow<ControllerInfoFile>(\n\t\tControllerInfoFileID,\n\t\tprotocolVersion,\n\t);\n\n\tlet sucUpdateEntries: SUCUpdateEntry[];\n\tif (protocolFileFormat < 5) {\n\t\tsucUpdateEntries = getFileOrThrow<SUCUpdateEntriesFileV0>(\n\t\t\tSUCUpdateEntriesFileIDV0,\n\t\t\tprotocolVersion,\n\t\t).updateEntries;\n\t} else {\n\t\t// V5 has split the entries into multiple files\n\t\tsucUpdateEntries = [];\n\t\tfor (\n\t\t\tlet index = 0;\n\t\t\tindex < SUC_MAX_UPDATES;\n\t\t\tindex += SUC_UPDATES_PER_FILE_V5\n\t\t) {\n\t\t\tconst file = getFile<SUCUpdateEntriesFileV5>(\n\t\t\t\tsucUpdateIndexToSUCUpdateEntriesFileIDV5(index),\n\t\t\t\tprotocolVersion,\n\t\t\t);\n\t\t\tif (!file) break;\n\t\t\tsucUpdateEntries.push(...file.updateEntries);\n\t\t}\n\t}\n\n\t// === Application NVM files ===\n\n\tconst applicationVersionFile700 = getFile<ApplicationVersionFile>(\n\t\tApplicationVersionFileID,\n\t\t\"7.0.0\", // We don't know the version here yet\n\t);\n\tconst applicationVersionFile800 = getFile<ApplicationVersionFile800>(\n\t\tApplicationVersionFile800ID,\n\t\t\"7.0.0\", // We don't know the version here yet\n\t);\n\tconst applicationVersionFile = applicationVersionFile700\n\t\t?? applicationVersionFile800;\n\tif (!applicationVersionFile) {\n\t\tthrow new ZWaveError(\n\t\t\t\"ApplicationVersionFile not found!\",\n\t\t\tZWaveErrorCodes.NVM_ObjectNotFound,\n\t\t);\n\t}\n\tconst applicationVersion =\n\t\t`${applicationVersionFile.major}.${applicationVersionFile.minor}.${applicationVersionFile.patch}`;\n\n\tconst rfConfigFile = getFile<ApplicationRFConfigFile>(\n\t\tApplicationRFConfigFileID,\n\t\tapplicationVersion,\n\t);\n\tconst applicationCCsFile = getFileOrThrow<ApplicationCCsFile>(\n\t\tApplicationCCsFileID,\n\t\tapplicationVersion,\n\t);\n\tconst applicationDataFile = getFile<ApplicationDataFile>(\n\t\tApplicationDataFileID,\n\t\tapplicationVersion,\n\t);\n\tconst applicationTypeFile = getFileOrThrow<ApplicationTypeFile>(\n\t\tApplicationTypeFileID,\n\t\tapplicationVersion,\n\t);\n\tconst applicationNameFile = getFile<ApplicationNameFile>(\n\t\tApplicationNameFileID,\n\t\tapplicationVersion,\n\t);\n\n\tconst preferredRepeaters = getFile<ProtocolPreferredRepeatersFile>(\n\t\tProtocolPreferredRepeatersFileID,\n\t\tapplicationVersion,\n\t)?.nodeIds;\n\n\tconst controllerProps = [\n\t\t\"nodeId\",\n\t\t\"lastNodeId\",\n\t\t\"staticControllerNodeId\",\n\t\t\"sucLastIndex\",\n\t\t\"controllerConfiguration\",\n\t\t\"sucAwarenessPushNeeded\",\n\t\t\"maxNodeId\",\n\t\t\"reservedId\",\n\t\t\"systemState\",\n\t\t\"lastNodeIdLR\",\n\t\t\"maxNodeIdLR\",\n\t\t\"reservedIdLR\",\n\t\t\"primaryLongRangeChannelId\",\n\t\t\"dcdcConfig\",\n\t] as const;\n\tconst controller: NVMJSONController = {\n\t\tprotocolVersion,\n\t\tapplicationVersion,\n\t\thomeId: buffer2hex(controllerInfoFile.homeId),\n\t\t...pick(controllerInfoFile, controllerProps),\n\t\t...pick(applicationTypeFile, [\n\t\t\t\"isListening\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t]),\n\t\tcommandClasses: pick(applicationCCsFile, [\n\t\t\t\"includedInsecurely\",\n\t\t\t\"includedSecurelyInsecureCCs\",\n\t\t\t\"includedSecurelySecureCCs\",\n\t\t]),\n\t\tpreferredRepeaters,\n\t\t...(rfConfigFile\n\t\t\t? {\n\t\t\t\trfConfig: {\n\t\t\t\t\trfRegion: rfConfigFile.rfRegion,\n\t\t\t\t\ttxPower: rfConfigFile.txPower,\n\t\t\t\t\tmeasured0dBm: rfConfigFile.measured0dBm,\n\t\t\t\t\tenablePTI: rfConfigFile.enablePTI ?? null,\n\t\t\t\t\tmaxTXPower: rfConfigFile.maxTXPower ?? null,\n\t\t\t\t\tnodeIdType: rfConfigFile.nodeIdType ?? null,\n\t\t\t\t},\n\t\t\t}\n\t\t\t: {}),\n\t\tsucUpdateEntries,\n\t\tapplicationData: applicationDataFile?.applicationData.toString(\"hex\")\n\t\t\t?? null,\n\t\tapplicationName: applicationNameFile?.name ?? null,\n\t};\n\n\t// Make sure all props are defined\n\tconst optionalControllerProps = [\n\t\t\"sucAwarenessPushNeeded\",\n\t\t\"lastNodeIdLR\",\n\t\t\"maxNodeIdLR\",\n\t\t\"reservedIdLR\",\n\t\t\"primaryLongRangeChannelId\",\n\t\t\"dcdcConfig\",\n\t\t\"rfConfig\",\n\t\t\"preferredRepeaters\",\n\t\t\"applicationData\",\n\t] as const;\n\tfor (const prop of optionalControllerProps) {\n\t\tif (controller[prop] === undefined) controller[prop] = null;\n\t}\n\n\tconst ret: NVMJSON = {\n\t\tformat: protocolFileFormat,\n\t\tcontroller,\n\t\tnodes: mapToObject(nodes),\n\t};\n\tif (lrNodes.size > 0) {\n\t\tret.lrNodes = mapToObject(lrNodes);\n\t}\n\n\treturn ret;\n}\n\nfunction nvmJSONNodeToNodeInfo(\n\tnodeId: number,\n\tnode: NVMJSONNodeWithInfo,\n): NodeInfo {\n\treturn {\n\t\tnodeId,\n\t\t...pick(node, [\n\t\t\t\"isListening\",\n\t\t\t\"isFrequentListening\",\n\t\t\t\"isRouting\",\n\t\t\t\"supportedDataRates\",\n\t\t\t\"protocolVersion\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"nodeType\",\n\t\t\t\"supportsSecurity\",\n\t\t\t\"supportsBeaming\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t\t\"neighbors\",\n\t\t\t\"sucUpdateIndex\",\n\t\t]),\n\t};\n}\n\nfunction nvmJSONLRNodeToLRNodeInfo(\n\tnodeId: number,\n\tnode: NVMJSONLRNode,\n): LRNodeInfo {\n\treturn {\n\t\tnodeId,\n\t\t...pick(node, [\n\t\t\t\"isListening\",\n\t\t\t\"isFrequentListening\",\n\t\t\t\"isRouting\",\n\t\t\t\"supportedDataRates\",\n\t\t\t\"protocolVersion\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"nodeType\",\n\t\t\t\"supportsSecurity\",\n\t\t\t\"supportsBeaming\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t]),\n\t};\n}\n\nfunction nvmJSONControllerToFileOptions(\n\tctrlr: NVMJSONController,\n): ControllerInfoFileOptions {\n\tconst ret = {\n\t\thomeId: Bytes.from(ctrlr.homeId.replace(/^0x/, \"\"), \"hex\"),\n\t\tnodeId: ctrlr.nodeId,\n\t\tlastNodeId: ctrlr.lastNodeId,\n\t\tstaticControllerNodeId: ctrlr.staticControllerNodeId,\n\t\tsucLastIndex: ctrlr.sucLastIndex,\n\t\tcontrollerConfiguration: ctrlr.controllerConfiguration,\n\t\tmaxNodeId: ctrlr.maxNodeId,\n\t\treservedId: ctrlr.reservedId,\n\t\tsystemState: ctrlr.systemState,\n\t} as unknown as ControllerInfoFileOptions;\n\tif (ctrlr.sucAwarenessPushNeeded != undefined) {\n\t\t// @ts-expect-error We're dealing with a conditional object here\n\t\t// TS doesn't like that.\n\t\tret.sucAwarenessPushNeeded = ctrlr.sucAwarenessPushNeeded;\n\t} else {\n\t\tObject.assign(\n\t\t\tret,\n\t\t\tstripUndefined(\n\t\t\t\tpick(ctrlr, [\n\t\t\t\t\t\"sucAwarenessPushNeeded\",\n\t\t\t\t\t\"lastNodeIdLR\",\n\t\t\t\t\t\"maxNodeIdLR\",\n\t\t\t\t\t\"reservedIdLR\",\n\t\t\t\t\t\"primaryLongRangeChannelId\",\n\t\t\t\t\t\"dcdcConfig\",\n\t\t\t\t]),\n\t\t\t),\n\t\t);\n\t}\n\treturn ret;\n}\n\n/** Reads an NVM buffer of a 700+ series stick and returns its JSON representation */\nexport async function nvmToJSON(\n\tbuffer: Uint8Array,\n\tdebugLogs: boolean = false,\n): Promise<NVMJSONWithMeta> {\n\tconst io = new NVMMemoryIO(buffer);\n\tconst nvm3 = new NVM3(io);\n\tconst info = await nvm3.init();\n\n\tconst adapter = new NVM3Adapter(nvm3);\n\n\tif (debugLogs) {\n\t\t// Dump all pages, all raw objects in each page, and each object in its final state\n\t\tawait dumpNVM(nvm3);\n\t}\n\n\tconst firstPageHeader = info.isSharedFileSystem\n\t\t? info.sections.all.pages[0]\n\t\t: info.sections.protocol.pages[0];\n\n\tconst meta: NVM3Meta = {\n\t\tsharedFileSystem: info.isSharedFileSystem,\n\t\t...pick(firstPageHeader, [\n\t\t\t\"pageSize\",\n\t\t\t\"writeSize\",\n\t\t\t\"memoryMapped\",\n\t\t\t\"deviceFamily\",\n\t\t]),\n\t};\n\n\tconst nodes = new Map<number, NVMJSONNode>();\n\tconst getNode = (id: number): NVMJSONNode => {\n\t\tif (!nodes.has(id)) nodes.set(id, createEmptyPhysicalNode());\n\t\treturn nodes.get(id)!;\n\t};\n\n\tconst lrNodes = new Map<number, NVMJSONLRNode>();\n\tconst getLRNode = (id: number): NVMJSONLRNode => {\n\t\tif (!lrNodes.has(id)) lrNodes.set(id, createEmptyLRNode());\n\t\treturn lrNodes.get(id)!;\n\t};\n\n\tlet protocolFileFormat: number;\n\tlet protocolVersion: string;\n\ttry {\n\t\tprotocolFileFormat = await adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"protocolFileFormat\",\n\t\t}, true);\n\t\tprotocolVersion = await adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"protocolVersion\",\n\t\t}, true);\n\t} catch (e) {\n\t\t// Firmwares based on SDK 7.23.0 and 7.23.1 do not write the protocol format/version to NVM,\n\t\t// so file 0x50000 is missing. Those are out in the wild, so we need to work around this.\n\t\t// There are a few heuristics we can use, assuming that Silabs doesn't break this again in a later version:\n\t\t// - SDK < 7.23.0 are not affected, also 7.23.2+ is fixed\n\t\tlet isSDK723 = true;\n\t\t// - The ApplicationRFConfigFile (0x68) exists and has 9 bytes\n\t\tisSDK723 &&= (await nvm3.get(ApplicationRFConfigFileID))?.length == 9;\n\t\t// - The ApplicationVersionFile800 (0x41000) exists\n\t\tisSDK723 &&= !!(await nvm3.get(ApplicationVersionFile800ID));\n\t\t// - The ProtocolLRNodeListFile (0x5000c) exists\n\t\tisSDK723 &&= !!(await nvm3.get(ProtocolLRNodeListFileID));\n\t\t// - The ControllerInfoFile (0x50004) exists and has 22 bytes\n\t\tisSDK723 &&= (await nvm3.get(ControllerInfoFileID))?.length == 22;\n\n\t\tif (isSDK723) {\n\t\t\t// Remember the expected format\n\t\t\tprotocolVersion = \"7.23.0\";\n\t\t\tprotocolFileFormat = 5;\n\t\t\t// And also mirror it back to the NVM adapter. We never save it to NVM,\n\t\t\t// so we can just set the file.\n\t\t\tadapter.setFile(\n\t\t\t\tnew ProtocolVersionFile({\n\t\t\t\t\tfileVersion: protocolVersion,\n\t\t\t\t\tformat: protocolFileFormat,\n\t\t\t\t\tmajor: 7,\n\t\t\t\t\tminor: 23,\n\t\t\t\t\tpatch: 0,\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// And we need to init the adapter again\n\t\t\tawait adapter[\"init\"]();\n\t\t} else {\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Bail early if the NVM uses a protocol file format that's newer than we support\n\tif (protocolFileFormat > MAX_PROTOCOL_FILE_FORMAT) {\n\t\tthrow new ZWaveError(\n\t\t\t`Unsupported protocol file format: ${protocolFileFormat}`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t\t{ protocolFileFormat },\n\t\t);\n\t}\n\n\t// Read all flags for all nodes\n\tconst appRouteLock = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"appRouteLock\",\n\t\t}, true),\n\t);\n\tconst routeSlaveSUC = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"routeSlaveSUC\",\n\t\t}, true),\n\t);\n\tconst sucPendingUpdate = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"sucPendingUpdate\",\n\t\t}, true),\n\t);\n\tconst virtualNodeIds = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"virtualNodeIds\",\n\t\t}, true),\n\t);\n\tconst pendingDiscovery = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"pendingDiscovery\",\n\t\t}, true),\n\t);\n\n\t// Figure out which nodes exist\n\tconst nodeIds = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"nodeIds\",\n\t}, true);\n\n\t// And create each node entry, including virtual ones\n\tfor (const id of nodeIds) {\n\t\tconst node = getNode(id) as NVMJSONNodeWithInfo;\n\n\t\t// Find node info\n\t\tconst nodeInfo = await adapter.get({\n\t\t\tdomain: \"node\",\n\t\t\tnodeId: id,\n\t\t\ttype: \"info\",\n\t\t}, true);\n\n\t\tObject.assign(node, nodeInfo);\n\n\t\t// Evaluate flags\n\t\tnode.isVirtual = virtualNodeIds.has(id);\n\t\tnode.appRouteLock = appRouteLock.has(id);\n\t\tnode.routeSlaveSUC = routeSlaveSUC.has(id);\n\t\tnode.sucPendingUpdate = sucPendingUpdate.has(id);\n\t\tnode.pendingDiscovery = pendingDiscovery.has(id);\n\n\t\tconst routes = await adapter.get({\n\t\t\tdomain: \"node\",\n\t\t\tnodeId: id,\n\t\t\ttype: \"routes\",\n\t\t});\n\t\tif (routes) {\n\t\t\tnode.lwr = routes.lwr;\n\t\t\tnode.nlwr = routes.nlwr;\n\t\t}\n\n\t\t// @ts-expect-error Some fields include a nodeId, but we don't need it\n\t\tdelete node.nodeId;\n\t}\n\n\t// If they exist, read info about LR nodes\n\tconst lrNodeIds = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"lrNodeIds\",\n\t});\n\tif (lrNodeIds) {\n\t\tfor (const id of lrNodeIds) {\n\t\t\tconst node = getLRNode(id);\n\n\t\t\t// Find node info\n\t\t\tconst nodeInfo = await adapter.get({\n\t\t\t\tdomain: \"lrnode\",\n\t\t\t\tnodeId: id,\n\t\t\t\ttype: \"info\",\n\t\t\t}, true);\n\n\t\t\tObject.assign(node, nodeInfo);\n\t\t}\n\t}\n\n\t// Read info about the controller\n\tconst sucUpdateEntries = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"sucUpdateEntries\",\n\t}, true);\n\n\tconst applicationVersion = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationVersion\",\n\t}, true);\n\n\tconst applicationFileFormat = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationFileFormat\",\n\t}, true);\n\n\tconst applicationData = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationData\",\n\t});\n\n\tconst applicationName = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationName\",\n\t});\n\n\tconst preferredRepeaters = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"preferredRepeaters\",\n\t});\n\n\t// The following are a bit awkward to read one by one, so we just take the files\n\tconst controllerInfoFile = await adapter.getFile<ControllerInfoFile>(\n\t\tControllerInfoFileID,\n\t\ttrue,\n\t);\n\tconst rfConfigFile = await adapter.getFile<ApplicationRFConfigFile>(\n\t\tApplicationRFConfigFileID,\n\t);\n\tconst applicationCCsFile = await adapter.getFile<ApplicationCCsFile>(\n\t\tApplicationCCsFileID,\n\t\ttrue,\n\t);\n\tconst applicationTypeFile = await adapter.getFile<ApplicationTypeFile>(\n\t\tApplicationTypeFileID,\n\t\ttrue,\n\t);\n\n\tconst controller: NVMJSONController = {\n\t\tprotocolVersion,\n\t\tapplicationVersion,\n\t\thomeId: buffer2hex(controllerInfoFile.homeId),\n\t\t...pick(controllerInfoFile, [\n\t\t\t\"nodeId\",\n\t\t\t\"lastNodeId\",\n\t\t\t\"staticControllerNodeId\",\n\t\t\t\"sucLastIndex\",\n\t\t\t\"controllerConfiguration\",\n\t\t\t\"sucAwarenessPushNeeded\",\n\t\t\t\"maxNodeId\",\n\t\t\t\"reservedId\",\n\t\t\t\"systemState\",\n\t\t\t\"lastNodeIdLR\",\n\t\t\t\"maxNodeIdLR\",\n\t\t\t\"reservedIdLR\",\n\t\t\t\"primaryLongRangeChannelId\",\n\t\t\t\"dcdcConfig\",\n\t\t]),\n\t\t...pick(applicationTypeFile, [\n\t\t\t\"isListening\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t]),\n\t\tcommandClasses: pick(applicationCCsFile, [\n\t\t\t\"includedInsecurely\",\n\t\t\t\"includedSecurelyInsecureCCs\",\n\t\t\t\"includedSecurelySecureCCs\",\n\t\t]),\n\t\tpreferredRepeaters,\n\t\t...(rfConfigFile\n\t\t\t? {\n\t\t\t\trfConfig: {\n\t\t\t\t\trfRegion: rfConfigFile.rfRegion,\n\t\t\t\t\ttxPower: rfConfigFile.txPower,\n\t\t\t\t\tmeasured0dBm: rfConfigFile.measured0dBm,\n\t\t\t\t\tenablePTI: rfConfigFile.enablePTI ?? null,\n\t\t\t\t\tmaxTXPower: rfConfigFile.maxTXPower ?? null,\n\t\t\t\t\tnodeIdType: rfConfigFile.nodeIdType ?? null,\n\t\t\t\t},\n\t\t\t}\n\t\t\t: {}),\n\t\tsucUpdateEntries,\n\t\tapplicationData:\n\t\t\t(applicationData && Bytes.view(applicationData).toString(\"hex\"))\n\t\t\t\t?? null,\n\t\tapplicationName: applicationName ?? null,\n\t};\n\n\t// Make sure all props are defined\n\tconst optionalControllerProps = [\n\t\t\"sucAwarenessPushNeeded\",\n\t\t\"lastNodeIdLR\",\n\t\t\"maxNodeIdLR\",\n\t\t\"reservedIdLR\",\n\t\t\"primaryLongRangeChannelId\",\n\t\t\"dcdcConfig\",\n\t\t\"rfConfig\",\n\t\t\"preferredRepeaters\",\n\t\t\"applicationData\",\n\t] as const;\n\tfor (const prop of optionalControllerProps) {\n\t\tif (controller[prop] === undefined) controller[prop] = null;\n\t}\n\n\tconst ret: NVMJSONWithMeta = {\n\t\tformat: protocolFileFormat,\n\t\tcontroller,\n\t\tnodes: mapToObject(nodes),\n\t\tmeta,\n\t};\n\tif (applicationFileFormat !== 0) {\n\t\tret.applicationFileFormat = applicationFileFormat;\n\t}\n\tif (lrNodes.size > 0) {\n\t\tret.lrNodes = mapToObject(lrNodes);\n\t}\n\treturn ret;\n}\n\n/** Reads an NVM buffer of a 500-series stick and returns its JSON representation */\nexport async function nvm500ToJSON(\n\tbuffer: Uint8Array,\n): Promise<Required<NVM500JSON>> {\n\tconst io = new NVMMemoryIO(buffer);\n\tconst nvm = new NVM500(io);\n\n\tconst info = await nvm.init();\n\tconst meta: NVM500Meta = {\n\t\tlibrary: info.library,\n\t\t...pick(info.nvmDescriptor, [\n\t\t\t\"manufacturerID\",\n\t\t\t\"firmwareID\",\n\t\t\t\"productType\",\n\t\t\t\"productID\",\n\t\t]),\n\t};\n\n\tconst adapter = new NVM500Adapter(nvm);\n\n\t// Read all flags for all nodes\n\tconst appRouteLock = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"appRouteLock\",\n\t\t}, true),\n\t);\n\tconst routeSlaveSUC = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"routeSlaveSUC\",\n\t\t}, true),\n\t);\n\tconst sucPendingUpdate = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"sucPendingUpdate\",\n\t\t}, true),\n\t);\n\tconst virtualNodeIds = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"virtualNodeIds\",\n\t\t}) ?? [],\n\t);\n\tconst pendingDiscovery = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"pendingDiscovery\",\n\t\t}, true),\n\t);\n\n\t// Figure out which nodes exist along with their info\n\tconst nodes: Record<number, NVM500JSONNode> = {};\n\tfor (let nodeId = 1; nodeId <= MAX_NODES; nodeId++) {\n\t\tconst nodeInfo = await adapter.get({\n\t\t\tdomain: \"node\",\n\t\t\tnodeId,\n\t\t\ttype: \"info\",\n\t\t});\n\t\tconst isVirtual = virtualNodeIds.has(nodeId);\n\t\tif (!nodeInfo) {\n\t\t\tif (isVirtual) {\n\t\t\t\tnodes[nodeId] = { isVirtual: true };\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst routes = await adapter.get({\n\t\t\tdomain: \"node\",\n\t\t\tnodeId,\n\t\t\ttype: \"routes\",\n\t\t});\n\n\t\t// @ts-expect-error Some fields include a nodeId, but we don't need it\n\t\tdelete nodeInfo.nodeId;\n\n\t\tnodes[nodeId] = {\n\t\t\t...nodeInfo,\n\t\t\tspecificDeviceClass: nodeInfo.specificDeviceClass ?? null,\n\t\t\tisVirtual,\n\n\t\t\tappRouteLock: appRouteLock.has(nodeId),\n\t\t\trouteSlaveSUC: routeSlaveSUC.has(nodeId),\n\t\t\tsucPendingUpdate: sucPendingUpdate.has(nodeId),\n\t\t\tpendingDiscovery: pendingDiscovery.has(nodeId),\n\n\t\t\tlwr: routes?.lwr ?? null,\n\t\t\tnlwr: routes?.nlwr ?? null,\n\t\t};\n\t}\n\n\t// Read info about the controller\n\tconst ownNodeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"nodeId\",\n\t}, true);\n\n\tconst ownHomeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"homeId\",\n\t}, true);\n\n\tlet learnedHomeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"learnedHomeId\",\n\t});\n\tif (learnedHomeId?.length === 4 && learnedHomeId.every((b) => b === 0)) {\n\t\tlearnedHomeId = undefined;\n\t}\n\n\tconst lastNodeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"lastNodeId\",\n\t}, true);\n\n\tconst maxNodeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"maxNodeId\",\n\t}, true);\n\n\tconst reservedId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"reservedId\",\n\t}, true);\n\n\tconst staticControllerNodeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"staticControllerNodeId\",\n\t}, true);\n\n\tconst sucLastIndex = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"sucLastIndex\",\n\t}, true);\n\n\tconst controllerConfiguration = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"controllerConfiguration\",\n\t}, true);\n\n\tconst commandClasses = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"commandClasses\",\n\t}, true);\n\n\tconst sucUpdateEntries = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"sucUpdateEntries\",\n\t}, true);\n\n\tconst applicationData = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationData\",\n\t});\n\n\tconst preferredRepeaters = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"preferredRepeaters\",\n\t}, true);\n\n\tconst systemState = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"systemState\",\n\t});\n\n\tconst watchdogStarted = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"watchdogStarted\",\n\t}, true);\n\n\tconst powerLevelNormal = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerLevelNormal\",\n\t});\n\tconst powerLevelLow = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerLevelLow\",\n\t});\n\tconst powerMode = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerMode\",\n\t});\n\tconst powerModeExtintEnable = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerModeExtintEnable\",\n\t});\n\tconst powerModeWutTimeout = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerModeWutTimeout\",\n\t});\n\n\tconst controller: NVM500JSONController = {\n\t\tprotocolVersion: info.nvmDescriptor.protocolVersion,\n\t\tapplicationVersion: info.nvmDescriptor.firmwareVersion,\n\t\townHomeId: buffer2hex(ownHomeId),\n\t\tlearnedHomeId: learnedHomeId\n\t\t\t? buffer2hex(learnedHomeId)\n\t\t\t: null,\n\t\tnodeId: ownNodeId,\n\t\tlastNodeId,\n\t\tstaticControllerNodeId,\n\t\tsucLastIndex,\n\t\tcontrollerConfiguration,\n\t\tsucUpdateEntries,\n\t\tmaxNodeId,\n\t\treservedId,\n\t\tsystemState,\n\t\twatchdogStarted,\n\t\trfConfig: {\n\t\t\tpowerLevelNormal,\n\t\t\tpowerLevelLow,\n\t\t\tpowerMode,\n\t\t\tpowerModeExtintEnable,\n\t\t\tpowerModeWutTimeout,\n\t\t},\n\t\tpreferredRepeaters,\n\t\tcommandClasses,\n\t\tapplicationData:\n\t\t\t(applicationData && Bytes.view(applicationData).toString(\"hex\"))\n\t\t\t\t?? null,\n\t};\n\n\treturn {\n\t\tformat: 500,\n\t\tmeta,\n\t\tcontroller,\n\t\tnodes,\n\t};\n}\n\nexport async function jsonToNVM(\n\tjson: NVMJSON,\n\ttargetSDKVersion: string,\n): Promise<Uint8Array> {\n\tconst parsedVersion = semverParse(targetSDKVersion);\n\tif (!parsedVersion) {\n\t\tthrow new ZWaveError(\n\t\t\t`Invalid SDK version: ${targetSDKVersion}`,\n\t\t\tZWaveErrorCodes.Argument_Invalid,\n\t\t);\n\t}\n\n\t// Erase the NVM\n\tconst sharedFileSystem = json.meta?.sharedFileSystem;\n\tconst nvmSize = sharedFileSystem\n\t\t? ZWAVE_SHARED_NVM_SIZE\n\t\t: (ZWAVE_APPLICATION_NVM_SIZE + ZWAVE_PROTOCOL_NVM_SIZE);\n\tconst ret = new Uint8Array(nvmSize);\n\tconst io = new NVMMemoryIO(ret);\n\tconst nvm3 = new NVM3(io);\n\tawait nvm3.erase(json.meta);\n\n\tconst serializeFile = async (file: NVMFile) => {\n\t\tconst { key, data } = file.serialize();\n\t\tawait nvm3.set(key, data);\n\t};\n\n\t// Figure out which SDK version we are targeting\n\tlet targetApplicationVersion: SemVer;\n\tlet targetProtocolVersion: SemVer;\n\tlet targetProtocolFormat: number;\n\n\t// We currently support application version migrations up to:\n\tconst HIGHEST_SUPPORTED_SDK_VERSION = \"7.21.0\";\n\t// For all higher ones, set the highest version we support and let the controller handle the migration itself\n\tif (semverLte(targetSDKVersion, HIGHEST_SUPPORTED_SDK_VERSION)) {\n\t\ttargetApplicationVersion = semverParse(targetSDKVersion)!;\n\t} else {\n\t\ttargetApplicationVersion = semverParse(HIGHEST_SUPPORTED_SDK_VERSION)!;\n\t}\n\n\t// The protocol version file only seems to be updated when the format of the protocol file system changes\n\t// Once again, we simply set the highest version we support here and let the controller handle any potential migration\n\tif (semverGte(targetSDKVersion, \"7.19.0\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.19.0\")!;\n\t\ttargetProtocolFormat = 5;\n\t} else if (semverGte(targetSDKVersion, \"7.17.0\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.17.0\")!;\n\t\ttargetProtocolFormat = 4;\n\t} else if (semverGte(targetSDKVersion, \"7.15.3\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.15.3\")!;\n\t\ttargetProtocolFormat = 3;\n\t} else if (semverGte(targetSDKVersion, \"7.12.0\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.12.0\")!;\n\t\ttargetProtocolFormat = 2;\n\t} else if (semverGte(targetSDKVersion, \"7.11.0\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.11.0\")!;\n\t\ttargetProtocolFormat = 1;\n\t} else {\n\t\ttargetProtocolVersion = semverParse(\"7.0.0\")!;\n\t\ttargetProtocolFormat = 0;\n\t}\n\n\tconst target = cloneDeep(json);\n\ttarget.controller.protocolVersion = targetProtocolVersion.format();\n\ttarget.format = targetProtocolFormat;\n\ttarget.controller.applicationVersion = parsedVersion.format();\n\n\t// Write application and protocol version files, because they are required\n\t// for the NVM3 adapter to work.\n\tconst ApplicationVersionConstructor = sharedFileSystem\n\t\t? ApplicationVersionFile800\n\t\t: ApplicationVersionFile;\n\tconst applVersionFile = new ApplicationVersionConstructor({\n\t\tformat: 0,\n\t\tmajor: targetApplicationVersion.major,\n\t\tminor: targetApplicationVersion.minor,\n\t\tpatch: targetApplicationVersion.patch,\n\t\tfileVersion: targetProtocolVersion.format(), // does not matter for this file\n\t});\n\tawait serializeFile(applVersionFile);\n\n\tconst protocolVersionFile = new ProtocolVersionFile({\n\t\tformat: targetProtocolFormat,\n\t\tmajor: targetProtocolVersion.major,\n\t\tminor: targetProtocolVersion.minor,\n\t\tpatch: targetProtocolVersion.patch,\n\t\tfileVersion: targetProtocolVersion.format(), // does not matter for this file\n\t});\n\tawait serializeFile(protocolVersionFile);\n\t{\n\t\tconst { key, data } = protocolVersionFile.serialize();\n\t\tawait nvm3.set(key, data);\n\t}\n\n\t// Now use the adapter where possible. Some properties have to be set together though,\n\t// so we set the files directly\n\tconst adapter = new NVM3Adapter(nvm3);\n\n\t// Start with the application data\n\n\tconst applTypeFile = new ApplicationTypeFile({\n\t\t...pick(target.controller, [\n\t\t\t\"isListening\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t]),\n\t\tfileVersion: target.controller.applicationVersion,\n\t});\n\tadapter.setFile(applTypeFile);\n\n\tconst applCCsFile = new ApplicationCCsFile({\n\t\t...pick(target.controller.commandClasses, [\n\t\t\t\"includedInsecurely\",\n\t\t\t\"includedSecurelyInsecureCCs\",\n\t\t\t\"includedSecurelySecureCCs\",\n\t\t]),\n\t\tfileVersion: target.controller.applicationVersion,\n\t});\n\tadapter.setFile(applCCsFile);\n\n\t// When converting it can be that the rfConfig doesn't exist. Make sure\n\t// that it is initialized with proper defaults.\n\ttarget.controller.rfConfig ??= {\n\t\trfRegion: RFRegion[\"Default (EU)\"],\n\t\ttxPower: 0.0,\n\t\tmeasured0dBm: +3.3,\n\t\tenablePTI: null,\n\t\tmaxTXPower: null,\n\t\tnodeIdType: null,\n\t};\n\n\t// Make sure the RF config format matches the application version.\n\t// Otherwise, the controller will ignore the file and not accept any changes to the RF config\n\tif (semverGte(targetSDKVersion, \"7.15.3\")) {\n\t\ttarget.controller.rfConfig.enablePTI ??= 0;\n\t\ttarget.controller.rfConfig.maxTXPower ??= 14.0;\n\t}\n\tif (semverGte(targetSDKVersion, \"7.21.0\")) {\n\t\ttarget.controller.rfConfig.nodeIdType ??= NodeIDType.Short;\n\t}\n\n\tconst applRFConfigFile = new ApplicationRFConfigFile({\n\t\t...pick(target.controller.rfConfig, [\n\t\t\t\"rfRegion\",\n\t\t\t\"txPower\",\n\t\t\t\"measured0dBm\",\n\t\t]),\n\t\tenablePTI: target.controller.rfConfig.enablePTI ?? undefined,\n\t\tmaxTXPower: target.controller.rfConfig.maxTXPower ?? undefined,\n\t\tnodeIdType: target.controller.rfConfig.nodeIdType ?? undefined,\n\t\tfileVersion: target.controller.applicationVersion,\n\t});\n\tadapter.setFile(applRFConfigFile);\n\n\tif (target.controller.applicationData) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"applicationData\" },\n\t\t\tBytes.from(target.controller.applicationData, \"hex\"),\n\t\t);\n\t}\n\n\t// The application name only seems to be used on 800 series with the shared file system\n\tif (target.controller.applicationName && target.meta?.sharedFileSystem) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"applicationName\" },\n\t\t\ttarget.controller.applicationName,\n\t\t);\n\t}\n\n\t// Now the protocol data\n\n\t// TODO: node IDs and LR node IDs should probably be handled by the NVM adapter when\n\t// setting the node info. But then we need to make sure here that the files are guaranteed to exist\n\tconst nodeInfoExists = new Set<number>();\n\tconst lrNodeInfoExists = new Set<number>();\n\tconst virtualNodeIds = new Set<number>();\n\n\tconst appRouteLock = new Set<number>();\n\tconst routeSlaveSUC = new Set<number>();\n\tconst sucPendingUpdate = new Set<number>();\n\tconst pendingDiscovery = new Set<number>();\n\n\t// Ensure that the route cache exists nodemask is written, even when no routes exist\n\tadapter.setFile(\n\t\tnew ProtocolRouteCacheExistsNodeMaskFile({\n\t\t\tnodeIds: [],\n\t\t\tfileVersion: target.controller.protocolVersion,\n\t\t}),\n\t);\n\n\tfor (const [id, node] of Object.entries(target.nodes)) {\n\t\tconst nodeId = parseInt(id);\n\t\tif (!nodeHasInfo(node)) {\n\t\t\tvirtualNodeIds.add(nodeId);\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tnodeInfoExists.add(nodeId);\n\t\t\tif (node.isVirtual) virtualNodeIds.add(nodeId);\n\t\t\tif (node.appRouteLock) appRouteLock.add(nodeId);\n\t\t\tif (node.routeSlaveSUC) routeSlaveSUC.add(nodeId);\n\t\t\tif (node.sucPendingUpdate) sucPendingUpdate.add(nodeId);\n\t\t\tif (node.pendingDiscovery) pendingDiscovery.add(nodeId);\n\t\t}\n\n\t\tawait adapter.set(\n\t\t\t{ domain: \"node\", nodeId, type: \"info\" },\n\t\t\tnvmJSONNodeToNodeInfo(nodeId, node),\n\t\t);\n\n\t\tif (node.lwr || node.nlwr) {\n\t\t\tawait adapter.set(\n\t\t\t\t{ domain: \"node\", nodeId, type: \"routes\" },\n\t\t\t\t{\n\t\t\t\t\tlwr: node.lwr ?? getEmptyRoute(),\n\t\t\t\t\tnlwr: node.nlwr ?? getEmptyRoute(),\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"nodeIds\" },\n\t\t[...nodeInfoExists],\n\t);\n\n\tif (target.lrNodes) {\n\t\tfor (const [id, node] of Object.entries(target.lrNodes)) {\n\t\t\tconst nodeId = parseInt(id);\n\t\t\tlrNodeInfoExists.add(nodeId);\n\n\t\t\tawait adapter.set(\n\t\t\t\t{ domain: \"lrnode\", nodeId, type: \"info\" },\n\t\t\t\tnvmJSONLRNodeToLRNodeInfo(nodeId, node),\n\t\t\t);\n\t\t}\n\t}\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"lrNodeIds\" },\n\t\t[...lrNodeInfoExists],\n\t);\n\n\t// For v3+ targets, the ControllerInfoFile must contain the LongRange properties\n\t// or the controller will ignore the file and not have a home ID\n\tif (targetProtocolFormat >= 3) {\n\t\ttarget.controller.lastNodeIdLR ??= 255;\n\t\ttarget.controller.maxNodeIdLR ??= 0;\n\t\ttarget.controller.reservedIdLR ??= 0;\n\t\ttarget.controller.primaryLongRangeChannelId ??= 0;\n\t\ttarget.controller.dcdcConfig ??= 255;\n\t}\n\tadapter.setFile(\n\t\tnew ControllerInfoFile(\n\t\t\tnvmJSONControllerToFileOptions(target.controller),\n\t\t),\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"appRouteLock\" },\n\t\t[...appRouteLock],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"routeSlaveSUC\" },\n\t\t[...routeSlaveSUC],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucPendingUpdate\" },\n\t\t[...sucPendingUpdate],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"virtualNodeIds\" },\n\t\t[...virtualNodeIds],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"pendingDiscovery\" },\n\t\t[...pendingDiscovery],\n\t);\n\n\tif (target.controller.preferredRepeaters?.length) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"preferredRepeaters\" },\n\t\t\ttarget.controller.preferredRepeaters,\n\t\t);\n\t}\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucUpdateEntries\" },\n\t\ttarget.controller.sucUpdateEntries,\n\t);\n\n\tawait adapter.commit();\n\tawait io.close();\n\treturn ret;\n}\n\n/** Takes a JSON represented 500 series NVM and converts it to binary */\nexport async function jsonToNVM500(\n\tjson: Required<NVM500JSON>,\n\tprotocolVersion: string,\n): Promise<Uint8Array> {\n\t// Try to find a matching implementation\n\tconst impl = nvm500Impls.find(\n\t\t(p) =>\n\t\t\tp.protocolVersions.includes(protocolVersion)\n\t\t\t&& p.name.toLowerCase().startsWith(json.meta.library),\n\t);\n\n\tif (!impl) {\n\t\tthrow new ZWaveError(\n\t\t\t`Did not find a matching implementation for protocol version ${protocolVersion} and library ${json.meta.library}. To convert 500-series NVMs, both the source and the target controller must be using Z-Wave SDK 6.61 or higher.`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t);\n\t}\n\n\tconst { layout, nvmSize } = resolveLayout(impl.layout);\n\n\t// Erase the NVM and set some basic information\n\tconst ret = new Uint8Array(nvmSize);\n\tconst io = new NVMMemoryIO(ret);\n\tconst nvm = new NVM500(io);\n\tawait nvm.erase({\n\t\tlayout,\n\t\tnvmSize,\n\t\tlibrary: impl.library,\n\t\tnvmDescriptor: {\n\t\t\t...pick(json.meta, [\n\t\t\t\t\"manufacturerID\",\n\t\t\t\t\"productType\",\n\t\t\t\t\"productID\",\n\t\t\t\t\"firmwareID\",\n\t\t\t]),\n\t\t\t// Override the protocol version with the specified one\n\t\t\tprotocolVersion,\n\t\t\tfirmwareVersion: json.controller.applicationVersion,\n\t\t},\n\t});\n\n\tconst adapter = new NVM500Adapter(nvm);\n\n\t// Set controller infos\n\tconst c = json.controller;\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"homeId\" },\n\t\tBytes.from(c.ownHomeId.replace(/^0x/, \"\"), \"hex\"),\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"learnedHomeId\" },\n\t\tc.learnedHomeId\n\t\t\t? Bytes.from(c.learnedHomeId.replace(/^0x/, \"\"), \"hex\")\n\t\t\t: undefined,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"nodeId\" },\n\t\tc.nodeId,\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"lastNodeId\" },\n\t\tc.lastNodeId,\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"maxNodeId\" },\n\t\tc.maxNodeId,\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"reservedId\" },\n\t\tc.reservedId,\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"staticControllerNodeId\" },\n\t\tc.staticControllerNodeId,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"controllerConfiguration\" },\n\t\tc.controllerConfiguration,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucUpdateEntries\" },\n\t\tc.sucUpdateEntries,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucLastIndex\" },\n\t\tc.sucLastIndex,\n\t);\n\n\tif (c.systemState != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"systemState\" },\n\t\t\tc.systemState,\n\t\t);\n\t}\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"watchdogStarted\" },\n\t\tc.watchdogStarted,\n\t);\n\n\tif (c.rfConfig.powerLevelNormal != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerLevelNormal\" },\n\t\t\tc.rfConfig.powerLevelNormal,\n\t\t);\n\t}\n\tif (c.rfConfig.powerLevelLow != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerLevelLow\" },\n\t\t\tc.rfConfig.powerLevelLow,\n\t\t);\n\t}\n\tif (c.rfConfig.powerMode != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerMode\" },\n\t\t\tc.rfConfig.powerMode,\n\t\t);\n\t}\n\tif (c.rfConfig.powerModeExtintEnable != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerModeExtintEnable\" },\n\t\t\tc.rfConfig.powerModeExtintEnable,\n\t\t);\n\t}\n\tif (c.rfConfig.powerModeWutTimeout != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerModeWutTimeout\" },\n\t\t\tc.rfConfig.powerModeWutTimeout,\n\t\t);\n\t}\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"preferredRepeaters\" },\n\t\tc.preferredRepeaters,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"commandClasses\" },\n\t\tc.commandClasses,\n\t);\n\n\tif (c.applicationData) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"applicationData\" },\n\t\t\tBytes.from(c.applicationData, \"hex\"),\n\t\t);\n\t}\n\n\t// Set node infos\n\tconst appRouteLock: number[] = [];\n\tconst routeSlaveSUC: number[] = [];\n\tconst pendingDiscovery: number[] = [];\n\tconst sucPendingUpdate: number[] = [];\n\tconst virtualNodeIds: number[] = [];\n\n\tfor (const [id, node] of Object.entries(json.nodes)) {\n\t\tconst nodeId = parseInt(id);\n\t\tif (!nodeHasInfo(node)) {\n\t\t\tvirtualNodeIds.push(nodeId);\n\t\t\tcontinue;\n\t\t}\n\t\tif (node.appRouteLock) appRouteLock.push(nodeId);\n\t\tif (node.routeSlaveSUC) routeSlaveSUC.push(nodeId);\n\t\tif (node.pendingDiscovery) pendingDiscovery.push(nodeId);\n\t\tif (node.sucPendingUpdate) sucPendingUpdate.push(nodeId);\n\n\t\tawait adapter.set(\n\t\t\t{ domain: \"node\", nodeId, type: \"info\" },\n\t\t\t{\n\t\t\t\tnodeId,\n\t\t\t\t...node,\n\t\t\t},\n\t\t);\n\n\t\tif (node.lwr || node.nlwr) {\n\t\t\tawait adapter.set(\n\t\t\t\t{ domain: \"node\", nodeId, type: \"routes\" },\n\t\t\t\t{\n\t\t\t\t\tlwr: node.lwr ?? undefined,\n\t\t\t\t\tnlwr: node.nlwr ?? undefined,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"appRouteLock\" },\n\t\t[...appRouteLock],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"routeSlaveSUC\" },\n\t\t[...routeSlaveSUC],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucPendingUpdate\" },\n\t\t[...sucPendingUpdate],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"virtualNodeIds\" },\n\t\t[...virtualNodeIds],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"pendingDiscovery\" },\n\t\t[...pendingDiscovery],\n\t);\n\n\tawait adapter.commit();\n\tawait io.close();\n\treturn ret;\n}\n\nexport function json500To700(\n\tjson: NVM500JSON,\n\ttruncateApplicationData?: boolean,\n): NVMJSON {\n\tconst source = cloneDeep(json);\n\n\t// On the 500 series, some properties are only defined for the nodes, so we pull it off the\n\t// controller's node entry\n\tlet controllerNode = source.nodes[\n\t\tsource.controller.nodeId || 1\n\t] as NVMJSONNodeWithInfo; // Little hack because TS doesn't type check the union type properly\n\tif (!nodeHasInfo(controllerNode)) {\n\t\t// No information available, use sensible defaults\n\t\tcontrollerNode = {\n\t\t\tisListening: true,\n\t\t\toptionalFunctionality: false,\n\t\t\t// Static PC Controller\n\t\t\tgenericDeviceClass: 0x02,\n\t\t\tspecificDeviceClass: 0x01,\n\t\t} as any;\n\t}\n\n\tlet applicationData: string | null = null;\n\tif (source.controller.applicationData) {\n\t\tlet raw = Bytes.from(source.controller.applicationData, \"hex\");\n\t\t// Find actual start and end of application data, ignoring zeroes\n\t\tlet start = 0;\n\t\twhile (start < raw.length && raw[start] === 0) {\n\t\t\tstart++;\n\t\t}\n\t\tlet end = raw.length - 1;\n\t\twhile (end > start && raw[end] === 0) {\n\t\t\tend--;\n\t\t}\n\t\traw = raw.subarray(start, end + 1);\n\t\tif (raw.length > 512) {\n\t\t\tif (!truncateApplicationData) {\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\"Invalid NVM JSON: Application data would be truncated! Set truncateApplicationData to true to allow this.\",\n\t\t\t\t\tZWaveErrorCodes.NVM_InvalidJSON,\n\t\t\t\t);\n\t\t\t}\n\t\t\traw = raw.subarray(0, 512);\n\t\t}\n\t\tapplicationData = raw.toString(\"hex\");\n\t}\n\n\t// https://github.com/zwave-js/zwave-js/issues/6055\n\t// On some controllers this byte can be 0xff (effectively not set)\n\tlet controllerConfiguration = source.controller.controllerConfiguration;\n\tif (source.controller.controllerConfiguration === 0xff) {\n\t\t// Default to SUC/Primary\n\t\tcontrollerConfiguration = ControllerCapabilityFlags.SISPresent\n\t\t\t| ControllerCapabilityFlags.WasRealPrimary\n\t\t\t| ControllerCapabilityFlags.SUC;\n\t}\n\n\tlet homeId: string;\n\tif (\n\t\t!!(\n\t\t\tcontrollerConfiguration & ControllerCapabilityFlags.OnOtherNetwork\n\t\t)\n\t\t&& source.controller.learnedHomeId\n\t\t&& source.controller.nodeId\n\t) {\n\t\t// The controller did not start the network itself. We only keep this if we have a home ID and node ID\n\t\thomeId = source.controller.learnedHomeId;\n\t} else {\n\t\t// The controller did start the network itself\n\t\thomeId = source.controller.ownHomeId;\n\t\tcontrollerConfiguration &= ~ControllerCapabilityFlags.OnOtherNetwork;\n\t\t// Reconstruct the node ID. If we don't know, 1 is a good default\n\t\tif (controllerConfiguration & ControllerCapabilityFlags.SUC) {\n\t\t\tsource.controller.nodeId = source.controller.staticControllerNodeId\n\t\t\t\t|| 1;\n\t\t} else {\n\t\t\tsource.controller.nodeId = 1;\n\t\t}\n\t}\n\n\t// https://github.com/zwave-js/zwave-js/issues/6055\n\t// Some controllers have invalid information for the IDs\n\tlet maxNodeId = source.controller.maxNodeId;\n\tif (maxNodeId === 0xff) maxNodeId = source.controller.lastNodeId;\n\tlet reservedId = source.controller.reservedId;\n\tif (reservedId === 0xff) reservedId = 0;\n\n\tconst ret: NVMJSON = {\n\t\t// Start out with format 0 (= protocol version 7.0.0), the jsonToNVM routines will do further conversion\n\t\tformat: 0,\n\t\tcontroller: {\n\t\t\t// This will contain the original 6.x protocol version, but the jsonToNVM routines will update it\n\t\t\tprotocolVersion: source.controller.protocolVersion,\n\t\t\tapplicationVersion: source.controller.applicationVersion,\n\t\t\thomeId,\n\t\t\tnodeId: source.controller.nodeId,\n\t\t\tlastNodeId: source.controller.lastNodeId,\n\t\t\tstaticControllerNodeId: source.controller.staticControllerNodeId,\n\t\t\tsucLastIndex: source.controller.sucLastIndex,\n\t\t\tcontrollerConfiguration,\n\t\t\tsucUpdateEntries: source.controller.sucUpdateEntries,\n\t\t\tmaxNodeId,\n\t\t\treservedId,\n\t\t\tsystemState: source.controller.systemState ?? 0,\n\t\t\tpreferredRepeaters: source.controller.preferredRepeaters,\n\n\t\t\t// RF config exists on both series but isn't compatible\n\n\t\t\tisListening: controllerNode.isListening,\n\t\t\toptionalFunctionality: controllerNode.optionalFunctionality,\n\t\t\tgenericDeviceClass: controllerNode.genericDeviceClass,\n\t\t\tspecificDeviceClass: controllerNode.specificDeviceClass ?? 0,\n\n\t\t\tcommandClasses: {\n\t\t\t\tincludedInsecurely: source.controller.commandClasses,\n\t\t\t\tincludedSecurelyInsecureCCs: [],\n\t\t\t\tincludedSecurelySecureCCs: [],\n\t\t\t},\n\n\t\t\tapplicationData,\n\t\t},\n\t\t// The node entries are actually compatible between the two JSON versions\n\t\t// but the types are structured differently\n\t\tnodes: source.nodes,\n\t};\n\treturn ret;\n}\n\nexport function json700To500(json: NVMJSON): NVM500JSON {\n\tconst source = cloneDeep(json);\n\n\tlet ownHomeId: string;\n\tlet learnedHomeId: string | null = null;\n\tlet nodeId: number;\n\tif (\n\t\tsource.controller.controllerConfiguration\n\t\t& ControllerCapabilityFlags.OnOtherNetwork\n\t) {\n\t\t// The controller did not start the network itself\n\t\townHomeId = learnedHomeId = source.controller.homeId;\n\t\tnodeId = source.controller.nodeId;\n\t} else {\n\t\t// The controller did start the network itself\n\t\townHomeId = source.controller.homeId;\n\t\t// 500 series controllers expect the node ID to be 0 when they are the primary\n\t\tnodeId = 0;\n\t}\n\n\tconst ret: NVM500JSON = {\n\t\tformat: 500,\n\t\tcontroller: {\n\t\t\t// This will contain the original 7.x protocol version, but the jsonToNVM routines will update it\n\t\t\tprotocolVersion: source.controller.protocolVersion,\n\t\t\tapplicationVersion: source.controller.applicationVersion,\n\t\t\t// The 700 series does not distinguish between own and learned home ID in NVM\n\t\t\t// We infer it from the controller configuration if we need it\n\t\t\townHomeId,\n\t\t\tlearnedHomeId,\n\t\t\tnodeId,\n\t\t\tlastNodeId: source.controller.lastNodeId,\n\t\t\tstaticControllerNodeId: source.controller.staticControllerNodeId,\n\t\t\tsucLastIndex: source.controller.sucLastIndex,\n\t\t\tcontrollerConfiguration: source.controller.controllerConfiguration,\n\t\t\tsucUpdateEntries: source.controller.sucUpdateEntries,\n\t\t\tmaxNodeId: source.controller.maxNodeId,\n\t\t\treservedId: source.controller.reservedId,\n\t\t\tsystemState: source.controller.systemState,\n\t\t\twatchdogStarted: 0,\n\t\t\tpreferredRepeaters: json.controller.preferredRepeaters ?? [],\n\n\t\t\t// RF config exists on both series but isn't compatible. So set the default,\n\t\t\t// it will be taken from the target NVM on restore.\n\t\t\trfConfig: {\n\t\t\t\tpowerLevelNormal: [255, 255, 255],\n\t\t\t\tpowerLevelLow: [255, 255, 255],\n\t\t\t\tpowerMode: 255,\n\t\t\t\tpowerModeExtintEnable: 255,\n\t\t\t\tpowerModeWutTimeout: 0xffffffff,\n\t\t\t},\n\n\t\t\tcommandClasses: source.controller.commandClasses.includedInsecurely,\n\n\t\t\tapplicationData: source.controller.applicationData,\n\t\t},\n\t\t// The node entries are actually compatible between the two JSON versions\n\t\t// just the types are structured differently\n\t\tnodes: source.nodes,\n\t};\n\treturn ret;\n}\n\n/** Converts the given source NVM into a format that is compatible with the given target NVM */\nexport async function migrateNVM(\n\tsourceNVM: Uint8Array,\n\ttargetNVM: Uint8Array,\n\toptions: MigrateNVMOptions = {},\n): Promise<Uint8Array> {\n\tlet source: ParsedNVM;\n\tlet target: ParsedNVM;\n\tlet sourceProtocolFileFormat: number | undefined;\n\tlet targetProtocolFileFormat: number | undefined;\n\n\ttry {\n\t\tsource = {\n\t\t\ttype: 700,\n\t\t\tjson: await nvmToJSON(sourceNVM),\n\t\t};\n\t\tsourceProtocolFileFormat = source.json.format;\n\t} catch (e) {\n\t\tif (isZWaveError(e) && e.code === ZWaveErrorCodes.NVM_InvalidFormat) {\n\t\t\t// This is not a 700 series NVM, maybe it is a 500 series one?\n\t\t\tsource = {\n\t\t\t\ttype: 500,\n\t\t\t\tjson: await nvm500ToJSON(sourceNVM),\n\t\t\t};\n\t\t} else if (\n\t\t\tisZWaveError(e)\n\t\t\t&& e.code === ZWaveErrorCodes.NVM_NotSupported\n\t\t\t&& isObject(e.context)\n\t\t\t&& typeof e.context.protocolFileFormat === \"number\"\n\t\t) {\n\t\t\t// This is a 700 series NVM, but the protocol version is not (yet) supported\n\t\t\tsource = { type: \"unknown\" };\n\t\t\tsourceProtocolFileFormat = e.context.protocolFileFormat;\n\t\t} else {\n\t\t\tsource = { type: \"unknown\" };\n\t\t}\n\t}\n\n\ttry {\n\t\ttarget = {\n\t\t\ttype: 700,\n\t\t\tjson: await nvmToJSON(targetNVM),\n\t\t};\n\t\ttargetProtocolFileFormat = target.json.format;\n\t} catch (e) {\n\t\tif (isZWaveError(e) && e.code === ZWaveErrorCodes.NVM_InvalidFormat) {\n\t\t\t// This is not a 700 series NVM, maybe it is a 500 series one?\n\t\t\ttarget = {\n\t\t\t\ttype: 500,\n\t\t\t\tjson: await nvm500ToJSON(targetNVM),\n\t\t\t};\n\t\t} else if (\n\t\t\tisZWaveError(e)\n\t\t\t&& e.code === ZWaveErrorCodes.NVM_NotSupported\n\t\t\t&& source.type === 700\n\t\t\t&& isObject(e.context)\n\t\t\t&& typeof e.context.protocolFileFormat === \"number\"\n\t\t) {\n\t\t\t// This is a 700 series NVM, but the protocol version is not (yet) supported\n\t\t\ttarget = { type: \"unknown\" };\n\t\t\ttargetProtocolFileFormat = e.context.protocolFileFormat;\n\t\t} else {\n\t\t\ttarget = { type: \"unknown\" };\n\t\t}\n\t}\n\n\tconst {\n\t\tpreserveApplicationData = true,\n\t\tpreserveNeighbors = true,\n\t\tpreserveRoutes = true,\n\t\tpreserveSUCUpdateEntries = true,\n\t} = options;\n\n\tconst preserveAll = preserveApplicationData\n\t\t&& preserveNeighbors\n\t\t&& preserveRoutes\n\t\t&& preserveSUCUpdateEntries;\n\n\t// Short circuit if...\n\tif (\n\t\ttarget.type === \"unknown\"\n\t\t&& targetProtocolFileFormat\n\t\t&& targetProtocolFileFormat > MAX_PROTOCOL_FILE_FORMAT\n\t\t&& sourceProtocolFileFormat\n\t\t&& sourceProtocolFileFormat <= targetProtocolFileFormat\n\t\t&& sourceNVM.length === targetNVM.length\n\t\t// ...everything should be preserved and...\n\t\t&& preserveAll\n\t) {\n\t\t// ...both the source and the target are 700 series, but at least the target uses an unsupported protocol version.\n\t\t// We can be sure however that the target can upgrade any 700 series NVM to its protocol version, as long as the\n\t\t// source protocol version is not higher than the target's\n\t\treturn sourceNVM;\n\t} else if (\n\t\tsource.type === 700\n\t\t&& target.type === 700\n\t\t// ...the source and target NVMs have the same size and structure\n\t\t&& sourceNVM.length === targetNVM.length\n\t\t&& source.json.meta.sharedFileSystem\n\t\t\t=== target.json.meta.sharedFileSystem\n\t\t// ...everything should be preserved,...\n\t\t&& preserveAll\n\t) {\n\t\t// ... the source and target protocol versions are compatible without conversion\n\t\tconst sourceProtocolVersion = source.json.controller.protocolVersion;\n\t\tconst targetProtocolVersion = target.json.controller.protocolVersion;\n\t\t// ... and the application version on the both is compatible with the respective protocol version\n\t\tconst sourceApplicationVersion =\n\t\t\tsource.json.controller.applicationVersion;\n\t\tconst targetApplicationVersion =\n\t\t\ttarget.json.controller.applicationVersion;\n\n\t\t// The 700 series firmware can automatically upgrade backups from a previous protocol version\n\t\t// Not sure when that ability was added. To be on the safe side, allow it for 7.16+ which definitely supports it.\n\t\tif (\n\t\t\tsemverGte(targetProtocolVersion, \"7.16.0\")\n\t\t\t&& semverGte(targetProtocolVersion, sourceProtocolVersion)\n\t\t\t// the application version is updated on every update, protocol version only when the format changes\n\t\t\t// so this is a good indicator if the NVMs are in a compatible state\n\t\t\t&& semverGte(targetApplicationVersion, targetProtocolVersion)\n\t\t\t&& semverGte(sourceApplicationVersion, sourceProtocolVersion)\n\t\t\t// avoid preserving broken 255.x versions which appear on some controllers\n\t\t\t&& semverLt(sourceApplicationVersion, \"255.0.0\")\n\t\t\t&& semverLt(targetApplicationVersion, \"255.0.0\")\n\t\t\t// and avoid restoring a backup with a shifted 800 series application version file\n\t\t\t&& (!hasShiftedAppVersion800File(source.json))\n\t\t) {\n\t\t\treturn sourceNVM;\n\t\t}\n\t} else if (source.type === \"unknown\" && target.type !== \"unknown\") {\n\t\t// ...only the source has an unsupported format, so we have to convert but can't\n\t\tthrow new ZWaveError(\n\t\t\t`The source NVM has an unsupported format, which cannot be restored on a ${target.type}-series NVM!`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t);\n\t} else if (source.type !== \"unknown\" && target.type === \"unknown\") {\n\t\t// ...only the target has an unsupported format, so we have to convert but can't\n\t\tthrow new ZWaveError(\n\t\t\t`The target NVM has an unsupported format, cannot restore ${source.type}-series NVM onto it!`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t);\n\t} else if (source.type === \"unknown\" && target.type === \"unknown\") {\n\t\t// ...both are an unsupported format, meaning pre-6.61 SDK, which we cannot convert\n\t\treturn sourceNVM;\n\t}\n\n\t// TypeScript doesn't understand multi-variable narrowings (yet)\n\tsource = source as Exclude<ParsedNVM, { type: \"unknown\" }>;\n\ttarget = target as Exclude<ParsedNVM, { type: \"unknown\" }>;\n\n\t// Some 700 series NVMs have a strange 255.x application version - fix that first\n\tif (\n\t\ttarget.type === 700\n\t\t&& semverGte(target.json.controller.applicationVersion, \"255.0.0\")\n\t) {\n\t\t// replace both with the protocol version\n\t\ttarget.json.controller.applicationVersion =\n\t\t\ttarget.json.controller.protocolVersion;\n\t}\n\n\t// In any case, preserve the application version of the target stick\n\tsource.json.controller.applicationVersion =\n\t\ttarget.json.controller.applicationVersion;\n\n\t// Remove information we do not want to preserve\n\tif (!preserveApplicationData) {\n\t\tsource.json.controller.applicationData = undefined;\n\t}\n\tif (!preserveNeighbors) {\n\t\tfor (const node of Object.values(source.json.nodes)) {\n\t\t\tif (!node.isVirtual) {\n\t\t\t\tnode.neighbors = [];\n\t\t\t}\n\t\t}\n\t}\n\tif (!preserveRoutes) {\n\t\tfor (const node of Object.values(source.json.nodes)) {\n\t\t\tif (!node.isVirtual) {\n\t\t\t\tnode.appRouteLock = false;\n\t\t\t\tnode.lwr = undefined;\n\t\t\t\tnode.nlwr = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (!preserveSUCUpdateEntries) {\n\t\tsource.json.controller.sucUpdateEntries = [];\n\t\tsource.json.controller.sucLastIndex = 0xff;\n\t\tfor (const node of Object.values(source.json.nodes)) {\n\t\t\tif (!node.isVirtual) {\n\t\t\t\tnode.sucUpdateIndex = 0xfe;\n\t\t\t\tnode.sucPendingUpdate = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (source.type === 500 && target.type === 500) {\n\t\t// Both are 500, so we just need to update the metadata to match the target\n\t\tconst json: Required<NVM500JSON> = {\n\t\t\t...source.json,\n\t\t\tmeta: target.json.meta,\n\t\t};\n\t\t// If the target is a 500 series stick, preserve the RF config\n\t\tjson.controller.rfConfig = target.json.controller.rfConfig;\n\t\treturn jsonToNVM500(json, target.json.controller.protocolVersion);\n\t} else if (source.type === 500 && target.type === 700) {\n\t\t// We need to upgrade the source to 700 series\n\t\tconst json: NVMJSONWithMeta = {\n\t\t\tlrNodes: {},\n\t\t\t...json500To700(source.json, true),\n\t\t\tmeta: target.json.meta,\n\t\t};\n\t\t// The target is a different series, try to preserve the RF config of the target stick\n\t\tjson.controller.rfConfig = target.json.controller.rfConfig;\n\t\t// 700 series distinguishes the NVM format by the application version\n\t\treturn jsonToNVM(json, target.json.controller.applicationVersion);\n\t} else if (source.type === 700 && target.type === 500) {\n\t\t// We need to downgrade the source to 500 series\n\t\tconst json: Required<NVM500JSON> = {\n\t\t\t...json700To500(source.json),\n\t\t\tmeta: target.json.meta,\n\t\t};\n\t\t// The target is a different series, try to preserve the RF config of the target stick\n\t\tjson.controller.rfConfig = target.json.controller.rfConfig;\n\t\treturn jsonToNVM500(json, target.json.controller.protocolVersion);\n\t} else {\n\t\t// Both are 700, so we just need to update the metadata to match the target\n\t\tconst json: NVMJSONWithMeta = {\n\t\t\t...(source.json as NVMJSONWithMeta),\n\t\t\tmeta: (target.json as NVMJSONWithMeta).meta,\n\t\t};\n\t\t// 700 series distinguishes the NVM format by the application version\n\t\treturn jsonToNVM(json, target.json.controller.applicationVersion);\n\t}\n}\n\n/**\n * Detects whether the app version file on a 800 series controller is shifted by 1 byte\n */\nfunction hasShiftedAppVersion800File(\n\tjson: NVMJSONWithMeta,\n): boolean {\n\t// We can only detect this on 800 series controllers with the shared FS\n\tif (!json.meta.sharedFileSystem) return false;\n\n\tconst protocolVersion = semverParse(json.controller.protocolVersion);\n\t// Invalid protocol version, cannot fix anything\n\tif (!protocolVersion) return false;\n\n\tconst applicationVersion = semverParse(json.controller.applicationVersion);\n\t// Invalid application version, cannot fix anything\n\tif (!applicationVersion) return false;\n\n\t// We consider the version shifted if:\n\t// - the app version format is the major protocol version\n\t// - the app version major is the minor protocol version +/- 3\n\n\tif (json.applicationFileFormat !== protocolVersion.major) return false;\n\tif (Math.abs(applicationVersion.major - protocolVersion.minor) > 3) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n\ttype CommandClasses,\n\tControllerCapabilityFlags,\n\tMAX_NODES,\n\tNodeIDType,\n\ttype NodeProtocolInfo,\n\tNodeType,\n\tRFRegion,\n\tstripUndefined,\n} from \"@zwave-js/core\";\nimport {\n\tZWaveError,\n\tZWaveErrorCodes,\n\tisZWaveError,\n} from \"@zwave-js/core/error\";\nimport {\n\tBytes,\n\ttype BytesView,\n\tbuffer2hex,\n\tcloneDeep,\n\tnum2hex,\n\tpick,\n} from \"@zwave-js/shared\";\nimport { isObject } from \"alcalzone-shared/typeguards\";\nimport type { SemVer } from \"semver\";\nimport semverGte from \"semver/functions/gte.js\";\nimport semverLt from \"semver/functions/lt.js\";\nimport semverLte from \"semver/functions/lte.js\";\nimport semverParse from \"semver/functions/parse.js\";\nimport { MAX_PROTOCOL_FILE_FORMAT, SUC_MAX_UPDATES } from \"./consts.js\";\nimport { NVM3, type NVM3Meta } from \"./lib/NVM3.js\";\nimport { NVM500 } from \"./lib/NVM500.js\";\nimport {\n\ttype Route,\n\ttype RouteCache,\n\tgetEmptyRoute,\n} from \"./lib/common/routeCache.js\";\nimport type { SUCUpdateEntry } from \"./lib/common/sucUpdateEntry.js\";\nimport { NVMMemoryIO } from \"./lib/io/NVMMemoryIO.js\";\nimport { NVM3Adapter } from \"./lib/nvm3/adapter.js\";\nimport {\n\tZWAVE_APPLICATION_NVM_SIZE,\n\tZWAVE_PROTOCOL_NVM_SIZE,\n\tZWAVE_SHARED_NVM_SIZE,\n} from \"./lib/nvm3/consts.js\";\nimport {\n\ttype ApplicationNameFile,\n\tApplicationNameFileID,\n} from \"./lib/nvm3/files/ApplicationNameFile.js\";\nimport {\n\tApplicationCCsFile,\n\tApplicationCCsFileID,\n\ttype ApplicationDataFile,\n\tApplicationDataFileID,\n\tApplicationRFConfigFile,\n\tApplicationRFConfigFileID,\n\tApplicationTypeFile,\n\tApplicationTypeFileID,\n\tApplicationVersionFile,\n\tApplicationVersionFile800,\n\tApplicationVersionFile800ID,\n\tApplicationVersionFileID,\n\tControllerInfoFile,\n\tControllerInfoFileID,\n\ttype ControllerInfoFileOptions,\n\ttype LRNodeInfo,\n\ttype LRNodeInfoFileV5,\n\tNVMFile,\n\ttype NodeInfo,\n\ttype NodeInfoFileV0,\n\ttype NodeInfoFileV1,\n\ttype ProtocolAppRouteLockNodeMaskFile,\n\tProtocolAppRouteLockNodeMaskFileID,\n\ttype ProtocolLRNodeListFile,\n\tProtocolLRNodeListFileID,\n\ttype ProtocolNodeListFile,\n\tProtocolNodeListFileID,\n\ttype ProtocolPendingDiscoveryNodeMaskFile,\n\tProtocolPendingDiscoveryNodeMaskFileID,\n\ttype ProtocolPreferredRepeatersFile,\n\tProtocolPreferredRepeatersFileID,\n\tProtocolRouteCacheExistsNodeMaskFile,\n\tProtocolRouteCacheExistsNodeMaskFileID,\n\ttype ProtocolRouteSlaveSUCNodeMaskFile,\n\tProtocolRouteSlaveSUCNodeMaskFileID,\n\ttype ProtocolSUCPendingUpdateNodeMaskFile,\n\tProtocolSUCPendingUpdateNodeMaskFileID,\n\tProtocolVersionFile,\n\tProtocolVersionFileID,\n\ttype ProtocolVirtualNodeMaskFile,\n\tProtocolVirtualNodeMaskFileID,\n\ttype RouteCacheFileV0,\n\ttype RouteCacheFileV1,\n\tSUCUpdateEntriesFileIDV0,\n\ttype SUCUpdateEntriesFileV0,\n\ttype SUCUpdateEntriesFileV5,\n\tSUC_UPDATES_PER_FILE_V5,\n\tnodeIdToLRNodeInfoFileIDV5,\n\tnodeIdToNodeInfoFileIDV0,\n\tnodeIdToNodeInfoFileIDV1,\n\tnodeIdToRouteCacheFileIDV0,\n\tnodeIdToRouteCacheFileIDV1,\n\tsucUpdateIndexToSUCUpdateEntriesFileIDV5,\n} from \"./lib/nvm3/files/index.js\";\nimport type { NVM3Object } from \"./lib/nvm3/object.js\";\nimport { dumpNVM, mapToObject } from \"./lib/nvm3/utils.js\";\nimport { NVM500Adapter } from \"./lib/nvm500/adapter.js\";\nimport { nvm500Impls } from \"./lib/nvm500/impls/index.js\";\nimport { resolveLayout } from \"./lib/nvm500/shared.js\";\nimport type {\n\tNVM500JSON,\n\tNVM500JSONController,\n\tNVM500JSONNode,\n\tNVM500Meta,\n} from \"./nvm500/NVMParser.js\";\n\nexport interface NVMJSON {\n\tformat: number; // protocol file format\n\tapplicationFileFormat?: number;\n\tmeta?: NVM3Meta;\n\tcontroller: NVMJSONController;\n\tnodes: Record<number, NVMJSONNode>;\n\tlrNodes?: Record<number, NVMJSONLRNode>;\n}\n\nexport type NVMJSONWithMeta = NVMJSON & { meta: NVM3Meta };\n\nexport interface NVMJSONController {\n\tprotocolVersion: string;\n\tapplicationVersion: string;\n\thomeId: string;\n\tnodeId: number;\n\tlastNodeId: number;\n\tstaticControllerNodeId: number;\n\tsucLastIndex: number;\n\tcontrollerConfiguration: number;\n\tsucUpdateEntries: SUCUpdateEntry[];\n\tsucAwarenessPushNeeded?: number | null;\n\tmaxNodeId: number;\n\treservedId: number;\n\tsystemState: number;\n\tlastNodeIdLR?: number | null;\n\tmaxNodeIdLR?: number | null;\n\treservedIdLR?: number | null;\n\tprimaryLongRangeChannelId?: number | null;\n\tdcdcConfig?: number | null;\n\trfConfig?: NVMJSONControllerRFConfig | null;\n\tpreferredRepeaters?: number[] | null;\n\n\tisListening: boolean;\n\toptionalFunctionality: boolean;\n\tgenericDeviceClass: number;\n\tspecificDeviceClass: number;\n\n\tcommandClasses: {\n\t\tincludedInsecurely: CommandClasses[];\n\t\tincludedSecurelyInsecureCCs: CommandClasses[];\n\t\tincludedSecurelySecureCCs: CommandClasses[];\n\t};\n\n\tapplicationData?: string | null;\n\tapplicationName?: string | null;\n}\n\nexport interface NVMJSONControllerRFConfig {\n\trfRegion: RFRegion;\n\ttxPower: number;\n\tmeasured0dBm: number;\n\tenablePTI: number | null;\n\tmaxTXPower: number | null;\n\tnodeIdType: NodeIDType | null;\n}\n\nexport interface NVMJSONNodeWithInfo\n\textends Omit<NodeProtocolInfo, \"hasSpecificDeviceClass\">\n{\n\tisVirtual: boolean;\n\n\tgenericDeviceClass: number;\n\tspecificDeviceClass: number | null;\n\tneighbors: number[];\n\tsucUpdateIndex: number;\n\n\tappRouteLock: boolean;\n\trouteSlaveSUC: boolean;\n\tsucPendingUpdate: boolean;\n\tpendingDiscovery: boolean;\n\n\tlwr?: Route | null;\n\tnlwr?: Route | null;\n}\n\n// Unlike NVMJSONNodeWithInfo this does not carry any node information\nexport interface NVMJSONVirtualNode {\n\tisVirtual: true;\n}\n\nexport interface NVMJSONLRNode\n\textends Omit<NodeProtocolInfo, \"hasSpecificDeviceClass\">\n{\n\tgenericDeviceClass: number;\n\tspecificDeviceClass?: number | null;\n}\n\nexport type NVMJSONNode = NVMJSONNodeWithInfo | NVMJSONVirtualNode;\n\ntype ParsedNVM =\n\t| {\n\t\ttype: 500;\n\t\tjson: Required<NVM500JSON>;\n\t}\n\t| {\n\t\ttype: 700;\n\t\tjson: NVMJSONWithMeta;\n\t}\n\t| {\n\t\ttype: \"unknown\";\n\t};\n\n/**\n * Options influencing how NVM contents should be migrated.\n * By default, all data will be preserved.\n */\nexport interface MigrateNVMOptions {\n\t/** Whether application data will be preserved */\n\tpreserveApplicationData?: boolean;\n\t/** Whether SUC update entries will be preserved */\n\tpreserveSUCUpdateEntries?: boolean;\n\t/** Whether LWR, NLWR and the priority route flag will be preserved */\n\tpreserveRoutes?: boolean;\n\t/** Whether the neighbor table will be preserved */\n\tpreserveNeighbors?: boolean;\n}\n\nexport function nodeHasInfo(node: NVMJSONNode): node is NVMJSONNodeWithInfo {\n\treturn !node.isVirtual || Object.keys(node).length > 1;\n}\n\nfunction createEmptyPhysicalNode(): NVMJSONNodeWithInfo {\n\treturn {\n\t\tisVirtual: false,\n\t\tisListening: false,\n\t\tisFrequentListening: false,\n\t\tisRouting: false,\n\t\tsupportedDataRates: [],\n\t\tprotocolVersion: 0,\n\t\toptionalFunctionality: false,\n\t\tnodeType: NodeType[\"End Node\"],\n\t\tsupportsSecurity: false,\n\t\tsupportsBeaming: false,\n\t\tgenericDeviceClass: 0,\n\t\tspecificDeviceClass: null,\n\t\tneighbors: [],\n\t\tsucUpdateIndex: 0,\n\t\tappRouteLock: false,\n\t\trouteSlaveSUC: false,\n\t\tsucPendingUpdate: false,\n\t\tpendingDiscovery: false,\n\t\tlwr: null,\n\t\tnlwr: null,\n\t};\n}\n\nfunction createEmptyLRNode(): NVMJSONLRNode {\n\treturn {\n\t\tisListening: false,\n\t\tisFrequentListening: false,\n\t\tisRouting: false,\n\t\tsupportedDataRates: [],\n\t\tprotocolVersion: 3,\n\t\toptionalFunctionality: false,\n\t\tnodeType: NodeType[\"End Node\"],\n\t\tsupportsSecurity: true,\n\t\tsupportsBeaming: false,\n\t\tgenericDeviceClass: 0,\n\t\tspecificDeviceClass: null,\n\t};\n}\n\n/** Converts a compressed set of NVM objects to a JSON representation */\nexport function nvmObjectsToJSON(\n\tobjects: ReadonlyMap<number, NVM3Object>,\n): NVMJSON {\n\tconst nodes = new Map<number, NVMJSONNode>();\n\tconst getNode = (id: number): NVMJSONNode => {\n\t\tif (!nodes.has(id)) nodes.set(id, createEmptyPhysicalNode());\n\t\treturn nodes.get(id)!;\n\t};\n\n\tconst lrNodes = new Map<number, NVMJSONLRNode>();\n\tconst getLRNode = (id: number): NVMJSONLRNode => {\n\t\tif (!lrNodes.has(id)) lrNodes.set(id, createEmptyLRNode());\n\t\treturn lrNodes.get(id)!;\n\t};\n\n\tconst getObject = (\n\t\tid: number | ((id: number) => boolean),\n\t): NVM3Object | undefined => {\n\t\tif (typeof id === \"number\") {\n\t\t\treturn objects.get(id);\n\t\t} else {\n\t\t\tfor (const [key, obj] of objects) {\n\t\t\t\tif (id(key)) return obj;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst getObjectOrThrow = (\n\t\tid: number | ((id: number) => boolean),\n\t): NVM3Object => {\n\t\tconst ret = getObject(id);\n\t\tif (ret) return ret;\n\t\tthrow new ZWaveError(\n\t\t\t`Object${\n\t\t\t\ttypeof id === \"number\" ? ` ${num2hex(id)} (${id})` : \"\"\n\t\t\t} not found!`,\n\t\t\tZWaveErrorCodes.NVM_ObjectNotFound,\n\t\t);\n\t};\n\n\tconst getFileOrThrow = <T extends NVMFile>(\n\t\tid: number | ((id: number) => boolean),\n\t\tfileVersion: string,\n\t): T => {\n\t\tconst obj = getObjectOrThrow(id);\n\t\treturn NVMFile.from(obj.key, obj.data!, fileVersion) as T;\n\t};\n\n\tconst getFile = <T extends NVMFile>(\n\t\tid: number | ((id: number) => boolean),\n\t\tfileVersion: string,\n\t): T | undefined => {\n\t\tconst obj = getObject(id);\n\t\tif (!obj || !obj.data) return undefined;\n\t\treturn NVMFile.from(obj.key, obj.data, fileVersion) as T;\n\t};\n\n\t// === Protocol NVM files ===\n\n\t// Figure out how to parse the individual files\n\tconst protocolVersionFile = getFileOrThrow<ProtocolVersionFile>(\n\t\tProtocolVersionFileID,\n\t\t\"7.0.0\", // We don't know the version here yet\n\t);\n\tconst protocolFileFormat = protocolVersionFile.format;\n\tconst protocolVersion =\n\t\t`${protocolVersionFile.major}.${protocolVersionFile.minor}.${protocolVersionFile.patch}`;\n\n\t// Bail early if the NVM uses a protocol file format that's newer than we support\n\tif (protocolFileFormat > MAX_PROTOCOL_FILE_FORMAT) {\n\t\tthrow new ZWaveError(\n\t\t\t`Unsupported protocol file format: ${protocolFileFormat}`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t\t{ protocolFileFormat },\n\t\t);\n\t}\n\n\t// Figure out which nodes exist\n\tconst nodeIds = getFileOrThrow<ProtocolNodeListFile>(\n\t\tProtocolNodeListFileID,\n\t\tprotocolVersion,\n\t).nodeIds;\n\n\t// Read all flags for all nodes\n\tconst appRouteLock = new Set(\n\t\tgetFileOrThrow<ProtocolAppRouteLockNodeMaskFile>(\n\t\t\tProtocolAppRouteLockNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst routeSlaveSUC = new Set(\n\t\tgetFileOrThrow<ProtocolRouteSlaveSUCNodeMaskFile>(\n\t\t\tProtocolRouteSlaveSUCNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst sucPendingUpdate = new Set(\n\t\tgetFileOrThrow<ProtocolSUCPendingUpdateNodeMaskFile>(\n\t\t\tProtocolSUCPendingUpdateNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst isVirtual = new Set(\n\t\tgetFileOrThrow<ProtocolVirtualNodeMaskFile>(\n\t\t\tProtocolVirtualNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst pendingDiscovery = new Set(\n\t\tgetFileOrThrow<ProtocolPendingDiscoveryNodeMaskFile>(\n\t\t\tProtocolPendingDiscoveryNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\tconst routeCacheExists = new Set(\n\t\tgetFileOrThrow<ProtocolRouteCacheExistsNodeMaskFile>(\n\t\t\tProtocolRouteCacheExistsNodeMaskFileID,\n\t\t\tprotocolVersion,\n\t\t).nodeIds,\n\t);\n\n\t// And create each node entry, including virtual ones\n\tfor (const id of nodeIds) {\n\t\tconst node = getNode(id) as NVMJSONNodeWithInfo;\n\n\t\tconst rememberOnlyVirtual = () => {\n\t\t\tnodes.set(id, {\n\t\t\t\tisVirtual: true,\n\t\t\t});\n\t\t};\n\n\t\t// Find node info\n\t\tlet nodeInfo: NodeInfo;\n\t\ttry {\n\t\t\tif (protocolFileFormat === 0) {\n\t\t\t\tconst fileId = nodeIdToNodeInfoFileIDV0(id);\n\t\t\t\tconst file = getFileOrThrow<NodeInfoFileV0>(\n\t\t\t\t\tfileId,\n\t\t\t\t\tprotocolVersion,\n\t\t\t\t);\n\t\t\t\tnodeInfo = file.nodeInfo;\n\t\t\t} else {\n\t\t\t\tconst fileId = nodeIdToNodeInfoFileIDV1(id);\n\t\t\t\tconst file = getFileOrThrow<NodeInfoFileV1>(\n\t\t\t\t\tfileId,\n\t\t\t\t\tprotocolVersion,\n\t\t\t\t);\n\t\t\t\tnodeInfo = file.nodeInfos.find((i) => i.nodeId === id)!;\n\t\t\t}\n\t\t} catch (e: any) {\n\t\t\tif (e.message.includes(\"Object not found\")) {\n\t\t\t\trememberOnlyVirtual();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\n\t\tObject.assign(node, nodeInfo);\n\n\t\t// Evaluate flags\n\t\tnode.isVirtual = isVirtual.has(id);\n\t\tnode.appRouteLock = appRouteLock.has(id);\n\t\tnode.routeSlaveSUC = routeSlaveSUC.has(id);\n\t\tnode.sucPendingUpdate = sucPendingUpdate.has(id);\n\t\tnode.pendingDiscovery = pendingDiscovery.has(id);\n\t\tif (routeCacheExists.has(id)) {\n\t\t\tlet routeCache: RouteCache | undefined;\n\t\t\tif (protocolFileFormat === 0) {\n\t\t\t\tconst fileId = nodeIdToRouteCacheFileIDV0(id);\n\t\t\t\tconst file = getFile<RouteCacheFileV0>(fileId, protocolVersion);\n\t\t\t\trouteCache = file?.routeCache;\n\t\t\t} else {\n\t\t\t\tconst fileId = nodeIdToRouteCacheFileIDV1(id);\n\t\t\t\tconst file = getFile<RouteCacheFileV1>(fileId, protocolVersion);\n\t\t\t\trouteCache = file?.routeCaches.find((i) => i.nodeId === id);\n\t\t\t}\n\t\t\tif (routeCache) {\n\t\t\t\tnode.lwr = routeCache.lwr;\n\t\t\t\tnode.nlwr = routeCache.nlwr;\n\t\t\t}\n\t\t}\n\n\t\t// @ts-expect-error Some fields include a nodeId, but we don't need it\n\t\tdelete node.nodeId;\n\t}\n\n\t// If they exist, read info about LR nodes\n\tconst lrNodeIds = getFile<ProtocolLRNodeListFile>(\n\t\tProtocolLRNodeListFileID,\n\t\tprotocolVersion,\n\t)?.nodeIds;\n\tif (lrNodeIds) {\n\t\tfor (const id of lrNodeIds) {\n\t\t\tconst node = getLRNode(id);\n\n\t\t\t// Find node info\n\t\t\tconst fileId = nodeIdToLRNodeInfoFileIDV5(id);\n\t\t\tconst file = getFileOrThrow<LRNodeInfoFileV5>(\n\t\t\t\tfileId,\n\t\t\t\tprotocolVersion,\n\t\t\t);\n\t\t\tconst { nodeId, ...nodeInfo } = file.nodeInfos.find((i) =>\n\t\t\t\ti.nodeId === id\n\t\t\t)!;\n\n\t\t\tObject.assign(node, nodeInfo);\n\t\t}\n\t}\n\n\t// Now read info about the controller\n\tconst controllerInfoFile = getFileOrThrow<ControllerInfoFile>(\n\t\tControllerInfoFileID,\n\t\tprotocolVersion,\n\t);\n\n\tlet sucUpdateEntries: SUCUpdateEntry[];\n\tif (protocolFileFormat < 5) {\n\t\tsucUpdateEntries = getFileOrThrow<SUCUpdateEntriesFileV0>(\n\t\t\tSUCUpdateEntriesFileIDV0,\n\t\t\tprotocolVersion,\n\t\t).updateEntries;\n\t} else {\n\t\t// V5 has split the entries into multiple files\n\t\tsucUpdateEntries = [];\n\t\tfor (\n\t\t\tlet index = 0;\n\t\t\tindex < SUC_MAX_UPDATES;\n\t\t\tindex += SUC_UPDATES_PER_FILE_V5\n\t\t) {\n\t\t\tconst file = getFile<SUCUpdateEntriesFileV5>(\n\t\t\t\tsucUpdateIndexToSUCUpdateEntriesFileIDV5(index),\n\t\t\t\tprotocolVersion,\n\t\t\t);\n\t\t\tif (!file) break;\n\t\t\tsucUpdateEntries.push(...file.updateEntries);\n\t\t}\n\t}\n\n\t// === Application NVM files ===\n\n\tconst applicationVersionFile700 = getFile<ApplicationVersionFile>(\n\t\tApplicationVersionFileID,\n\t\t\"7.0.0\", // We don't know the version here yet\n\t);\n\tconst applicationVersionFile800 = getFile<ApplicationVersionFile800>(\n\t\tApplicationVersionFile800ID,\n\t\t\"7.0.0\", // We don't know the version here yet\n\t);\n\tconst applicationVersionFile = applicationVersionFile700\n\t\t?? applicationVersionFile800;\n\tif (!applicationVersionFile) {\n\t\tthrow new ZWaveError(\n\t\t\t\"ApplicationVersionFile not found!\",\n\t\t\tZWaveErrorCodes.NVM_ObjectNotFound,\n\t\t);\n\t}\n\tconst applicationVersion =\n\t\t`${applicationVersionFile.major}.${applicationVersionFile.minor}.${applicationVersionFile.patch}`;\n\n\tconst rfConfigFile = getFile<ApplicationRFConfigFile>(\n\t\tApplicationRFConfigFileID,\n\t\tapplicationVersion,\n\t);\n\tconst applicationCCsFile = getFileOrThrow<ApplicationCCsFile>(\n\t\tApplicationCCsFileID,\n\t\tapplicationVersion,\n\t);\n\tconst applicationDataFile = getFile<ApplicationDataFile>(\n\t\tApplicationDataFileID,\n\t\tapplicationVersion,\n\t);\n\tconst applicationTypeFile = getFileOrThrow<ApplicationTypeFile>(\n\t\tApplicationTypeFileID,\n\t\tapplicationVersion,\n\t);\n\tconst applicationNameFile = getFile<ApplicationNameFile>(\n\t\tApplicationNameFileID,\n\t\tapplicationVersion,\n\t);\n\n\tconst preferredRepeaters = getFile<ProtocolPreferredRepeatersFile>(\n\t\tProtocolPreferredRepeatersFileID,\n\t\tapplicationVersion,\n\t)?.nodeIds;\n\n\tconst controllerProps = [\n\t\t\"nodeId\",\n\t\t\"lastNodeId\",\n\t\t\"staticControllerNodeId\",\n\t\t\"sucLastIndex\",\n\t\t\"controllerConfiguration\",\n\t\t\"sucAwarenessPushNeeded\",\n\t\t\"maxNodeId\",\n\t\t\"reservedId\",\n\t\t\"systemState\",\n\t\t\"lastNodeIdLR\",\n\t\t\"maxNodeIdLR\",\n\t\t\"reservedIdLR\",\n\t\t\"primaryLongRangeChannelId\",\n\t\t\"dcdcConfig\",\n\t] as const;\n\tconst controller: NVMJSONController = {\n\t\tprotocolVersion,\n\t\tapplicationVersion,\n\t\thomeId: buffer2hex(controllerInfoFile.homeId),\n\t\t...pick(controllerInfoFile, controllerProps),\n\t\t...pick(applicationTypeFile, [\n\t\t\t\"isListening\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t]),\n\t\tcommandClasses: pick(applicationCCsFile, [\n\t\t\t\"includedInsecurely\",\n\t\t\t\"includedSecurelyInsecureCCs\",\n\t\t\t\"includedSecurelySecureCCs\",\n\t\t]),\n\t\tpreferredRepeaters,\n\t\t...(rfConfigFile\n\t\t\t? {\n\t\t\t\trfConfig: {\n\t\t\t\t\trfRegion: rfConfigFile.rfRegion,\n\t\t\t\t\ttxPower: rfConfigFile.txPower,\n\t\t\t\t\tmeasured0dBm: rfConfigFile.measured0dBm,\n\t\t\t\t\tenablePTI: rfConfigFile.enablePTI ?? null,\n\t\t\t\t\tmaxTXPower: rfConfigFile.maxTXPower ?? null,\n\t\t\t\t\tnodeIdType: rfConfigFile.nodeIdType ?? null,\n\t\t\t\t},\n\t\t\t}\n\t\t\t: {}),\n\t\tsucUpdateEntries,\n\t\tapplicationData: applicationDataFile?.applicationData.toString(\"hex\")\n\t\t\t?? null,\n\t\tapplicationName: applicationNameFile?.name ?? null,\n\t};\n\n\t// Make sure all props are defined\n\tconst optionalControllerProps = [\n\t\t\"sucAwarenessPushNeeded\",\n\t\t\"lastNodeIdLR\",\n\t\t\"maxNodeIdLR\",\n\t\t\"reservedIdLR\",\n\t\t\"primaryLongRangeChannelId\",\n\t\t\"dcdcConfig\",\n\t\t\"rfConfig\",\n\t\t\"preferredRepeaters\",\n\t\t\"applicationData\",\n\t] as const;\n\tfor (const prop of optionalControllerProps) {\n\t\tif (controller[prop] === undefined) controller[prop] = null;\n\t}\n\n\tconst ret: NVMJSON = {\n\t\tformat: protocolFileFormat,\n\t\tcontroller,\n\t\tnodes: mapToObject(nodes),\n\t};\n\tif (lrNodes.size > 0) {\n\t\tret.lrNodes = mapToObject(lrNodes);\n\t}\n\n\treturn ret;\n}\n\nfunction nvmJSONNodeToNodeInfo(\n\tnodeId: number,\n\tnode: NVMJSONNodeWithInfo,\n): NodeInfo {\n\treturn {\n\t\tnodeId,\n\t\t...pick(node, [\n\t\t\t\"isListening\",\n\t\t\t\"isFrequentListening\",\n\t\t\t\"isRouting\",\n\t\t\t\"supportedDataRates\",\n\t\t\t\"protocolVersion\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"nodeType\",\n\t\t\t\"supportsSecurity\",\n\t\t\t\"supportsBeaming\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t\t\"neighbors\",\n\t\t\t\"sucUpdateIndex\",\n\t\t]),\n\t};\n}\n\nfunction nvmJSONLRNodeToLRNodeInfo(\n\tnodeId: number,\n\tnode: NVMJSONLRNode,\n): LRNodeInfo {\n\treturn {\n\t\tnodeId,\n\t\t...pick(node, [\n\t\t\t\"isListening\",\n\t\t\t\"isFrequentListening\",\n\t\t\t\"isRouting\",\n\t\t\t\"supportedDataRates\",\n\t\t\t\"protocolVersion\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"nodeType\",\n\t\t\t\"supportsSecurity\",\n\t\t\t\"supportsBeaming\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t]),\n\t};\n}\n\nfunction nvmJSONControllerToFileOptions(\n\tctrlr: NVMJSONController,\n): ControllerInfoFileOptions {\n\tconst ret = {\n\t\thomeId: Bytes.from(ctrlr.homeId.replace(/^0x/, \"\"), \"hex\"),\n\t\tnodeId: ctrlr.nodeId,\n\t\tlastNodeId: ctrlr.lastNodeId,\n\t\tstaticControllerNodeId: ctrlr.staticControllerNodeId,\n\t\tsucLastIndex: ctrlr.sucLastIndex,\n\t\tcontrollerConfiguration: ctrlr.controllerConfiguration,\n\t\tmaxNodeId: ctrlr.maxNodeId,\n\t\treservedId: ctrlr.reservedId,\n\t\tsystemState: ctrlr.systemState,\n\t} as unknown as ControllerInfoFileOptions;\n\tif (ctrlr.sucAwarenessPushNeeded != undefined) {\n\t\t// @ts-expect-error We're dealing with a conditional object here\n\t\t// TS doesn't like that.\n\t\tret.sucAwarenessPushNeeded = ctrlr.sucAwarenessPushNeeded;\n\t} else {\n\t\tObject.assign(\n\t\t\tret,\n\t\t\tstripUndefined(\n\t\t\t\tpick(ctrlr, [\n\t\t\t\t\t\"sucAwarenessPushNeeded\",\n\t\t\t\t\t\"lastNodeIdLR\",\n\t\t\t\t\t\"maxNodeIdLR\",\n\t\t\t\t\t\"reservedIdLR\",\n\t\t\t\t\t\"primaryLongRangeChannelId\",\n\t\t\t\t\t\"dcdcConfig\",\n\t\t\t\t]),\n\t\t\t),\n\t\t);\n\t}\n\treturn ret;\n}\n\n/** Reads an NVM buffer of a 700+ series stick and returns its JSON representation */\nexport async function nvmToJSON(\n\tbuffer: BytesView,\n\tdebugLogs: boolean = false,\n): Promise<NVMJSONWithMeta> {\n\tconst io = new NVMMemoryIO(buffer);\n\tconst nvm3 = new NVM3(io);\n\tconst info = await nvm3.init();\n\n\tconst adapter = new NVM3Adapter(nvm3);\n\n\tif (debugLogs) {\n\t\t// Dump all pages, all raw objects in each page, and each object in its final state\n\t\tawait dumpNVM(nvm3);\n\t}\n\n\tconst firstPageHeader = info.isSharedFileSystem\n\t\t? info.sections.all.pages[0]\n\t\t: info.sections.protocol.pages[0];\n\n\tconst meta: NVM3Meta = {\n\t\tsharedFileSystem: info.isSharedFileSystem,\n\t\t...pick(firstPageHeader, [\n\t\t\t\"pageSize\",\n\t\t\t\"writeSize\",\n\t\t\t\"memoryMapped\",\n\t\t\t\"deviceFamily\",\n\t\t]),\n\t};\n\n\tconst nodes = new Map<number, NVMJSONNode>();\n\tconst getNode = (id: number): NVMJSONNode => {\n\t\tif (!nodes.has(id)) nodes.set(id, createEmptyPhysicalNode());\n\t\treturn nodes.get(id)!;\n\t};\n\n\tconst lrNodes = new Map<number, NVMJSONLRNode>();\n\tconst getLRNode = (id: number): NVMJSONLRNode => {\n\t\tif (!lrNodes.has(id)) lrNodes.set(id, createEmptyLRNode());\n\t\treturn lrNodes.get(id)!;\n\t};\n\n\tlet protocolFileFormat: number;\n\tlet protocolVersion: string;\n\ttry {\n\t\tprotocolFileFormat = await adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"protocolFileFormat\",\n\t\t}, true);\n\t\tprotocolVersion = await adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"protocolVersion\",\n\t\t}, true);\n\t} catch (e) {\n\t\t// Firmwares based on SDK 7.23.0 and 7.23.1 do not write the protocol format/version to NVM,\n\t\t// so file 0x50000 is missing. Those are out in the wild, so we need to work around this.\n\t\t// There are a few heuristics we can use, assuming that Silabs doesn't break this again in a later version:\n\t\t// - SDK < 7.23.0 are not affected, also 7.23.2+ is fixed\n\t\tlet isSDK723 = true;\n\t\t// - The ApplicationRFConfigFile (0x68) exists and has 9 bytes\n\t\tisSDK723 &&= (await nvm3.get(ApplicationRFConfigFileID))?.length == 9;\n\t\t// - The ApplicationVersionFile800 (0x41000) exists\n\t\tisSDK723 &&= !!(await nvm3.get(ApplicationVersionFile800ID));\n\t\t// - The ProtocolLRNodeListFile (0x5000c) exists\n\t\tisSDK723 &&= !!(await nvm3.get(ProtocolLRNodeListFileID));\n\t\t// - The ControllerInfoFile (0x50004) exists and has 22 bytes\n\t\tisSDK723 &&= (await nvm3.get(ControllerInfoFileID))?.length == 22;\n\n\t\tif (isSDK723) {\n\t\t\t// Remember the expected format\n\t\t\tprotocolVersion = \"7.23.0\";\n\t\t\tprotocolFileFormat = 5;\n\t\t\t// And also mirror it back to the NVM adapter. We never save it to NVM,\n\t\t\t// so we can just set the file.\n\t\t\tadapter.setFile(\n\t\t\t\tnew ProtocolVersionFile({\n\t\t\t\t\tfileVersion: protocolVersion,\n\t\t\t\t\tformat: protocolFileFormat,\n\t\t\t\t\tmajor: 7,\n\t\t\t\t\tminor: 23,\n\t\t\t\t\tpatch: 0,\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// And we need to init the adapter again\n\t\t\tawait adapter[\"init\"]();\n\t\t} else {\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Bail early if the NVM uses a protocol file format that's newer than we support\n\tif (protocolFileFormat > MAX_PROTOCOL_FILE_FORMAT) {\n\t\tthrow new ZWaveError(\n\t\t\t`Unsupported protocol file format: ${protocolFileFormat}`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t\t{ protocolFileFormat },\n\t\t);\n\t}\n\n\t// Read all flags for all nodes\n\tconst appRouteLock = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"appRouteLock\",\n\t\t}, true),\n\t);\n\tconst routeSlaveSUC = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"routeSlaveSUC\",\n\t\t}, true),\n\t);\n\tconst sucPendingUpdate = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"sucPendingUpdate\",\n\t\t}, true),\n\t);\n\tconst virtualNodeIds = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"virtualNodeIds\",\n\t\t}, true),\n\t);\n\tconst pendingDiscovery = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"pendingDiscovery\",\n\t\t}, true),\n\t);\n\n\t// Figure out which nodes exist\n\tconst nodeIds = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"nodeIds\",\n\t}, true);\n\n\t// And create each node entry, including virtual ones\n\tfor (const id of nodeIds) {\n\t\tconst node = getNode(id) as NVMJSONNodeWithInfo;\n\n\t\t// Find node info\n\t\tconst nodeInfo = await adapter.get({\n\t\t\tdomain: \"node\",\n\t\t\tnodeId: id,\n\t\t\ttype: \"info\",\n\t\t}, true);\n\n\t\tObject.assign(node, nodeInfo);\n\n\t\t// Evaluate flags\n\t\tnode.isVirtual = virtualNodeIds.has(id);\n\t\tnode.appRouteLock = appRouteLock.has(id);\n\t\tnode.routeSlaveSUC = routeSlaveSUC.has(id);\n\t\tnode.sucPendingUpdate = sucPendingUpdate.has(id);\n\t\tnode.pendingDiscovery = pendingDiscovery.has(id);\n\n\t\tconst routes = await adapter.get({\n\t\t\tdomain: \"node\",\n\t\t\tnodeId: id,\n\t\t\ttype: \"routes\",\n\t\t});\n\t\tif (routes) {\n\t\t\tnode.lwr = routes.lwr;\n\t\t\tnode.nlwr = routes.nlwr;\n\t\t}\n\n\t\t// @ts-expect-error Some fields include a nodeId, but we don't need it\n\t\tdelete node.nodeId;\n\t}\n\n\t// If they exist, read info about LR nodes\n\tconst lrNodeIds = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"lrNodeIds\",\n\t});\n\tif (lrNodeIds) {\n\t\tfor (const id of lrNodeIds) {\n\t\t\tconst node = getLRNode(id);\n\n\t\t\t// Find node info\n\t\t\tconst nodeInfo = await adapter.get({\n\t\t\t\tdomain: \"lrnode\",\n\t\t\t\tnodeId: id,\n\t\t\t\ttype: \"info\",\n\t\t\t}, true);\n\n\t\t\tObject.assign(node, nodeInfo);\n\t\t}\n\t}\n\n\t// Read info about the controller\n\tconst sucUpdateEntries = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"sucUpdateEntries\",\n\t}, true);\n\n\tconst applicationVersion = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationVersion\",\n\t}, true);\n\n\tconst applicationFileFormat = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationFileFormat\",\n\t}, true);\n\n\tconst applicationData = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationData\",\n\t});\n\n\tconst applicationName = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationName\",\n\t});\n\n\tconst preferredRepeaters = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"preferredRepeaters\",\n\t});\n\n\t// The following are a bit awkward to read one by one, so we just take the files\n\tconst controllerInfoFile = await adapter.getFile<ControllerInfoFile>(\n\t\tControllerInfoFileID,\n\t\ttrue,\n\t);\n\tconst rfConfigFile = await adapter.getFile<ApplicationRFConfigFile>(\n\t\tApplicationRFConfigFileID,\n\t);\n\tconst applicationCCsFile = await adapter.getFile<ApplicationCCsFile>(\n\t\tApplicationCCsFileID,\n\t\ttrue,\n\t);\n\tconst applicationTypeFile = await adapter.getFile<ApplicationTypeFile>(\n\t\tApplicationTypeFileID,\n\t\ttrue,\n\t);\n\n\tconst controller: NVMJSONController = {\n\t\tprotocolVersion,\n\t\tapplicationVersion,\n\t\thomeId: buffer2hex(controllerInfoFile.homeId),\n\t\t...pick(controllerInfoFile, [\n\t\t\t\"nodeId\",\n\t\t\t\"lastNodeId\",\n\t\t\t\"staticControllerNodeId\",\n\t\t\t\"sucLastIndex\",\n\t\t\t\"controllerConfiguration\",\n\t\t\t\"sucAwarenessPushNeeded\",\n\t\t\t\"maxNodeId\",\n\t\t\t\"reservedId\",\n\t\t\t\"systemState\",\n\t\t\t\"lastNodeIdLR\",\n\t\t\t\"maxNodeIdLR\",\n\t\t\t\"reservedIdLR\",\n\t\t\t\"primaryLongRangeChannelId\",\n\t\t\t\"dcdcConfig\",\n\t\t]),\n\t\t...pick(applicationTypeFile, [\n\t\t\t\"isListening\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t]),\n\t\tcommandClasses: pick(applicationCCsFile, [\n\t\t\t\"includedInsecurely\",\n\t\t\t\"includedSecurelyInsecureCCs\",\n\t\t\t\"includedSecurelySecureCCs\",\n\t\t]),\n\t\tpreferredRepeaters,\n\t\t...(rfConfigFile\n\t\t\t? {\n\t\t\t\trfConfig: {\n\t\t\t\t\trfRegion: rfConfigFile.rfRegion,\n\t\t\t\t\ttxPower: rfConfigFile.txPower,\n\t\t\t\t\tmeasured0dBm: rfConfigFile.measured0dBm,\n\t\t\t\t\tenablePTI: rfConfigFile.enablePTI ?? null,\n\t\t\t\t\tmaxTXPower: rfConfigFile.maxTXPower ?? null,\n\t\t\t\t\tnodeIdType: rfConfigFile.nodeIdType ?? null,\n\t\t\t\t},\n\t\t\t}\n\t\t\t: {}),\n\t\tsucUpdateEntries,\n\t\tapplicationData:\n\t\t\t(applicationData && Bytes.view(applicationData).toString(\"hex\"))\n\t\t\t\t?? null,\n\t\tapplicationName: applicationName ?? null,\n\t};\n\n\t// Make sure all props are defined\n\tconst optionalControllerProps = [\n\t\t\"sucAwarenessPushNeeded\",\n\t\t\"lastNodeIdLR\",\n\t\t\"maxNodeIdLR\",\n\t\t\"reservedIdLR\",\n\t\t\"primaryLongRangeChannelId\",\n\t\t\"dcdcConfig\",\n\t\t\"rfConfig\",\n\t\t\"preferredRepeaters\",\n\t\t\"applicationData\",\n\t] as const;\n\tfor (const prop of optionalControllerProps) {\n\t\tif (controller[prop] === undefined) controller[prop] = null;\n\t}\n\n\tconst ret: NVMJSONWithMeta = {\n\t\tformat: protocolFileFormat,\n\t\tcontroller,\n\t\tnodes: mapToObject(nodes),\n\t\tmeta,\n\t};\n\tif (applicationFileFormat !== 0) {\n\t\tret.applicationFileFormat = applicationFileFormat;\n\t}\n\tif (lrNodes.size > 0) {\n\t\tret.lrNodes = mapToObject(lrNodes);\n\t}\n\treturn ret;\n}\n\n/** Reads an NVM buffer of a 500-series stick and returns its JSON representation */\nexport async function nvm500ToJSON(\n\tbuffer: BytesView,\n): Promise<Required<NVM500JSON>> {\n\tconst io = new NVMMemoryIO(buffer);\n\tconst nvm = new NVM500(io);\n\n\tconst info = await nvm.init();\n\tconst meta: NVM500Meta = {\n\t\tlibrary: info.library,\n\t\t...pick(info.nvmDescriptor, [\n\t\t\t\"manufacturerID\",\n\t\t\t\"firmwareID\",\n\t\t\t\"productType\",\n\t\t\t\"productID\",\n\t\t]),\n\t};\n\n\tconst adapter = new NVM500Adapter(nvm);\n\n\t// Read all flags for all nodes\n\tconst appRouteLock = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"appRouteLock\",\n\t\t}, true),\n\t);\n\tconst routeSlaveSUC = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"routeSlaveSUC\",\n\t\t}, true),\n\t);\n\tconst sucPendingUpdate = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"sucPendingUpdate\",\n\t\t}, true),\n\t);\n\tconst virtualNodeIds = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"virtualNodeIds\",\n\t\t}) ?? [],\n\t);\n\tconst pendingDiscovery = new Set(\n\t\tawait adapter.get({\n\t\t\tdomain: \"controller\",\n\t\t\ttype: \"pendingDiscovery\",\n\t\t}, true),\n\t);\n\n\t// Figure out which nodes exist along with their info\n\tconst nodes: Record<number, NVM500JSONNode> = {};\n\tfor (let nodeId = 1; nodeId <= MAX_NODES; nodeId++) {\n\t\tconst nodeInfo = await adapter.get({\n\t\t\tdomain: \"node\",\n\t\t\tnodeId,\n\t\t\ttype: \"info\",\n\t\t});\n\t\tconst isVirtual = virtualNodeIds.has(nodeId);\n\t\tif (!nodeInfo) {\n\t\t\tif (isVirtual) {\n\t\t\t\tnodes[nodeId] = { isVirtual: true };\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst routes = await adapter.get({\n\t\t\tdomain: \"node\",\n\t\t\tnodeId,\n\t\t\ttype: \"routes\",\n\t\t});\n\n\t\t// @ts-expect-error Some fields include a nodeId, but we don't need it\n\t\tdelete nodeInfo.nodeId;\n\n\t\tnodes[nodeId] = {\n\t\t\t...nodeInfo,\n\t\t\tspecificDeviceClass: nodeInfo.specificDeviceClass ?? null,\n\t\t\tisVirtual,\n\n\t\t\tappRouteLock: appRouteLock.has(nodeId),\n\t\t\trouteSlaveSUC: routeSlaveSUC.has(nodeId),\n\t\t\tsucPendingUpdate: sucPendingUpdate.has(nodeId),\n\t\t\tpendingDiscovery: pendingDiscovery.has(nodeId),\n\n\t\t\tlwr: routes?.lwr ?? null,\n\t\t\tnlwr: routes?.nlwr ?? null,\n\t\t};\n\t}\n\n\t// Read info about the controller\n\tconst ownNodeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"nodeId\",\n\t}, true);\n\n\tconst ownHomeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"homeId\",\n\t}, true);\n\n\tlet learnedHomeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"learnedHomeId\",\n\t});\n\tif (learnedHomeId?.length === 4 && learnedHomeId.every((b) => b === 0)) {\n\t\tlearnedHomeId = undefined;\n\t}\n\n\tconst lastNodeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"lastNodeId\",\n\t}, true);\n\n\tconst maxNodeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"maxNodeId\",\n\t}, true);\n\n\tconst reservedId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"reservedId\",\n\t}, true);\n\n\tconst staticControllerNodeId = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"staticControllerNodeId\",\n\t}, true);\n\n\tconst sucLastIndex = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"sucLastIndex\",\n\t}, true);\n\n\tconst controllerConfiguration = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"controllerConfiguration\",\n\t}, true);\n\n\tconst commandClasses = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"commandClasses\",\n\t}, true);\n\n\tconst sucUpdateEntries = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"sucUpdateEntries\",\n\t}, true);\n\n\tconst applicationData = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"applicationData\",\n\t});\n\n\tconst preferredRepeaters = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"preferredRepeaters\",\n\t}, true);\n\n\tconst systemState = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"systemState\",\n\t});\n\n\tconst watchdogStarted = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"watchdogStarted\",\n\t}, true);\n\n\tconst powerLevelNormal = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerLevelNormal\",\n\t});\n\tconst powerLevelLow = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerLevelLow\",\n\t});\n\tconst powerMode = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerMode\",\n\t});\n\tconst powerModeExtintEnable = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerModeExtintEnable\",\n\t});\n\tconst powerModeWutTimeout = await adapter.get({\n\t\tdomain: \"controller\",\n\t\ttype: \"powerModeWutTimeout\",\n\t});\n\n\tconst controller: NVM500JSONController = {\n\t\tprotocolVersion: info.nvmDescriptor.protocolVersion,\n\t\tapplicationVersion: info.nvmDescriptor.firmwareVersion,\n\t\townHomeId: buffer2hex(ownHomeId),\n\t\tlearnedHomeId: learnedHomeId\n\t\t\t? buffer2hex(learnedHomeId)\n\t\t\t: null,\n\t\tnodeId: ownNodeId,\n\t\tlastNodeId,\n\t\tstaticControllerNodeId,\n\t\tsucLastIndex,\n\t\tcontrollerConfiguration,\n\t\tsucUpdateEntries,\n\t\tmaxNodeId,\n\t\treservedId,\n\t\tsystemState,\n\t\twatchdogStarted,\n\t\trfConfig: {\n\t\t\tpowerLevelNormal,\n\t\t\tpowerLevelLow,\n\t\t\tpowerMode,\n\t\t\tpowerModeExtintEnable,\n\t\t\tpowerModeWutTimeout,\n\t\t},\n\t\tpreferredRepeaters,\n\t\tcommandClasses,\n\t\tapplicationData:\n\t\t\t(applicationData && Bytes.view(applicationData).toString(\"hex\"))\n\t\t\t\t?? null,\n\t};\n\n\treturn {\n\t\tformat: 500,\n\t\tmeta,\n\t\tcontroller,\n\t\tnodes,\n\t};\n}\n\nexport async function jsonToNVM(\n\tjson: NVMJSON,\n\ttargetSDKVersion: string,\n): Promise<BytesView> {\n\tconst parsedVersion = semverParse(targetSDKVersion);\n\tif (!parsedVersion) {\n\t\tthrow new ZWaveError(\n\t\t\t`Invalid SDK version: ${targetSDKVersion}`,\n\t\t\tZWaveErrorCodes.Argument_Invalid,\n\t\t);\n\t}\n\n\t// Erase the NVM\n\tconst sharedFileSystem = json.meta?.sharedFileSystem;\n\tconst nvmSize = sharedFileSystem\n\t\t? ZWAVE_SHARED_NVM_SIZE\n\t\t: (ZWAVE_APPLICATION_NVM_SIZE + ZWAVE_PROTOCOL_NVM_SIZE);\n\tconst ret = new Uint8Array(nvmSize);\n\tconst io = new NVMMemoryIO(ret);\n\tconst nvm3 = new NVM3(io);\n\tawait nvm3.erase(json.meta);\n\n\tconst serializeFile = async (file: NVMFile) => {\n\t\tconst { key, data } = file.serialize();\n\t\tawait nvm3.set(key, data);\n\t};\n\n\t// Figure out which SDK version we are targeting\n\tlet targetApplicationVersion: SemVer;\n\tlet targetProtocolVersion: SemVer;\n\tlet targetProtocolFormat: number;\n\n\t// We currently support application version migrations up to:\n\tconst HIGHEST_SUPPORTED_SDK_VERSION = \"7.21.0\";\n\t// For all higher ones, set the highest version we support and let the controller handle the migration itself\n\tif (semverLte(targetSDKVersion, HIGHEST_SUPPORTED_SDK_VERSION)) {\n\t\ttargetApplicationVersion = semverParse(targetSDKVersion)!;\n\t} else {\n\t\ttargetApplicationVersion = semverParse(HIGHEST_SUPPORTED_SDK_VERSION)!;\n\t}\n\n\t// The protocol version file only seems to be updated when the format of the protocol file system changes\n\t// Once again, we simply set the highest version we support here and let the controller handle any potential migration\n\tif (semverGte(targetSDKVersion, \"7.19.0\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.19.0\")!;\n\t\ttargetProtocolFormat = 5;\n\t} else if (semverGte(targetSDKVersion, \"7.17.0\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.17.0\")!;\n\t\ttargetProtocolFormat = 4;\n\t} else if (semverGte(targetSDKVersion, \"7.15.3\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.15.3\")!;\n\t\ttargetProtocolFormat = 3;\n\t} else if (semverGte(targetSDKVersion, \"7.12.0\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.12.0\")!;\n\t\ttargetProtocolFormat = 2;\n\t} else if (semverGte(targetSDKVersion, \"7.11.0\")) {\n\t\ttargetProtocolVersion = semverParse(\"7.11.0\")!;\n\t\ttargetProtocolFormat = 1;\n\t} else {\n\t\ttargetProtocolVersion = semverParse(\"7.0.0\")!;\n\t\ttargetProtocolFormat = 0;\n\t}\n\n\tconst target = cloneDeep(json);\n\ttarget.controller.protocolVersion = targetProtocolVersion.format();\n\ttarget.format = targetProtocolFormat;\n\ttarget.controller.applicationVersion = parsedVersion.format();\n\n\t// Write application and protocol version files, because they are required\n\t// for the NVM3 adapter to work.\n\tconst ApplicationVersionConstructor = sharedFileSystem\n\t\t? ApplicationVersionFile800\n\t\t: ApplicationVersionFile;\n\tconst applVersionFile = new ApplicationVersionConstructor({\n\t\tformat: 0,\n\t\tmajor: targetApplicationVersion.major,\n\t\tminor: targetApplicationVersion.minor,\n\t\tpatch: targetApplicationVersion.patch,\n\t\tfileVersion: targetProtocolVersion.format(), // does not matter for this file\n\t});\n\tawait serializeFile(applVersionFile);\n\n\tconst protocolVersionFile = new ProtocolVersionFile({\n\t\tformat: targetProtocolFormat,\n\t\tmajor: targetProtocolVersion.major,\n\t\tminor: targetProtocolVersion.minor,\n\t\tpatch: targetProtocolVersion.patch,\n\t\tfileVersion: targetProtocolVersion.format(), // does not matter for this file\n\t});\n\tawait serializeFile(protocolVersionFile);\n\t{\n\t\tconst { key, data } = protocolVersionFile.serialize();\n\t\tawait nvm3.set(key, data);\n\t}\n\n\t// Now use the adapter where possible. Some properties have to be set together though,\n\t// so we set the files directly\n\tconst adapter = new NVM3Adapter(nvm3);\n\n\t// Start with the application data\n\n\tconst applTypeFile = new ApplicationTypeFile({\n\t\t...pick(target.controller, [\n\t\t\t\"isListening\",\n\t\t\t\"optionalFunctionality\",\n\t\t\t\"genericDeviceClass\",\n\t\t\t\"specificDeviceClass\",\n\t\t]),\n\t\tfileVersion: target.controller.applicationVersion,\n\t});\n\tadapter.setFile(applTypeFile);\n\n\tconst applCCsFile = new ApplicationCCsFile({\n\t\t...pick(target.controller.commandClasses, [\n\t\t\t\"includedInsecurely\",\n\t\t\t\"includedSecurelyInsecureCCs\",\n\t\t\t\"includedSecurelySecureCCs\",\n\t\t]),\n\t\tfileVersion: target.controller.applicationVersion,\n\t});\n\tadapter.setFile(applCCsFile);\n\n\t// When converting it can be that the rfConfig doesn't exist. Make sure\n\t// that it is initialized with proper defaults.\n\ttarget.controller.rfConfig ??= {\n\t\trfRegion: RFRegion[\"Default (EU)\"],\n\t\ttxPower: 0.0,\n\t\tmeasured0dBm: +3.3,\n\t\tenablePTI: null,\n\t\tmaxTXPower: null,\n\t\tnodeIdType: null,\n\t};\n\n\t// Make sure the RF config format matches the application version.\n\t// Otherwise, the controller will ignore the file and not accept any changes to the RF config\n\tif (semverGte(targetSDKVersion, \"7.15.3\")) {\n\t\ttarget.controller.rfConfig.enablePTI ??= 0;\n\t\ttarget.controller.rfConfig.maxTXPower ??= 14.0;\n\t}\n\tif (semverGte(targetSDKVersion, \"7.21.0\")) {\n\t\ttarget.controller.rfConfig.nodeIdType ??= NodeIDType.Short;\n\t}\n\n\tconst applRFConfigFile = new ApplicationRFConfigFile({\n\t\t...pick(target.controller.rfConfig, [\n\t\t\t\"rfRegion\",\n\t\t\t\"txPower\",\n\t\t\t\"measured0dBm\",\n\t\t]),\n\t\tenablePTI: target.controller.rfConfig.enablePTI ?? undefined,\n\t\tmaxTXPower: target.controller.rfConfig.maxTXPower ?? undefined,\n\t\tnodeIdType: target.controller.rfConfig.nodeIdType ?? undefined,\n\t\tfileVersion: target.controller.applicationVersion,\n\t});\n\tadapter.setFile(applRFConfigFile);\n\n\tif (target.controller.applicationData) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"applicationData\" },\n\t\t\tBytes.from(target.controller.applicationData, \"hex\"),\n\t\t);\n\t}\n\n\t// The application name only seems to be used on 800 series with the shared file system\n\tif (target.controller.applicationName && target.meta?.sharedFileSystem) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"applicationName\" },\n\t\t\ttarget.controller.applicationName,\n\t\t);\n\t}\n\n\t// Now the protocol data\n\n\t// TODO: node IDs and LR node IDs should probably be handled by the NVM adapter when\n\t// setting the node info. But then we need to make sure here that the files are guaranteed to exist\n\tconst nodeInfoExists = new Set<number>();\n\tconst lrNodeInfoExists = new Set<number>();\n\tconst virtualNodeIds = new Set<number>();\n\n\tconst appRouteLock = new Set<number>();\n\tconst routeSlaveSUC = new Set<number>();\n\tconst sucPendingUpdate = new Set<number>();\n\tconst pendingDiscovery = new Set<number>();\n\n\t// Ensure that the route cache exists nodemask is written, even when no routes exist\n\tadapter.setFile(\n\t\tnew ProtocolRouteCacheExistsNodeMaskFile({\n\t\t\tnodeIds: [],\n\t\t\tfileVersion: target.controller.protocolVersion,\n\t\t}),\n\t);\n\n\tfor (const [id, node] of Object.entries(target.nodes)) {\n\t\tconst nodeId = parseInt(id);\n\t\tif (!nodeHasInfo(node)) {\n\t\t\tvirtualNodeIds.add(nodeId);\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tnodeInfoExists.add(nodeId);\n\t\t\tif (node.isVirtual) virtualNodeIds.add(nodeId);\n\t\t\tif (node.appRouteLock) appRouteLock.add(nodeId);\n\t\t\tif (node.routeSlaveSUC) routeSlaveSUC.add(nodeId);\n\t\t\tif (node.sucPendingUpdate) sucPendingUpdate.add(nodeId);\n\t\t\tif (node.pendingDiscovery) pendingDiscovery.add(nodeId);\n\t\t}\n\n\t\tawait adapter.set(\n\t\t\t{ domain: \"node\", nodeId, type: \"info\" },\n\t\t\tnvmJSONNodeToNodeInfo(nodeId, node),\n\t\t);\n\n\t\tif (node.lwr || node.nlwr) {\n\t\t\tawait adapter.set(\n\t\t\t\t{ domain: \"node\", nodeId, type: \"routes\" },\n\t\t\t\t{\n\t\t\t\t\tlwr: node.lwr ?? getEmptyRoute(),\n\t\t\t\t\tnlwr: node.nlwr ?? getEmptyRoute(),\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"nodeIds\" },\n\t\t[...nodeInfoExists],\n\t);\n\n\tif (target.lrNodes) {\n\t\tfor (const [id, node] of Object.entries(target.lrNodes)) {\n\t\t\tconst nodeId = parseInt(id);\n\t\t\tlrNodeInfoExists.add(nodeId);\n\n\t\t\tawait adapter.set(\n\t\t\t\t{ domain: \"lrnode\", nodeId, type: \"info\" },\n\t\t\t\tnvmJSONLRNodeToLRNodeInfo(nodeId, node),\n\t\t\t);\n\t\t}\n\t}\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"lrNodeIds\" },\n\t\t[...lrNodeInfoExists],\n\t);\n\n\t// For v3+ targets, the ControllerInfoFile must contain the LongRange properties\n\t// or the controller will ignore the file and not have a home ID\n\tif (targetProtocolFormat >= 3) {\n\t\ttarget.controller.lastNodeIdLR ??= 255;\n\t\ttarget.controller.maxNodeIdLR ??= 0;\n\t\ttarget.controller.reservedIdLR ??= 0;\n\t\ttarget.controller.primaryLongRangeChannelId ??= 0;\n\t\ttarget.controller.dcdcConfig ??= 255;\n\t}\n\tadapter.setFile(\n\t\tnew ControllerInfoFile(\n\t\t\tnvmJSONControllerToFileOptions(target.controller),\n\t\t),\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"appRouteLock\" },\n\t\t[...appRouteLock],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"routeSlaveSUC\" },\n\t\t[...routeSlaveSUC],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucPendingUpdate\" },\n\t\t[...sucPendingUpdate],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"virtualNodeIds\" },\n\t\t[...virtualNodeIds],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"pendingDiscovery\" },\n\t\t[...pendingDiscovery],\n\t);\n\n\tif (target.controller.preferredRepeaters?.length) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"preferredRepeaters\" },\n\t\t\ttarget.controller.preferredRepeaters,\n\t\t);\n\t}\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucUpdateEntries\" },\n\t\ttarget.controller.sucUpdateEntries,\n\t);\n\n\tawait adapter.commit();\n\tawait io.close();\n\treturn ret;\n}\n\n/** Takes a JSON represented 500 series NVM and converts it to binary */\nexport async function jsonToNVM500(\n\tjson: Required<NVM500JSON>,\n\tprotocolVersion: string,\n): Promise<BytesView> {\n\t// Try to find a matching implementation\n\tconst impl = nvm500Impls.find(\n\t\t(p) =>\n\t\t\tp.protocolVersions.includes(protocolVersion)\n\t\t\t&& p.name.toLowerCase().startsWith(json.meta.library),\n\t);\n\n\tif (!impl) {\n\t\tthrow new ZWaveError(\n\t\t\t`Did not find a matching implementation for protocol version ${protocolVersion} and library ${json.meta.library}. To convert 500-series NVMs, both the source and the target controller must be using Z-Wave SDK 6.61 or higher.`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t);\n\t}\n\n\tconst { layout, nvmSize } = resolveLayout(impl.layout);\n\n\t// Erase the NVM and set some basic information\n\tconst ret = new Uint8Array(nvmSize);\n\tconst io = new NVMMemoryIO(ret);\n\tconst nvm = new NVM500(io);\n\tawait nvm.erase({\n\t\tlayout,\n\t\tnvmSize,\n\t\tlibrary: impl.library,\n\t\tnvmDescriptor: {\n\t\t\t...pick(json.meta, [\n\t\t\t\t\"manufacturerID\",\n\t\t\t\t\"productType\",\n\t\t\t\t\"productID\",\n\t\t\t\t\"firmwareID\",\n\t\t\t]),\n\t\t\t// Override the protocol version with the specified one\n\t\t\tprotocolVersion,\n\t\t\tfirmwareVersion: json.controller.applicationVersion,\n\t\t},\n\t});\n\n\tconst adapter = new NVM500Adapter(nvm);\n\n\t// Set controller infos\n\tconst c = json.controller;\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"homeId\" },\n\t\tBytes.from(c.ownHomeId.replace(/^0x/, \"\"), \"hex\"),\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"learnedHomeId\" },\n\t\tc.learnedHomeId\n\t\t\t? Bytes.from(c.learnedHomeId.replace(/^0x/, \"\"), \"hex\")\n\t\t\t: undefined,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"nodeId\" },\n\t\tc.nodeId,\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"lastNodeId\" },\n\t\tc.lastNodeId,\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"maxNodeId\" },\n\t\tc.maxNodeId,\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"reservedId\" },\n\t\tc.reservedId,\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"staticControllerNodeId\" },\n\t\tc.staticControllerNodeId,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"controllerConfiguration\" },\n\t\tc.controllerConfiguration,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucUpdateEntries\" },\n\t\tc.sucUpdateEntries,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucLastIndex\" },\n\t\tc.sucLastIndex,\n\t);\n\n\tif (c.systemState != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"systemState\" },\n\t\t\tc.systemState,\n\t\t);\n\t}\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"watchdogStarted\" },\n\t\tc.watchdogStarted,\n\t);\n\n\tif (c.rfConfig.powerLevelNormal != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerLevelNormal\" },\n\t\t\tc.rfConfig.powerLevelNormal,\n\t\t);\n\t}\n\tif (c.rfConfig.powerLevelLow != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerLevelLow\" },\n\t\t\tc.rfConfig.powerLevelLow,\n\t\t);\n\t}\n\tif (c.rfConfig.powerMode != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerMode\" },\n\t\t\tc.rfConfig.powerMode,\n\t\t);\n\t}\n\tif (c.rfConfig.powerModeExtintEnable != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerModeExtintEnable\" },\n\t\t\tc.rfConfig.powerModeExtintEnable,\n\t\t);\n\t}\n\tif (c.rfConfig.powerModeWutTimeout != undefined) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"powerModeWutTimeout\" },\n\t\t\tc.rfConfig.powerModeWutTimeout,\n\t\t);\n\t}\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"preferredRepeaters\" },\n\t\tc.preferredRepeaters,\n\t);\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"commandClasses\" },\n\t\tc.commandClasses,\n\t);\n\n\tif (c.applicationData) {\n\t\tawait adapter.set(\n\t\t\t{ domain: \"controller\", type: \"applicationData\" },\n\t\t\tBytes.from(c.applicationData, \"hex\"),\n\t\t);\n\t}\n\n\t// Set node infos\n\tconst appRouteLock: number[] = [];\n\tconst routeSlaveSUC: number[] = [];\n\tconst pendingDiscovery: number[] = [];\n\tconst sucPendingUpdate: number[] = [];\n\tconst virtualNodeIds: number[] = [];\n\n\tfor (const [id, node] of Object.entries(json.nodes)) {\n\t\tconst nodeId = parseInt(id);\n\t\tif (!nodeHasInfo(node)) {\n\t\t\tvirtualNodeIds.push(nodeId);\n\t\t\tcontinue;\n\t\t}\n\t\tif (node.appRouteLock) appRouteLock.push(nodeId);\n\t\tif (node.routeSlaveSUC) routeSlaveSUC.push(nodeId);\n\t\tif (node.pendingDiscovery) pendingDiscovery.push(nodeId);\n\t\tif (node.sucPendingUpdate) sucPendingUpdate.push(nodeId);\n\n\t\tawait adapter.set(\n\t\t\t{ domain: \"node\", nodeId, type: \"info\" },\n\t\t\t{\n\t\t\t\tnodeId,\n\t\t\t\t...node,\n\t\t\t},\n\t\t);\n\n\t\tif (node.lwr || node.nlwr) {\n\t\t\tawait adapter.set(\n\t\t\t\t{ domain: \"node\", nodeId, type: \"routes\" },\n\t\t\t\t{\n\t\t\t\t\tlwr: node.lwr ?? undefined,\n\t\t\t\t\tnlwr: node.nlwr ?? undefined,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"appRouteLock\" },\n\t\t[...appRouteLock],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"routeSlaveSUC\" },\n\t\t[...routeSlaveSUC],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"sucPendingUpdate\" },\n\t\t[...sucPendingUpdate],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"virtualNodeIds\" },\n\t\t[...virtualNodeIds],\n\t);\n\tawait adapter.set(\n\t\t{ domain: \"controller\", type: \"pendingDiscovery\" },\n\t\t[...pendingDiscovery],\n\t);\n\n\tawait adapter.commit();\n\tawait io.close();\n\treturn ret;\n}\n\nexport function json500To700(\n\tjson: NVM500JSON,\n\ttruncateApplicationData?: boolean,\n): NVMJSON {\n\tconst source = cloneDeep(json);\n\n\t// On the 500 series, some properties are only defined for the nodes, so we pull it off the\n\t// controller's node entry\n\tlet controllerNode = source.nodes[\n\t\tsource.controller.nodeId || 1\n\t] as NVMJSONNodeWithInfo; // Little hack because TS doesn't type check the union type properly\n\tif (!nodeHasInfo(controllerNode)) {\n\t\t// No information available, use sensible defaults\n\t\tcontrollerNode = {\n\t\t\tisListening: true,\n\t\t\toptionalFunctionality: false,\n\t\t\t// Static PC Controller\n\t\t\tgenericDeviceClass: 0x02,\n\t\t\tspecificDeviceClass: 0x01,\n\t\t} as any;\n\t}\n\n\tlet applicationData: string | null = null;\n\tif (source.controller.applicationData) {\n\t\tlet raw = Bytes.from(source.controller.applicationData, \"hex\");\n\t\t// Find actual start and end of application data, ignoring zeroes\n\t\tlet start = 0;\n\t\twhile (start < raw.length && raw[start] === 0) {\n\t\t\tstart++;\n\t\t}\n\t\tlet end = raw.length - 1;\n\t\twhile (end > start && raw[end] === 0) {\n\t\t\tend--;\n\t\t}\n\t\traw = raw.subarray(start, end + 1);\n\t\tif (raw.length > 512) {\n\t\t\tif (!truncateApplicationData) {\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\"Invalid NVM JSON: Application data would be truncated! Set truncateApplicationData to true to allow this.\",\n\t\t\t\t\tZWaveErrorCodes.NVM_InvalidJSON,\n\t\t\t\t);\n\t\t\t}\n\t\t\traw = raw.subarray(0, 512);\n\t\t}\n\t\tapplicationData = raw.toString(\"hex\");\n\t}\n\n\t// https://github.com/zwave-js/zwave-js/issues/6055\n\t// On some controllers this byte can be 0xff (effectively not set)\n\tlet controllerConfiguration = source.controller.controllerConfiguration;\n\tif (source.controller.controllerConfiguration === 0xff) {\n\t\t// Default to SUC/Primary\n\t\tcontrollerConfiguration = ControllerCapabilityFlags.SISPresent\n\t\t\t| ControllerCapabilityFlags.WasRealPrimary\n\t\t\t| ControllerCapabilityFlags.SUC;\n\t}\n\n\tlet homeId: string;\n\tif (\n\t\t!!(\n\t\t\tcontrollerConfiguration & ControllerCapabilityFlags.OnOtherNetwork\n\t\t)\n\t\t&& source.controller.learnedHomeId\n\t\t&& source.controller.nodeId\n\t) {\n\t\t// The controller did not start the network itself. We only keep this if we have a home ID and node ID\n\t\thomeId = source.controller.learnedHomeId;\n\t} else {\n\t\t// The controller did start the network itself\n\t\thomeId = source.controller.ownHomeId;\n\t\tcontrollerConfiguration &= ~ControllerCapabilityFlags.OnOtherNetwork;\n\t\t// Reconstruct the node ID. If we don't know, 1 is a good default\n\t\tif (controllerConfiguration & ControllerCapabilityFlags.SUC) {\n\t\t\tsource.controller.nodeId = source.controller.staticControllerNodeId\n\t\t\t\t|| 1;\n\t\t} else {\n\t\t\tsource.controller.nodeId = 1;\n\t\t}\n\t}\n\n\t// https://github.com/zwave-js/zwave-js/issues/6055\n\t// Some controllers have invalid information for the IDs\n\tlet maxNodeId = source.controller.maxNodeId;\n\tif (maxNodeId === 0xff) maxNodeId = source.controller.lastNodeId;\n\tlet reservedId = source.controller.reservedId;\n\tif (reservedId === 0xff) reservedId = 0;\n\n\tconst ret: NVMJSON = {\n\t\t// Start out with format 0 (= protocol version 7.0.0), the jsonToNVM routines will do further conversion\n\t\tformat: 0,\n\t\tcontroller: {\n\t\t\t// This will contain the original 6.x protocol version, but the jsonToNVM routines will update it\n\t\t\tprotocolVersion: source.controller.protocolVersion,\n\t\t\tapplicationVersion: source.controller.applicationVersion,\n\t\t\thomeId,\n\t\t\tnodeId: source.controller.nodeId,\n\t\t\tlastNodeId: source.controller.lastNodeId,\n\t\t\tstaticControllerNodeId: source.controller.staticControllerNodeId,\n\t\t\tsucLastIndex: source.controller.sucLastIndex,\n\t\t\tcontrollerConfiguration,\n\t\t\tsucUpdateEntries: source.controller.sucUpdateEntries,\n\t\t\tmaxNodeId,\n\t\t\treservedId,\n\t\t\tsystemState: source.controller.systemState ?? 0,\n\t\t\tpreferredRepeaters: source.controller.preferredRepeaters,\n\n\t\t\t// RF config exists on both series but isn't compatible\n\n\t\t\tisListening: controllerNode.isListening,\n\t\t\toptionalFunctionality: controllerNode.optionalFunctionality,\n\t\t\tgenericDeviceClass: controllerNode.genericDeviceClass,\n\t\t\tspecificDeviceClass: controllerNode.specificDeviceClass ?? 0,\n\n\t\t\tcommandClasses: {\n\t\t\t\tincludedInsecurely: source.controller.commandClasses,\n\t\t\t\tincludedSecurelyInsecureCCs: [],\n\t\t\t\tincludedSecurelySecureCCs: [],\n\t\t\t},\n\n\t\t\tapplicationData,\n\t\t},\n\t\t// The node entries are actually compatible between the two JSON versions\n\t\t// but the types are structured differently\n\t\tnodes: source.nodes,\n\t};\n\treturn ret;\n}\n\nexport function json700To500(json: NVMJSON): NVM500JSON {\n\tconst source = cloneDeep(json);\n\n\tlet ownHomeId: string;\n\tlet learnedHomeId: string | null = null;\n\tlet nodeId: number;\n\tif (\n\t\tsource.controller.controllerConfiguration\n\t\t& ControllerCapabilityFlags.OnOtherNetwork\n\t) {\n\t\t// The controller did not start the network itself\n\t\townHomeId = learnedHomeId = source.controller.homeId;\n\t\tnodeId = source.controller.nodeId;\n\t} else {\n\t\t// The controller did start the network itself\n\t\townHomeId = source.controller.homeId;\n\t\t// 500 series controllers expect the node ID to be 0 when they are the primary\n\t\tnodeId = 0;\n\t}\n\n\tconst ret: NVM500JSON = {\n\t\tformat: 500,\n\t\tcontroller: {\n\t\t\t// This will contain the original 7.x protocol version, but the jsonToNVM routines will update it\n\t\t\tprotocolVersion: source.controller.protocolVersion,\n\t\t\tapplicationVersion: source.controller.applicationVersion,\n\t\t\t// The 700 series does not distinguish between own and learned home ID in NVM\n\t\t\t// We infer it from the controller configuration if we need it\n\t\t\townHomeId,\n\t\t\tlearnedHomeId,\n\t\t\tnodeId,\n\t\t\tlastNodeId: source.controller.lastNodeId,\n\t\t\tstaticControllerNodeId: source.controller.staticControllerNodeId,\n\t\t\tsucLastIndex: source.controller.sucLastIndex,\n\t\t\tcontrollerConfiguration: source.controller.controllerConfiguration,\n\t\t\tsucUpdateEntries: source.controller.sucUpdateEntries,\n\t\t\tmaxNodeId: source.controller.maxNodeId,\n\t\t\treservedId: source.controller.reservedId,\n\t\t\tsystemState: source.controller.systemState,\n\t\t\twatchdogStarted: 0,\n\t\t\tpreferredRepeaters: json.controller.preferredRepeaters ?? [],\n\n\t\t\t// RF config exists on both series but isn't compatible. So set the default,\n\t\t\t// it will be taken from the target NVM on restore.\n\t\t\trfConfig: {\n\t\t\t\tpowerLevelNormal: [255, 255, 255],\n\t\t\t\tpowerLevelLow: [255, 255, 255],\n\t\t\t\tpowerMode: 255,\n\t\t\t\tpowerModeExtintEnable: 255,\n\t\t\t\tpowerModeWutTimeout: 0xffffffff,\n\t\t\t},\n\n\t\t\tcommandClasses: source.controller.commandClasses.includedInsecurely,\n\n\t\t\tapplicationData: source.controller.applicationData,\n\t\t},\n\t\t// The node entries are actually compatible between the two JSON versions\n\t\t// just the types are structured differently\n\t\tnodes: source.nodes,\n\t};\n\treturn ret;\n}\n\n/** Converts the given source NVM into a format that is compatible with the given target NVM */\nexport async function migrateNVM(\n\tsourceNVM: BytesView,\n\ttargetNVM: BytesView,\n\toptions: MigrateNVMOptions = {},\n): Promise<BytesView> {\n\tlet source: ParsedNVM;\n\tlet target: ParsedNVM;\n\tlet sourceProtocolFileFormat: number | undefined;\n\tlet targetProtocolFileFormat: number | undefined;\n\n\ttry {\n\t\tsource = {\n\t\t\ttype: 700,\n\t\t\tjson: await nvmToJSON(sourceNVM),\n\t\t};\n\t\tsourceProtocolFileFormat = source.json.format;\n\t} catch (e) {\n\t\tif (isZWaveError(e) && e.code === ZWaveErrorCodes.NVM_InvalidFormat) {\n\t\t\t// This is not a 700 series NVM, maybe it is a 500 series one?\n\t\t\tsource = {\n\t\t\t\ttype: 500,\n\t\t\t\tjson: await nvm500ToJSON(sourceNVM),\n\t\t\t};\n\t\t} else if (\n\t\t\tisZWaveError(e)\n\t\t\t&& e.code === ZWaveErrorCodes.NVM_NotSupported\n\t\t\t&& isObject(e.context)\n\t\t\t&& typeof e.context.protocolFileFormat === \"number\"\n\t\t) {\n\t\t\t// This is a 700 series NVM, but the protocol version is not (yet) supported\n\t\t\tsource = { type: \"unknown\" };\n\t\t\tsourceProtocolFileFormat = e.context.protocolFileFormat;\n\t\t} else {\n\t\t\tsource = { type: \"unknown\" };\n\t\t}\n\t}\n\n\ttry {\n\t\ttarget = {\n\t\t\ttype: 700,\n\t\t\tjson: await nvmToJSON(targetNVM),\n\t\t};\n\t\ttargetProtocolFileFormat = target.json.format;\n\t} catch (e) {\n\t\tif (isZWaveError(e) && e.code === ZWaveErrorCodes.NVM_InvalidFormat) {\n\t\t\t// This is not a 700 series NVM, maybe it is a 500 series one?\n\t\t\ttarget = {\n\t\t\t\ttype: 500,\n\t\t\t\tjson: await nvm500ToJSON(targetNVM),\n\t\t\t};\n\t\t} else if (\n\t\t\tisZWaveError(e)\n\t\t\t&& e.code === ZWaveErrorCodes.NVM_NotSupported\n\t\t\t&& source.type === 700\n\t\t\t&& isObject(e.context)\n\t\t\t&& typeof e.context.protocolFileFormat === \"number\"\n\t\t) {\n\t\t\t// This is a 700 series NVM, but the protocol version is not (yet) supported\n\t\t\ttarget = { type: \"unknown\" };\n\t\t\ttargetProtocolFileFormat = e.context.protocolFileFormat;\n\t\t} else {\n\t\t\ttarget = { type: \"unknown\" };\n\t\t}\n\t}\n\n\tconst {\n\t\tpreserveApplicationData = true,\n\t\tpreserveNeighbors = true,\n\t\tpreserveRoutes = true,\n\t\tpreserveSUCUpdateEntries = true,\n\t} = options;\n\n\tconst preserveAll = preserveApplicationData\n\t\t&& preserveNeighbors\n\t\t&& preserveRoutes\n\t\t&& preserveSUCUpdateEntries;\n\n\t// Short circuit if...\n\tif (\n\t\ttarget.type === \"unknown\"\n\t\t&& targetProtocolFileFormat\n\t\t&& targetProtocolFileFormat > MAX_PROTOCOL_FILE_FORMAT\n\t\t&& sourceProtocolFileFormat\n\t\t&& sourceProtocolFileFormat <= targetProtocolFileFormat\n\t\t&& sourceNVM.length === targetNVM.length\n\t\t// ...everything should be preserved and...\n\t\t&& preserveAll\n\t) {\n\t\t// ...both the source and the target are 700 series, but at least the target uses an unsupported protocol version.\n\t\t// We can be sure however that the target can upgrade any 700 series NVM to its protocol version, as long as the\n\t\t// source protocol version is not higher than the target's\n\t\treturn sourceNVM;\n\t} else if (\n\t\tsource.type === 700\n\t\t&& target.type === 700\n\t\t// ...the source and target NVMs have the same size and structure\n\t\t&& sourceNVM.length === targetNVM.length\n\t\t&& source.json.meta.sharedFileSystem\n\t\t\t=== target.json.meta.sharedFileSystem\n\t\t// ...everything should be preserved,...\n\t\t&& preserveAll\n\t) {\n\t\t// ... the source and target protocol versions are compatible without conversion\n\t\tconst sourceProtocolVersion = source.json.controller.protocolVersion;\n\t\tconst targetProtocolVersion = target.json.controller.protocolVersion;\n\t\t// ... and the application version on the both is compatible with the respective protocol version\n\t\tconst sourceApplicationVersion =\n\t\t\tsource.json.controller.applicationVersion;\n\t\tconst targetApplicationVersion =\n\t\t\ttarget.json.controller.applicationVersion;\n\n\t\t// The 700 series firmware can automatically upgrade backups from a previous protocol version\n\t\t// Not sure when that ability was added. To be on the safe side, allow it for 7.16+ which definitely supports it.\n\t\tif (\n\t\t\tsemverGte(targetProtocolVersion, \"7.16.0\")\n\t\t\t&& semverGte(targetProtocolVersion, sourceProtocolVersion)\n\t\t\t// the application version is updated on every update, protocol version only when the format changes\n\t\t\t// so this is a good indicator if the NVMs are in a compatible state\n\t\t\t&& semverGte(targetApplicationVersion, targetProtocolVersion)\n\t\t\t&& semverGte(sourceApplicationVersion, sourceProtocolVersion)\n\t\t\t// avoid preserving broken 255.x versions which appear on some controllers\n\t\t\t&& semverLt(sourceApplicationVersion, \"255.0.0\")\n\t\t\t&& semverLt(targetApplicationVersion, \"255.0.0\")\n\t\t\t// and avoid restoring a backup with a shifted 800 series application version file\n\t\t\t&& (!hasShiftedAppVersion800File(source.json))\n\t\t) {\n\t\t\treturn sourceNVM;\n\t\t}\n\t} else if (source.type === \"unknown\" && target.type !== \"unknown\") {\n\t\t// ...only the source has an unsupported format, so we have to convert but can't\n\t\tthrow new ZWaveError(\n\t\t\t`The source NVM has an unsupported format, which cannot be restored on a ${target.type}-series NVM!`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t);\n\t} else if (source.type !== \"unknown\" && target.type === \"unknown\") {\n\t\t// ...only the target has an unsupported format, so we have to convert but can't\n\t\tthrow new ZWaveError(\n\t\t\t`The target NVM has an unsupported format, cannot restore ${source.type}-series NVM onto it!`,\n\t\t\tZWaveErrorCodes.NVM_NotSupported,\n\t\t);\n\t} else if (source.type === \"unknown\" && target.type === \"unknown\") {\n\t\t// ...both are an unsupported format, meaning pre-6.61 SDK, which we cannot convert\n\t\treturn sourceNVM;\n\t}\n\n\t// TypeScript doesn't understand multi-variable narrowings (yet)\n\tsource = source as Exclude<ParsedNVM, { type: \"unknown\" }>;\n\ttarget = target as Exclude<ParsedNVM, { type: \"unknown\" }>;\n\n\t// Some 700 series NVMs have a strange 255.x application version - fix that first\n\tif (\n\t\ttarget.type === 700\n\t\t&& semverGte(target.json.controller.applicationVersion, \"255.0.0\")\n\t) {\n\t\t// replace both with the protocol version\n\t\ttarget.json.controller.applicationVersion =\n\t\t\ttarget.json.controller.protocolVersion;\n\t}\n\n\t// In any case, preserve the application version of the target stick\n\tsource.json.controller.applicationVersion =\n\t\ttarget.json.controller.applicationVersion;\n\n\t// Remove information we do not want to preserve\n\tif (!preserveApplicationData) {\n\t\tsource.json.controller.applicationData = undefined;\n\t}\n\tif (!preserveNeighbors) {\n\t\tfor (const node of Object.values(source.json.nodes)) {\n\t\t\tif (!node.isVirtual) {\n\t\t\t\tnode.neighbors = [];\n\t\t\t}\n\t\t}\n\t}\n\tif (!preserveRoutes) {\n\t\tfor (const node of Object.values(source.json.nodes)) {\n\t\t\tif (!node.isVirtual) {\n\t\t\t\tnode.appRouteLock = false;\n\t\t\t\tnode.lwr = undefined;\n\t\t\t\tnode.nlwr = undefined;\n\t\t\t}\n\t\t}\n\t}\n\tif (!preserveSUCUpdateEntries) {\n\t\tsource.json.controller.sucUpdateEntries = [];\n\t\tsource.json.controller.sucLastIndex = 0xff;\n\t\tfor (const node of Object.values(source.json.nodes)) {\n\t\t\tif (!node.isVirtual) {\n\t\t\t\tnode.sucUpdateIndex = 0xfe;\n\t\t\t\tnode.sucPendingUpdate = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (source.type === 500 && target.type === 500) {\n\t\t// Both are 500, so we just need to update the metadata to match the target\n\t\tconst json: Required<NVM500JSON> = {\n\t\t\t...source.json,\n\t\t\tmeta: target.json.meta,\n\t\t};\n\t\t// If the target is a 500 series stick, preserve the RF config\n\t\tjson.controller.rfConfig = target.json.controller.rfConfig;\n\t\treturn jsonToNVM500(json, target.json.controller.protocolVersion);\n\t} else if (source.type === 500 && target.type === 700) {\n\t\t// We need to upgrade the source to 700 series\n\t\tconst json: NVMJSONWithMeta = {\n\t\t\tlrNodes: {},\n\t\t\t...json500To700(source.json, true),\n\t\t\tmeta: target.json.meta,\n\t\t};\n\t\t// The target is a different series, try to preserve the RF config of the target stick\n\t\tjson.controller.rfConfig = target.json.controller.rfConfig;\n\t\t// 700 series distinguishes the NVM format by the application version\n\t\treturn jsonToNVM(json, target.json.controller.applicationVersion);\n\t} else if (source.type === 700 && target.type === 500) {\n\t\t// We need to downgrade the source to 500 series\n\t\tconst json: Required<NVM500JSON> = {\n\t\t\t...json700To500(source.json),\n\t\t\tmeta: target.json.meta,\n\t\t};\n\t\t// The target is a different series, try to preserve the RF config of the target stick\n\t\tjson.controller.rfConfig = target.json.controller.rfConfig;\n\t\treturn jsonToNVM500(json, target.json.controller.protocolVersion);\n\t} else {\n\t\t// Both are 700, so we just need to update the metadata to match the target\n\t\tconst json: NVMJSONWithMeta = {\n\t\t\t...(source.json as NVMJSONWithMeta),\n\t\t\tmeta: (target.json as NVMJSONWithMeta).meta,\n\t\t};\n\t\t// 700 series distinguishes the NVM format by the application version\n\t\treturn jsonToNVM(json, target.json.controller.applicationVersion);\n\t}\n}\n\n/**\n * Detects whether the app version file on a 800 series controller is shifted by 1 byte\n */\nfunction hasShiftedAppVersion800File(\n\tjson: NVMJSONWithMeta,\n): boolean {\n\t// We can only detect this on 800 series controllers with the shared FS\n\tif (!json.meta.sharedFileSystem) return false;\n\n\tconst protocolVersion = semverParse(json.controller.protocolVersion);\n\t// Invalid protocol version, cannot fix anything\n\tif (!protocolVersion) return false;\n\n\tconst applicationVersion = semverParse(json.controller.applicationVersion);\n\t// Invalid application version, cannot fix anything\n\tif (!applicationVersion) return false;\n\n\t// We consider the version shifted if:\n\t// - the app version format is the major protocol version\n\t// - the app version major is the minor protocol version +/- 3\n\n\tif (json.applicationFileFormat !== protocolVersion.major) return false;\n\tif (Math.abs(applicationVersion.major - protocolVersion.minor) > 3) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_consts", "import_adapter", "import_shared", "ret", "semverParse", "semverLte", "semverGte", "semverLt"]
|
|
7
7
|
}
|
package/build/cjs/lib/NVM3.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type BytesView } from "@zwave-js/shared";
|
|
1
2
|
import { type NVM, type NVMIO } from "./common/definitions.js";
|
|
2
3
|
import { PageWriteSize } from "./nvm3/consts.js";
|
|
3
4
|
import { type NVMSection } from "./nvm3/files/index.js";
|
|
@@ -30,7 +31,7 @@ export interface NVM3Meta {
|
|
|
30
31
|
memoryMapped: boolean;
|
|
31
32
|
}
|
|
32
33
|
export type NVM3EraseOptions = Partial<NVM3Meta>;
|
|
33
|
-
export declare class NVM3 implements NVM<number,
|
|
34
|
+
export declare class NVM3 implements NVM<number, BytesView> {
|
|
34
35
|
constructor(io: NVMIO);
|
|
35
36
|
private _io;
|
|
36
37
|
private _access;
|
|
@@ -41,12 +42,12 @@ export declare class NVM3 implements NVM<number, Uint8Array> {
|
|
|
41
42
|
init(): Promise<NVM3FileSystemInfo>;
|
|
42
43
|
private getNVMSectionForFile;
|
|
43
44
|
has(fileId: number): Promise<boolean>;
|
|
44
|
-
readObjectData(object: NVM3ObjectHeader): Promise<
|
|
45
|
-
get(fileId: number, section?: NVM3SectionInfo): Promise<
|
|
45
|
+
readObjectData(object: NVM3ObjectHeader): Promise<BytesView>;
|
|
46
|
+
get(fileId: number, section?: NVM3SectionInfo): Promise<BytesView | undefined>;
|
|
46
47
|
private writeObjects;
|
|
47
|
-
set(property: number, value:
|
|
48
|
+
set(property: number, value: BytesView): Promise<void>;
|
|
48
49
|
/** Writes multiple values to the NVM at once. `null` / `undefined` cause the value to be deleted */
|
|
49
|
-
setMany(values: [number,
|
|
50
|
+
setMany(values: [number, BytesView | null | undefined][]): Promise<void>;
|
|
50
51
|
delete(property: number): Promise<void>;
|
|
51
52
|
erase(options?: NVM3EraseOptions): Promise<void>;
|
|
52
53
|
}
|