@zwave-js/nvmedit 13.2.0 → 13.4.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/cli.js +5 -5
- package/build/cli.js.map +1 -1
- package/build/convert.d.ts +15 -14
- package/build/convert.d.ts.map +1 -1
- package/build/convert.js +647 -389
- package/build/convert.js.map +1 -1
- package/build/index.d.ts +12 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +20 -2
- package/build/index.js.map +1 -1
- package/build/index_safe.d.ts +7 -4
- package/build/index_safe.d.ts.map +1 -1
- package/build/index_safe.js +4 -2
- package/build/index_safe.js.map +1 -1
- package/build/lib/NVM3.d.ts +53 -0
- package/build/lib/NVM3.d.ts.map +1 -0
- package/build/lib/NVM3.js +650 -0
- package/build/lib/NVM3.js.map +1 -0
- package/build/lib/NVM500.d.ts +46 -0
- package/build/lib/NVM500.d.ts.map +1 -0
- package/build/lib/NVM500.js +413 -0
- package/build/lib/NVM500.js.map +1 -0
- package/build/lib/common/definitions.d.ts +138 -0
- package/build/lib/common/definitions.d.ts.map +1 -0
- package/build/lib/common/definitions.js +11 -0
- package/build/lib/common/definitions.js.map +1 -0
- package/build/lib/common/routeCache.d.ts +18 -0
- package/build/lib/common/routeCache.d.ts.map +1 -0
- package/build/lib/common/routeCache.js +56 -0
- package/build/lib/common/routeCache.js.map +1 -0
- package/build/lib/common/sucUpdateEntry.d.ts +10 -0
- package/build/lib/common/sucUpdateEntry.d.ts.map +1 -0
- package/build/lib/common/sucUpdateEntry.js +35 -0
- package/build/lib/common/sucUpdateEntry.js.map +1 -0
- package/build/lib/common/utils.d.ts +9 -0
- package/build/lib/common/utils.d.ts.map +1 -0
- package/build/lib/common/utils.js +52 -0
- package/build/lib/common/utils.js.map +1 -0
- package/build/lib/io/BufferedNVMReader.d.ts +21 -0
- package/build/lib/io/BufferedNVMReader.d.ts.map +1 -0
- package/build/lib/io/BufferedNVMReader.js +79 -0
- package/build/lib/io/BufferedNVMReader.js.map +1 -0
- package/build/lib/io/NVMFileIO.d.ts +24 -0
- package/build/lib/io/NVMFileIO.d.ts.map +1 -0
- package/build/lib/io/NVMFileIO.js +86 -0
- package/build/lib/io/NVMFileIO.js.map +1 -0
- package/build/lib/io/NVMMemoryIO.d.ts +20 -0
- package/build/lib/io/NVMMemoryIO.d.ts.map +1 -0
- package/build/lib/io/NVMMemoryIO.js +48 -0
- package/build/lib/io/NVMMemoryIO.js.map +1 -0
- package/build/lib/nvm3/adapter.d.ts +33 -0
- package/build/lib/nvm3/adapter.d.ts.map +1 -0
- package/build/lib/nvm3/adapter.js +903 -0
- package/build/lib/nvm3/adapter.js.map +1 -0
- package/build/lib/nvm3/consts.d.ts.map +1 -0
- package/build/lib/nvm3/consts.js.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationCCsFile.d.ts +5 -3
- package/build/lib/nvm3/files/ApplicationCCsFile.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationCCsFile.js +4 -3
- package/build/lib/nvm3/files/ApplicationCCsFile.js.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationDataFile.d.ts +4 -4
- package/build/lib/nvm3/files/ApplicationDataFile.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationDataFile.js +7 -6
- package/build/lib/nvm3/files/ApplicationDataFile.js.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationNameFile.d.ts +5 -3
- package/build/lib/nvm3/files/ApplicationNameFile.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationNameFile.js +4 -3
- package/build/lib/nvm3/files/ApplicationNameFile.js.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationRFConfigFile.d.ts +5 -3
- package/build/lib/nvm3/files/ApplicationRFConfigFile.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationRFConfigFile.js +4 -3
- package/build/lib/nvm3/files/ApplicationRFConfigFile.js.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationTypeFile.d.ts +5 -3
- package/build/lib/nvm3/files/ApplicationTypeFile.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/ApplicationTypeFile.js +4 -3
- package/build/lib/nvm3/files/ApplicationTypeFile.js.map +1 -0
- package/build/{files → lib/nvm3/files}/ControllerInfoFile.d.ts +5 -3
- package/build/lib/nvm3/files/ControllerInfoFile.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/ControllerInfoFile.js +4 -3
- package/build/lib/nvm3/files/ControllerInfoFile.js.map +1 -0
- package/build/{files → lib/nvm3/files}/NVMFile.d.ts +18 -7
- package/build/lib/nvm3/files/NVMFile.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/NVMFile.js +44 -30
- package/build/lib/nvm3/files/NVMFile.js.map +1 -0
- package/build/{files → lib/nvm3/files}/NodeInfoFiles.d.ts +10 -4
- package/build/lib/nvm3/files/NodeInfoFiles.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/NodeInfoFiles.js +6 -3
- package/build/lib/nvm3/files/NodeInfoFiles.js.map +1 -0
- package/build/{files → lib/nvm3/files}/ProtocolNodeMaskFiles.d.ts +22 -15
- package/build/lib/nvm3/files/ProtocolNodeMaskFiles.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/ProtocolNodeMaskFiles.js +50 -30
- package/build/lib/nvm3/files/ProtocolNodeMaskFiles.js.map +1 -0
- package/build/{files → lib/nvm3/files}/RouteCacheFiles.d.ts +8 -17
- package/build/lib/nvm3/files/RouteCacheFiles.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/RouteCacheFiles.js +16 -64
- package/build/lib/nvm3/files/RouteCacheFiles.js.map +1 -0
- package/build/{files → lib/nvm3/files}/SUCUpdateEntriesFile.d.ts +10 -13
- package/build/lib/nvm3/files/SUCUpdateEntriesFile.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/SUCUpdateEntriesFile.js +15 -42
- package/build/lib/nvm3/files/SUCUpdateEntriesFile.js.map +1 -0
- package/build/{files → lib/nvm3/files}/VersionFiles.d.ts +7 -5
- package/build/lib/nvm3/files/VersionFiles.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/VersionFiles.js +10 -7
- package/build/lib/nvm3/files/VersionFiles.js.map +1 -0
- package/build/{files → lib/nvm3/files}/index.d.ts +1 -0
- package/build/lib/nvm3/files/index.d.ts.map +1 -0
- package/build/{files → lib/nvm3/files}/index.js +1 -0
- package/build/lib/nvm3/files/index.js.map +1 -0
- package/build/lib/nvm3/object.d.ts +29 -0
- package/build/lib/nvm3/object.d.ts.map +1 -0
- package/build/lib/nvm3/object.js +118 -0
- package/build/lib/nvm3/object.js.map +1 -0
- package/build/{nvm3 → lib/nvm3}/page.d.ts +1 -5
- package/build/lib/nvm3/page.d.ts.map +1 -0
- package/build/lib/nvm3/page.js +37 -0
- package/build/lib/nvm3/page.js.map +1 -0
- package/build/{nvm3 → lib/nvm3}/utils.d.ts +2 -4
- package/build/lib/nvm3/utils.d.ts.map +1 -0
- package/build/lib/nvm3/utils.js +143 -0
- package/build/lib/nvm3/utils.js.map +1 -0
- package/build/lib/nvm500/EntryParsers.d.ts.map +1 -0
- package/build/lib/nvm500/EntryParsers.js.map +1 -0
- package/build/lib/nvm500/adapter.d.ts +22 -0
- package/build/lib/nvm500/adapter.d.ts.map +1 -0
- package/build/lib/nvm500/adapter.js +371 -0
- package/build/lib/nvm500/adapter.js.map +1 -0
- package/build/lib/nvm500/impls/Bridge_6_6x.d.ts +3 -0
- package/build/lib/nvm500/impls/Bridge_6_6x.d.ts.map +1 -0
- package/build/{nvm500/parsers → lib/nvm500/impls}/Bridge_6_6x.js +1 -1
- package/build/lib/nvm500/impls/Bridge_6_6x.js.map +1 -0
- package/build/lib/nvm500/impls/Bridge_6_7x.d.ts +3 -0
- package/build/lib/nvm500/impls/Bridge_6_7x.d.ts.map +1 -0
- package/build/{nvm500/parsers → lib/nvm500/impls}/Bridge_6_7x.js +1 -1
- package/build/lib/nvm500/impls/Bridge_6_7x.js.map +1 -0
- package/build/lib/nvm500/impls/Bridge_6_8x.d.ts +3 -0
- package/build/lib/nvm500/impls/Bridge_6_8x.d.ts.map +1 -0
- package/build/{nvm500/parsers → lib/nvm500/impls}/Bridge_6_8x.js +1 -1
- package/build/lib/nvm500/impls/Bridge_6_8x.js.map +1 -0
- package/build/lib/nvm500/impls/Static_6_6x.d.ts +3 -0
- package/build/lib/nvm500/impls/Static_6_6x.d.ts.map +1 -0
- package/build/{nvm500/parsers → lib/nvm500/impls}/Static_6_6x.js +1 -1
- package/build/lib/nvm500/impls/Static_6_6x.js.map +1 -0
- package/build/lib/nvm500/impls/Static_6_7x.d.ts +3 -0
- package/build/lib/nvm500/impls/Static_6_7x.d.ts.map +1 -0
- package/build/{nvm500/parsers → lib/nvm500/impls}/Static_6_7x.js +1 -1
- package/build/lib/nvm500/impls/Static_6_7x.js.map +1 -0
- package/build/lib/nvm500/impls/Static_6_8x.d.ts +3 -0
- package/build/lib/nvm500/impls/Static_6_8x.d.ts.map +1 -0
- package/build/{nvm500/parsers → lib/nvm500/impls}/Static_6_8x.js +1 -1
- package/build/lib/nvm500/impls/Static_6_8x.js.map +1 -0
- package/build/lib/nvm500/impls/index.d.ts +2 -0
- package/build/lib/nvm500/impls/index.d.ts.map +1 -0
- package/build/lib/nvm500/impls/index.js +18 -0
- package/build/lib/nvm500/impls/index.js.map +1 -0
- package/build/{nvm500 → lib/nvm500}/shared.d.ts +19 -2
- package/build/lib/nvm500/shared.d.ts.map +1 -0
- package/build/{nvm500 → lib/nvm500}/shared.js +19 -1
- package/build/lib/nvm500/shared.js.map +1 -0
- package/build/nvm500/NVMParser.d.ts +5 -36
- package/build/nvm500/NVMParser.d.ts.map +1 -1
- package/build/nvm500/NVMParser.js +0 -524
- package/build/nvm500/NVMParser.js.map +1 -1
- package/package.json +2 -2
- package/build/files/ApplicationCCsFile.d.ts.map +0 -1
- package/build/files/ApplicationCCsFile.js.map +0 -1
- package/build/files/ApplicationDataFile.d.ts.map +0 -1
- package/build/files/ApplicationDataFile.js.map +0 -1
- package/build/files/ApplicationNameFile.d.ts.map +0 -1
- package/build/files/ApplicationNameFile.js.map +0 -1
- package/build/files/ApplicationRFConfigFile.d.ts.map +0 -1
- package/build/files/ApplicationRFConfigFile.js.map +0 -1
- package/build/files/ApplicationTypeFile.d.ts.map +0 -1
- package/build/files/ApplicationTypeFile.js.map +0 -1
- package/build/files/ControllerInfoFile.d.ts.map +0 -1
- package/build/files/ControllerInfoFile.js.map +0 -1
- package/build/files/NVMFile.d.ts.map +0 -1
- package/build/files/NVMFile.js.map +0 -1
- package/build/files/NodeInfoFiles.d.ts.map +0 -1
- package/build/files/NodeInfoFiles.js.map +0 -1
- package/build/files/ProtocolNodeMaskFiles.d.ts.map +0 -1
- package/build/files/ProtocolNodeMaskFiles.js.map +0 -1
- package/build/files/RouteCacheFiles.d.ts.map +0 -1
- package/build/files/RouteCacheFiles.js.map +0 -1
- package/build/files/SUCUpdateEntriesFile.d.ts.map +0 -1
- package/build/files/SUCUpdateEntriesFile.js.map +0 -1
- package/build/files/VersionFiles.d.ts.map +0 -1
- package/build/files/VersionFiles.js.map +0 -1
- package/build/files/index.d.ts.map +0 -1
- package/build/files/index.js.map +0 -1
- package/build/nvm3/consts.d.ts.map +0 -1
- package/build/nvm3/consts.js.map +0 -1
- package/build/nvm3/nvm.d.ts +0 -31
- package/build/nvm3/nvm.d.ts.map +0 -1
- package/build/nvm3/nvm.js +0 -184
- package/build/nvm3/nvm.js.map +0 -1
- package/build/nvm3/object.d.ts +0 -25
- package/build/nvm3/object.d.ts.map +0 -1
- package/build/nvm3/object.js +0 -197
- package/build/nvm3/object.js.map +0 -1
- package/build/nvm3/page.d.ts.map +0 -1
- package/build/nvm3/page.js +0 -129
- package/build/nvm3/page.js.map +0 -1
- package/build/nvm3/utils.d.ts.map +0 -1
- package/build/nvm3/utils.js +0 -103
- package/build/nvm3/utils.js.map +0 -1
- package/build/nvm500/EntryParsers.d.ts.map +0 -1
- package/build/nvm500/EntryParsers.js.map +0 -1
- package/build/nvm500/parsers/Bridge_6_6x.d.ts +0 -3
- package/build/nvm500/parsers/Bridge_6_6x.d.ts.map +0 -1
- package/build/nvm500/parsers/Bridge_6_6x.js.map +0 -1
- package/build/nvm500/parsers/Bridge_6_7x.d.ts +0 -3
- package/build/nvm500/parsers/Bridge_6_7x.d.ts.map +0 -1
- package/build/nvm500/parsers/Bridge_6_7x.js.map +0 -1
- package/build/nvm500/parsers/Bridge_6_8x.d.ts +0 -3
- package/build/nvm500/parsers/Bridge_6_8x.d.ts.map +0 -1
- package/build/nvm500/parsers/Bridge_6_8x.js.map +0 -1
- package/build/nvm500/parsers/Static_6_6x.d.ts +0 -3
- package/build/nvm500/parsers/Static_6_6x.d.ts.map +0 -1
- package/build/nvm500/parsers/Static_6_6x.js.map +0 -1
- package/build/nvm500/parsers/Static_6_7x.d.ts +0 -3
- package/build/nvm500/parsers/Static_6_7x.d.ts.map +0 -1
- package/build/nvm500/parsers/Static_6_7x.js.map +0 -1
- package/build/nvm500/parsers/Static_6_8x.d.ts +0 -3
- package/build/nvm500/parsers/Static_6_8x.d.ts.map +0 -1
- package/build/nvm500/parsers/Static_6_8x.js.map +0 -1
- package/build/nvm500/shared.d.ts.map +0 -1
- package/build/nvm500/shared.js.map +0 -1
- package/build/shared.d.ts +0 -2
- package/build/shared.d.ts.map +0 -1
- package/build/shared.js +0 -3
- package/build/shared.js.map +0 -1
- /package/build/{nvm3 → lib/nvm3}/consts.d.ts +0 -0
- /package/build/{nvm3 → lib/nvm3}/consts.js +0 -0
- /package/build/{nvm500 → lib/nvm500}/EntryParsers.d.ts +0 -0
- /package/build/{nvm500 → lib/nvm500}/EntryParsers.js +0 -0
|
@@ -0,0 +1,903 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NVM3Adapter = void 0;
|
|
4
|
+
const core_1 = require("@zwave-js/core");
|
|
5
|
+
const shared_1 = require("@zwave-js/shared");
|
|
6
|
+
const helpers_1 = require("alcalzone-shared/helpers");
|
|
7
|
+
const consts_1 = require("../../consts");
|
|
8
|
+
const files_1 = require("./files");
|
|
9
|
+
const DEFAULT_FILE_VERSION = "7.0.0";
|
|
10
|
+
class NVM3Adapter {
|
|
11
|
+
constructor(nvm) {
|
|
12
|
+
this._nvm = nvm;
|
|
13
|
+
}
|
|
14
|
+
_nvm;
|
|
15
|
+
_initialized = false;
|
|
16
|
+
_protocolInfo;
|
|
17
|
+
_applicationInfo;
|
|
18
|
+
/** A list of pending changes that haven't been written to the NVM yet. `null` indicates a deleted entry. */
|
|
19
|
+
_pendingChanges = new Map();
|
|
20
|
+
getFileVersion(fileId) {
|
|
21
|
+
if (fileId === files_1.ProtocolVersionFileID
|
|
22
|
+
|| fileId === files_1.ApplicationVersionFileID
|
|
23
|
+
|| fileId === files_1.ApplicationVersionFile800ID) {
|
|
24
|
+
return DEFAULT_FILE_VERSION;
|
|
25
|
+
}
|
|
26
|
+
const section = (0, files_1.getNVMSectionByFileID)(fileId);
|
|
27
|
+
if (section === "application") {
|
|
28
|
+
return this._applicationInfo?.version ?? DEFAULT_FILE_VERSION;
|
|
29
|
+
}
|
|
30
|
+
else if (section === "protocol") {
|
|
31
|
+
return this._protocolInfo?.version ?? DEFAULT_FILE_VERSION;
|
|
32
|
+
}
|
|
33
|
+
return DEFAULT_FILE_VERSION;
|
|
34
|
+
}
|
|
35
|
+
async init() {
|
|
36
|
+
if (!this._protocolInfo) {
|
|
37
|
+
const protocolVersionFile = await this._getFile(files_1.ProtocolVersionFileID, true);
|
|
38
|
+
if (protocolVersionFile) {
|
|
39
|
+
const version = `${protocolVersionFile.major}.${protocolVersionFile.minor}.${protocolVersionFile.patch}`;
|
|
40
|
+
this._protocolInfo = {
|
|
41
|
+
version,
|
|
42
|
+
format: protocolVersionFile.format,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!this._applicationInfo) {
|
|
47
|
+
const applicationVersionFile700 = await this._getFile(files_1.ApplicationVersionFileID, true);
|
|
48
|
+
const applicationVersionFile800 = await this._getFile(files_1.ApplicationVersionFile800ID, true);
|
|
49
|
+
const applicationVersionFile = applicationVersionFile700
|
|
50
|
+
?? applicationVersionFile800;
|
|
51
|
+
if (applicationVersionFile) {
|
|
52
|
+
const version = `${applicationVersionFile.major}.${applicationVersionFile.minor}.${applicationVersionFile.patch}`;
|
|
53
|
+
this._applicationInfo = {
|
|
54
|
+
version,
|
|
55
|
+
format: applicationVersionFile.format,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
this._initialized = true;
|
|
60
|
+
}
|
|
61
|
+
/** Adds a complete file to the list of pending changes */
|
|
62
|
+
setFile(file) {
|
|
63
|
+
const { key, data } = file.serialize();
|
|
64
|
+
this._pendingChanges.set(key, data);
|
|
65
|
+
}
|
|
66
|
+
async hasFile(fileId) {
|
|
67
|
+
if (!this._initialized)
|
|
68
|
+
await this.init();
|
|
69
|
+
if (this._pendingChanges.has(fileId)) {
|
|
70
|
+
return this._pendingChanges.get(fileId) !== null;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
return this._nvm.has(fileId);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async _getFile(fileId, skipInit = false) {
|
|
77
|
+
if (!skipInit && !this._initialized)
|
|
78
|
+
await this.init();
|
|
79
|
+
// Prefer pending changes over the actual NVM, so changes can be composed
|
|
80
|
+
let data;
|
|
81
|
+
if (this._pendingChanges.has(fileId)) {
|
|
82
|
+
data = this._pendingChanges.get(fileId);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
data = await this._nvm.get(fileId);
|
|
86
|
+
}
|
|
87
|
+
if (!data)
|
|
88
|
+
return;
|
|
89
|
+
const fileVersion = this.getFileVersion(fileId);
|
|
90
|
+
return files_1.NVMFile.from(fileId, data, fileVersion);
|
|
91
|
+
}
|
|
92
|
+
async _expectFile(fileId, skipInit = false) {
|
|
93
|
+
const file = await this._getFile(fileId, skipInit);
|
|
94
|
+
if (!file) {
|
|
95
|
+
throw new core_1.ZWaveError(`NVM file ${(0, shared_1.num2hex)(fileId)} not found`, core_1.ZWaveErrorCodes.NVM_ObjectNotFound);
|
|
96
|
+
}
|
|
97
|
+
return file;
|
|
98
|
+
}
|
|
99
|
+
getFile(fileId, required) {
|
|
100
|
+
if (required) {
|
|
101
|
+
return this._expectFile(fileId);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
return this._getFile(fileId);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
get(property, required) {
|
|
108
|
+
if (property.domain === "controller") {
|
|
109
|
+
return this.getControllerNVMProperty(property, !!required);
|
|
110
|
+
}
|
|
111
|
+
else if (property.domain === "lrnode") {
|
|
112
|
+
return this.getLRNodeNVMProperty(property, !!required);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
return this.getNodeNVMProperty(property, !!required);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async getControllerNVMProperty(property, required) {
|
|
119
|
+
const getFile = (fileId) => {
|
|
120
|
+
if (required) {
|
|
121
|
+
return this._expectFile(fileId);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return this._getFile(fileId);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
switch (property.type) {
|
|
128
|
+
case "protocolVersion": {
|
|
129
|
+
const file = await getFile(files_1.ProtocolVersionFileID);
|
|
130
|
+
if (!file)
|
|
131
|
+
return;
|
|
132
|
+
return `${file.major}.${file.minor}.${file.patch}`;
|
|
133
|
+
}
|
|
134
|
+
case "protocolFileFormat": {
|
|
135
|
+
const file = await getFile(files_1.ProtocolVersionFileID);
|
|
136
|
+
return file?.format;
|
|
137
|
+
}
|
|
138
|
+
case "applicationVersion":
|
|
139
|
+
case "applicationFileFormat": {
|
|
140
|
+
const file700 = await this._getFile(files_1.ApplicationVersionFileID);
|
|
141
|
+
const file800 = await this._getFile(files_1.ApplicationVersionFile800ID);
|
|
142
|
+
const file = file700 ?? file800;
|
|
143
|
+
if (!file) {
|
|
144
|
+
if (required) {
|
|
145
|
+
throw new core_1.ZWaveError("ApplicationVersionFile not found!", core_1.ZWaveErrorCodes.NVM_ObjectNotFound);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (property.type === "applicationVersion") {
|
|
152
|
+
return `${file.major}.${file.minor}.${file.patch}`;
|
|
153
|
+
}
|
|
154
|
+
else if (property.type === "applicationFileFormat") {
|
|
155
|
+
return file?.format;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
case "applicationData": {
|
|
159
|
+
const file = await getFile(files_1.ApplicationDataFileID);
|
|
160
|
+
return file?.applicationData;
|
|
161
|
+
}
|
|
162
|
+
case "applicationName": {
|
|
163
|
+
const file = await getFile(files_1.ApplicationNameFileID);
|
|
164
|
+
return file?.name;
|
|
165
|
+
}
|
|
166
|
+
case "homeId":
|
|
167
|
+
case "nodeId":
|
|
168
|
+
case "lastNodeId":
|
|
169
|
+
case "staticControllerNodeId":
|
|
170
|
+
case "sucLastIndex":
|
|
171
|
+
case "controllerConfiguration":
|
|
172
|
+
case "sucAwarenessPushNeeded":
|
|
173
|
+
case "maxNodeId":
|
|
174
|
+
case "reservedId":
|
|
175
|
+
case "systemState":
|
|
176
|
+
case "lastNodeIdLR":
|
|
177
|
+
case "maxNodeIdLR":
|
|
178
|
+
case "reservedIdLR":
|
|
179
|
+
case "primaryLongRangeChannelId":
|
|
180
|
+
case "dcdcConfig": {
|
|
181
|
+
const file = await getFile(files_1.ControllerInfoFileID);
|
|
182
|
+
return file?.[property.type];
|
|
183
|
+
}
|
|
184
|
+
case "includedInsecurely":
|
|
185
|
+
case "includedSecurelyInsecureCCs":
|
|
186
|
+
case "includedSecurelySecureCCs": {
|
|
187
|
+
const file = await getFile(files_1.ApplicationCCsFileID);
|
|
188
|
+
return file?.[property.type];
|
|
189
|
+
}
|
|
190
|
+
case "rfRegion":
|
|
191
|
+
case "txPower":
|
|
192
|
+
case "measured0dBm":
|
|
193
|
+
case "enablePTI":
|
|
194
|
+
case "maxTXPower":
|
|
195
|
+
case "nodeIdType": {
|
|
196
|
+
const file = await getFile(files_1.ApplicationRFConfigFileID);
|
|
197
|
+
return file?.[property.type];
|
|
198
|
+
}
|
|
199
|
+
case "isListening":
|
|
200
|
+
case "optionalFunctionality":
|
|
201
|
+
case "genericDeviceClass":
|
|
202
|
+
case "specificDeviceClass": {
|
|
203
|
+
const file = await getFile(files_1.ApplicationTypeFileID);
|
|
204
|
+
return file?.[property.type];
|
|
205
|
+
}
|
|
206
|
+
case "preferredRepeaters": {
|
|
207
|
+
const file = await getFile(files_1.ProtocolPreferredRepeatersFileID);
|
|
208
|
+
return file?.nodeIds;
|
|
209
|
+
}
|
|
210
|
+
case "appRouteLock": {
|
|
211
|
+
const file = await getFile(files_1.ProtocolAppRouteLockNodeMaskFileID);
|
|
212
|
+
return file?.nodeIds;
|
|
213
|
+
}
|
|
214
|
+
case "routeSlaveSUC": {
|
|
215
|
+
const file = await getFile(files_1.ProtocolRouteSlaveSUCNodeMaskFileID);
|
|
216
|
+
return file?.nodeIds;
|
|
217
|
+
}
|
|
218
|
+
case "sucPendingUpdate": {
|
|
219
|
+
const file = await getFile(files_1.ProtocolSUCPendingUpdateNodeMaskFileID);
|
|
220
|
+
return file?.nodeIds;
|
|
221
|
+
}
|
|
222
|
+
case "pendingDiscovery": {
|
|
223
|
+
const file = await getFile(files_1.ProtocolPendingDiscoveryNodeMaskFileID);
|
|
224
|
+
return file?.nodeIds;
|
|
225
|
+
}
|
|
226
|
+
case "nodeIds": {
|
|
227
|
+
const file = await getFile(files_1.ProtocolNodeListFileID);
|
|
228
|
+
return file?.nodeIds;
|
|
229
|
+
}
|
|
230
|
+
case "lrNodeIds": {
|
|
231
|
+
const file = await getFile(files_1.ProtocolLRNodeListFileID);
|
|
232
|
+
return file?.nodeIds;
|
|
233
|
+
}
|
|
234
|
+
case "virtualNodeIds": {
|
|
235
|
+
const file = await getFile(files_1.ProtocolVirtualNodeMaskFileID);
|
|
236
|
+
return file?.nodeIds;
|
|
237
|
+
}
|
|
238
|
+
case "sucUpdateEntries": {
|
|
239
|
+
if (this._protocolInfo.format < 5) {
|
|
240
|
+
const file = await getFile(files_1.SUCUpdateEntriesFileIDV0);
|
|
241
|
+
return file?.updateEntries;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// V5 has split the entries into multiple files
|
|
245
|
+
const updateEntries = [];
|
|
246
|
+
for (let index = 0; index < consts_1.SUC_MAX_UPDATES; index += files_1.SUC_UPDATES_PER_FILE_V5) {
|
|
247
|
+
// None of the files are required
|
|
248
|
+
const file = await this._getFile((0, files_1.sucUpdateIndexToSUCUpdateEntriesFileIDV5)(index));
|
|
249
|
+
if (!file)
|
|
250
|
+
break;
|
|
251
|
+
updateEntries.push(...file.updateEntries);
|
|
252
|
+
}
|
|
253
|
+
return updateEntries;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
case "learnedHomeId":
|
|
257
|
+
case "commandClasses":
|
|
258
|
+
case "watchdogStarted":
|
|
259
|
+
case "powerLevelNormal":
|
|
260
|
+
case "powerLevelLow":
|
|
261
|
+
case "powerMode":
|
|
262
|
+
case "powerModeExtintEnable":
|
|
263
|
+
case "powerModeWutTimeout":
|
|
264
|
+
// 500 series only, not supported on 700+
|
|
265
|
+
return;
|
|
266
|
+
default:
|
|
267
|
+
(0, helpers_1.assertNever)(property.type);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async getNodeNVMProperty(property, required) {
|
|
271
|
+
const getFile = (fileId) => {
|
|
272
|
+
if (required) {
|
|
273
|
+
return this._expectFile(fileId);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
return this._getFile(fileId);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
switch (property.type) {
|
|
280
|
+
case "info": {
|
|
281
|
+
if (this._protocolInfo.format < 1) {
|
|
282
|
+
const file = await getFile((0, files_1.nodeIdToNodeInfoFileIDV0)(property.nodeId));
|
|
283
|
+
return file?.nodeInfo;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
const file = await getFile((0, files_1.nodeIdToNodeInfoFileIDV1)(property.nodeId));
|
|
287
|
+
return file?.nodeInfos.find((info) => info.nodeId === property.nodeId);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
case "routes": {
|
|
291
|
+
// The existence of routes is stored separately
|
|
292
|
+
const nodeMaskFile = await this.getFile(files_1.ProtocolRouteCacheExistsNodeMaskFileID);
|
|
293
|
+
// If the node is not marked as having routes, don't try to read them
|
|
294
|
+
if (!nodeMaskFile)
|
|
295
|
+
return;
|
|
296
|
+
if (!nodeMaskFile.nodeIdSet.has(property.nodeId))
|
|
297
|
+
return;
|
|
298
|
+
let routeCache;
|
|
299
|
+
if (this._protocolInfo.format < 1) {
|
|
300
|
+
const file = await getFile((0, files_1.nodeIdToRouteCacheFileIDV0)(property.nodeId));
|
|
301
|
+
routeCache = file?.routeCache;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
const file = await getFile((0, files_1.nodeIdToRouteCacheFileIDV1)(property.nodeId));
|
|
305
|
+
routeCache = file?.routeCaches.find((route) => route.nodeId === property.nodeId);
|
|
306
|
+
}
|
|
307
|
+
if (!routeCache)
|
|
308
|
+
return;
|
|
309
|
+
return {
|
|
310
|
+
lwr: routeCache.lwr,
|
|
311
|
+
nlwr: routeCache.nlwr,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
default:
|
|
315
|
+
(0, helpers_1.assertNever)(property.type);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async getLRNodeNVMProperty(property, required) {
|
|
319
|
+
const getFile = (fileId) => {
|
|
320
|
+
if (required) {
|
|
321
|
+
return this._expectFile(fileId);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
return this._getFile(fileId);
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
switch (property.type) {
|
|
328
|
+
case "info": {
|
|
329
|
+
const file = await getFile((0, files_1.nodeIdToLRNodeInfoFileIDV5)(property.nodeId));
|
|
330
|
+
return file?.nodeInfos.find((info) => info.nodeId === property.nodeId);
|
|
331
|
+
}
|
|
332
|
+
default:
|
|
333
|
+
(0, helpers_1.assertNever)(property.type);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async set(property, value) {
|
|
337
|
+
if (!this._initialized)
|
|
338
|
+
await this.init();
|
|
339
|
+
if (property.domain === "controller") {
|
|
340
|
+
return this.setControllerNVMProperty(property, value);
|
|
341
|
+
}
|
|
342
|
+
else if (property.domain === "lrnode") {
|
|
343
|
+
return this.setLRNodeNVMProperty(property, value);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
return this.setNodeNVMProperty(property, value);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
async setControllerNVMProperty(property, value) {
|
|
350
|
+
const failFileMissing = () => {
|
|
351
|
+
throw new core_1.ZWaveError("Cannot set property in NVM for non-existing file", core_1.ZWaveErrorCodes.NVM_ObjectNotFound);
|
|
352
|
+
};
|
|
353
|
+
const expectFile = async (fileId) => {
|
|
354
|
+
const file = await this._getFile(fileId);
|
|
355
|
+
if (!file)
|
|
356
|
+
throw failFileMissing();
|
|
357
|
+
return file;
|
|
358
|
+
};
|
|
359
|
+
const changedFiles = [];
|
|
360
|
+
const deletedFiles = [];
|
|
361
|
+
switch (property.type) {
|
|
362
|
+
case "protocolVersion": {
|
|
363
|
+
const file = await expectFile(files_1.ProtocolVersionFileID);
|
|
364
|
+
const [major, minor, patch] = value.split(".")
|
|
365
|
+
.map((part) => parseInt(part, 10));
|
|
366
|
+
file.major = major;
|
|
367
|
+
file.minor = minor;
|
|
368
|
+
file.patch = patch;
|
|
369
|
+
changedFiles.push(file);
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
case "protocolFileFormat": {
|
|
373
|
+
const file = await expectFile(files_1.ProtocolVersionFileID);
|
|
374
|
+
file.format = value;
|
|
375
|
+
changedFiles.push(file);
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
case "applicationVersion": {
|
|
379
|
+
const file700 = await this._getFile(files_1.ApplicationVersionFileID);
|
|
380
|
+
const file800 = await this._getFile(files_1.ApplicationVersionFile800ID);
|
|
381
|
+
const file = file700 ?? file800;
|
|
382
|
+
if (!file) {
|
|
383
|
+
throw new core_1.ZWaveError("ApplicationVersionFile not found!", core_1.ZWaveErrorCodes.NVM_ObjectNotFound);
|
|
384
|
+
}
|
|
385
|
+
const [major, minor, patch] = value.split(".")
|
|
386
|
+
.map((part) => parseInt(part, 10));
|
|
387
|
+
file.major = major;
|
|
388
|
+
file.minor = minor;
|
|
389
|
+
file.patch = patch;
|
|
390
|
+
changedFiles.push(file);
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
case "applicationFileFormat": {
|
|
394
|
+
const file = await expectFile(files_1.ApplicationVersionFileID);
|
|
395
|
+
file.format = value;
|
|
396
|
+
changedFiles.push(file);
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
case "applicationData": {
|
|
400
|
+
const file = new files_1.ApplicationDataFile({
|
|
401
|
+
applicationData: value,
|
|
402
|
+
fileVersion: this.getFileVersion(files_1.ApplicationDataFileID),
|
|
403
|
+
});
|
|
404
|
+
file.applicationData = value;
|
|
405
|
+
changedFiles.push(file);
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
case "applicationName": {
|
|
409
|
+
const file = new files_1.ApplicationNameFile({
|
|
410
|
+
name: value,
|
|
411
|
+
fileVersion: this.getFileVersion(files_1.ApplicationNameFileID),
|
|
412
|
+
});
|
|
413
|
+
changedFiles.push(file);
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
case "homeId":
|
|
417
|
+
case "nodeId":
|
|
418
|
+
case "lastNodeId":
|
|
419
|
+
case "staticControllerNodeId":
|
|
420
|
+
case "sucLastIndex":
|
|
421
|
+
case "controllerConfiguration":
|
|
422
|
+
case "sucAwarenessPushNeeded":
|
|
423
|
+
case "maxNodeId":
|
|
424
|
+
case "reservedId":
|
|
425
|
+
case "systemState":
|
|
426
|
+
case "lastNodeIdLR":
|
|
427
|
+
case "maxNodeIdLR":
|
|
428
|
+
case "reservedIdLR":
|
|
429
|
+
case "primaryLongRangeChannelId":
|
|
430
|
+
case "dcdcConfig": {
|
|
431
|
+
const file = await expectFile(files_1.ControllerInfoFileID);
|
|
432
|
+
file[property.type] = value;
|
|
433
|
+
changedFiles.push(file);
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
case "includedInsecurely":
|
|
437
|
+
case "includedSecurelyInsecureCCs":
|
|
438
|
+
case "includedSecurelySecureCCs": {
|
|
439
|
+
const file = await expectFile(files_1.ApplicationCCsFileID);
|
|
440
|
+
file[property.type] = value;
|
|
441
|
+
changedFiles.push(file);
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
case "rfRegion":
|
|
445
|
+
case "txPower":
|
|
446
|
+
case "measured0dBm":
|
|
447
|
+
case "enablePTI":
|
|
448
|
+
case "maxTXPower":
|
|
449
|
+
case "nodeIdType": {
|
|
450
|
+
const file = await expectFile(files_1.ApplicationRFConfigFileID);
|
|
451
|
+
file[property.type] = value;
|
|
452
|
+
changedFiles.push(file);
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
case "isListening":
|
|
456
|
+
case "optionalFunctionality":
|
|
457
|
+
case "genericDeviceClass":
|
|
458
|
+
case "specificDeviceClass": {
|
|
459
|
+
const file = await expectFile(files_1.ApplicationTypeFileID);
|
|
460
|
+
file[property.type] = value;
|
|
461
|
+
changedFiles.push(file);
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
case "nodeIds": {
|
|
465
|
+
const file = await this._getFile(files_1.ProtocolNodeListFileID) ?? new files_1.ProtocolNodeListFile({
|
|
466
|
+
nodeIds: [],
|
|
467
|
+
fileVersion: this.getFileVersion(files_1.ProtocolNodeListFileID),
|
|
468
|
+
});
|
|
469
|
+
file.nodeIds = value;
|
|
470
|
+
changedFiles.push(file);
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
case "lrNodeIds": {
|
|
474
|
+
const file = await this._getFile(files_1.ProtocolLRNodeListFileID) ?? new files_1.ProtocolLRNodeListFile({
|
|
475
|
+
nodeIds: [],
|
|
476
|
+
fileVersion: this.getFileVersion(files_1.ProtocolLRNodeListFileID),
|
|
477
|
+
});
|
|
478
|
+
file.nodeIds = value;
|
|
479
|
+
changedFiles.push(file);
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
case "virtualNodeIds": {
|
|
483
|
+
const file = await this._getFile(files_1.ProtocolVirtualNodeMaskFileID) ?? new files_1.ProtocolVirtualNodeMaskFile({
|
|
484
|
+
nodeIds: [],
|
|
485
|
+
fileVersion: this.getFileVersion(files_1.ProtocolVirtualNodeMaskFileID),
|
|
486
|
+
});
|
|
487
|
+
file.nodeIds = value;
|
|
488
|
+
changedFiles.push(file);
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
case "preferredRepeaters": {
|
|
492
|
+
const file = new files_1.ProtocolPreferredRepeatersFile({
|
|
493
|
+
nodeIds: value,
|
|
494
|
+
fileVersion: this.getFileVersion(files_1.ProtocolPreferredRepeatersFileID),
|
|
495
|
+
});
|
|
496
|
+
changedFiles.push(file);
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
case "appRouteLock": {
|
|
500
|
+
const file = new files_1.ProtocolAppRouteLockNodeMaskFile({
|
|
501
|
+
nodeIds: value,
|
|
502
|
+
fileVersion: this.getFileVersion(files_1.ProtocolAppRouteLockNodeMaskFileID),
|
|
503
|
+
});
|
|
504
|
+
changedFiles.push(file);
|
|
505
|
+
break;
|
|
506
|
+
}
|
|
507
|
+
case "routeSlaveSUC": {
|
|
508
|
+
const file = new files_1.ProtocolRouteSlaveSUCNodeMaskFile({
|
|
509
|
+
nodeIds: value,
|
|
510
|
+
fileVersion: this.getFileVersion(files_1.ProtocolRouteSlaveSUCNodeMaskFileID),
|
|
511
|
+
});
|
|
512
|
+
changedFiles.push(file);
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
case "sucPendingUpdate": {
|
|
516
|
+
const file = new files_1.ProtocolSUCPendingUpdateNodeMaskFile({
|
|
517
|
+
nodeIds: value,
|
|
518
|
+
fileVersion: this.getFileVersion(files_1.ProtocolSUCPendingUpdateNodeMaskFileID),
|
|
519
|
+
});
|
|
520
|
+
changedFiles.push(file);
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
523
|
+
case "pendingDiscovery": {
|
|
524
|
+
const file = new files_1.ProtocolPendingDiscoveryNodeMaskFile({
|
|
525
|
+
nodeIds: value,
|
|
526
|
+
fileVersion: this.getFileVersion(files_1.ProtocolPendingDiscoveryNodeMaskFileID),
|
|
527
|
+
});
|
|
528
|
+
changedFiles.push(file);
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
case "sucUpdateEntries": {
|
|
532
|
+
if (this._protocolInfo.format < 5) {
|
|
533
|
+
const file = new files_1.SUCUpdateEntriesFileV0({
|
|
534
|
+
updateEntries: value,
|
|
535
|
+
fileVersion: this.getFileVersion(files_1.SUCUpdateEntriesFileIDV0),
|
|
536
|
+
});
|
|
537
|
+
changedFiles.push(file);
|
|
538
|
+
break;
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
// V5 has split the entries into multiple files
|
|
542
|
+
for (let index = 0; index < consts_1.SUC_MAX_UPDATES; index += files_1.SUC_UPDATES_PER_FILE_V5) {
|
|
543
|
+
const fileId = (0, files_1.sucUpdateIndexToSUCUpdateEntriesFileIDV5)(index);
|
|
544
|
+
const fileExists = await this.hasFile(fileId);
|
|
545
|
+
const fileVersion = this.getFileVersion(fileId);
|
|
546
|
+
const slice = value.slice(index, index + files_1.SUC_UPDATES_PER_FILE_V5);
|
|
547
|
+
if (slice.length > 0) {
|
|
548
|
+
const file = new files_1.SUCUpdateEntriesFileV5({
|
|
549
|
+
updateEntries: slice,
|
|
550
|
+
fileVersion,
|
|
551
|
+
});
|
|
552
|
+
changedFiles.push(file);
|
|
553
|
+
}
|
|
554
|
+
else if (fileExists) {
|
|
555
|
+
deletedFiles.push(fileId);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
break;
|
|
560
|
+
}
|
|
561
|
+
case "learnedHomeId":
|
|
562
|
+
case "commandClasses":
|
|
563
|
+
case "watchdogStarted":
|
|
564
|
+
case "powerLevelNormal":
|
|
565
|
+
case "powerLevelLow":
|
|
566
|
+
case "powerMode":
|
|
567
|
+
case "powerModeExtintEnable":
|
|
568
|
+
case "powerModeWutTimeout":
|
|
569
|
+
// 500 series only, not supported on 700+
|
|
570
|
+
return;
|
|
571
|
+
default:
|
|
572
|
+
(0, helpers_1.assertNever)(property.type);
|
|
573
|
+
}
|
|
574
|
+
for (const file of changedFiles) {
|
|
575
|
+
const { key, data } = file.serialize();
|
|
576
|
+
this._pendingChanges.set(key, data);
|
|
577
|
+
}
|
|
578
|
+
for (const file of deletedFiles) {
|
|
579
|
+
this._pendingChanges.set(file, null);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
async setLRNodeNVMProperty(property, value) {
|
|
583
|
+
const changedFiles = [];
|
|
584
|
+
const deletedFiles = [];
|
|
585
|
+
switch (property.type) {
|
|
586
|
+
case "info": {
|
|
587
|
+
const fileId = (0, files_1.nodeIdToLRNodeInfoFileIDV5)(property.nodeId);
|
|
588
|
+
let file = await this._getFile(fileId);
|
|
589
|
+
if (value) {
|
|
590
|
+
// Info added or modified
|
|
591
|
+
file ??= new files_1.LRNodeInfoFileV5({
|
|
592
|
+
nodeInfos: [],
|
|
593
|
+
fileVersion: this.getFileVersion(fileId),
|
|
594
|
+
});
|
|
595
|
+
const existingIndex = file.nodeInfos.findIndex((info) => info.nodeId === property.nodeId);
|
|
596
|
+
if (existingIndex !== -1) {
|
|
597
|
+
file.nodeInfos[existingIndex] = value;
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
file.nodeInfos.push(value);
|
|
601
|
+
}
|
|
602
|
+
changedFiles.push(file);
|
|
603
|
+
}
|
|
604
|
+
else if (file) {
|
|
605
|
+
// info deleted
|
|
606
|
+
const existingIndex = file.nodeInfos.findIndex((info) => info.nodeId === property.nodeId);
|
|
607
|
+
if (existingIndex !== -1) {
|
|
608
|
+
file.nodeInfos.splice(existingIndex, 1);
|
|
609
|
+
if (file.nodeInfos.length === 0) {
|
|
610
|
+
deletedFiles.push(fileId);
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
changedFiles.push(file);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
break;
|
|
618
|
+
}
|
|
619
|
+
default:
|
|
620
|
+
(0, helpers_1.assertNever)(property.type);
|
|
621
|
+
}
|
|
622
|
+
for (const file of changedFiles) {
|
|
623
|
+
const { key, data } = file.serialize();
|
|
624
|
+
this._pendingChanges.set(key, data);
|
|
625
|
+
}
|
|
626
|
+
for (const file of deletedFiles) {
|
|
627
|
+
this._pendingChanges.set(file, null);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
async setNodeNVMProperty(property, value) {
|
|
631
|
+
const changedFiles = [];
|
|
632
|
+
const deletedFiles = [];
|
|
633
|
+
switch (property.type) {
|
|
634
|
+
case "info": {
|
|
635
|
+
if (this._protocolInfo.format < 1) {
|
|
636
|
+
// V0, single node info per file
|
|
637
|
+
const fileId = (0, files_1.nodeIdToNodeInfoFileIDV0)(property.nodeId);
|
|
638
|
+
let file = await this._getFile(fileId);
|
|
639
|
+
if (value) {
|
|
640
|
+
// Info added or modified
|
|
641
|
+
file ??= new files_1.NodeInfoFileV0({
|
|
642
|
+
nodeInfo: undefined,
|
|
643
|
+
fileVersion: this.getFileVersion(fileId),
|
|
644
|
+
});
|
|
645
|
+
file.nodeInfo = value;
|
|
646
|
+
changedFiles.push(file);
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
// info deleted
|
|
650
|
+
deletedFiles.push(fileId);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
// V1+, multiple node infos per file
|
|
655
|
+
const fileId = (0, files_1.nodeIdToNodeInfoFileIDV1)(property.nodeId);
|
|
656
|
+
let file = await this._getFile(fileId);
|
|
657
|
+
if (value) {
|
|
658
|
+
// Info added or modified
|
|
659
|
+
file ??= new files_1.NodeInfoFileV1({
|
|
660
|
+
nodeInfos: [],
|
|
661
|
+
fileVersion: this.getFileVersion(fileId),
|
|
662
|
+
});
|
|
663
|
+
const existingIndex = file.nodeInfos.findIndex((info) => info.nodeId === property.nodeId);
|
|
664
|
+
if (existingIndex !== -1) {
|
|
665
|
+
file.nodeInfos[existingIndex] = value;
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
file.nodeInfos.push(value);
|
|
669
|
+
}
|
|
670
|
+
changedFiles.push(file);
|
|
671
|
+
}
|
|
672
|
+
else if (file) {
|
|
673
|
+
// info deleted
|
|
674
|
+
const existingIndex = file.nodeInfos.findIndex((info) => info.nodeId === property.nodeId);
|
|
675
|
+
if (existingIndex !== -1) {
|
|
676
|
+
file.nodeInfos.splice(existingIndex, 1);
|
|
677
|
+
if (file.nodeInfos.length === 0) {
|
|
678
|
+
deletedFiles.push(fileId);
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
changedFiles.push(file);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
688
|
+
case "routes": {
|
|
689
|
+
if (this._protocolInfo.format < 1) {
|
|
690
|
+
// V0, single route per file
|
|
691
|
+
const fileId = (0, files_1.nodeIdToRouteCacheFileIDV0)(property.nodeId);
|
|
692
|
+
let file = await this._getFile(fileId);
|
|
693
|
+
if (value) {
|
|
694
|
+
// Route added or modified
|
|
695
|
+
file ??= new files_1.RouteCacheFileV0({
|
|
696
|
+
routeCache: undefined,
|
|
697
|
+
fileVersion: this.getFileVersion(fileId),
|
|
698
|
+
});
|
|
699
|
+
file.routeCache = {
|
|
700
|
+
nodeId: property.nodeId,
|
|
701
|
+
lwr: value.lwr,
|
|
702
|
+
nlwr: value.nlwr,
|
|
703
|
+
};
|
|
704
|
+
changedFiles.push(file);
|
|
705
|
+
}
|
|
706
|
+
else if (file) {
|
|
707
|
+
// Route deleted
|
|
708
|
+
deletedFiles.push(fileId);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
// V1+, multiple routes per file
|
|
713
|
+
const fileId = (0, files_1.nodeIdToRouteCacheFileIDV1)(property.nodeId);
|
|
714
|
+
const file = await this._getFile(fileId) ?? new files_1.RouteCacheFileV1({
|
|
715
|
+
routeCaches: [],
|
|
716
|
+
fileVersion: this.getFileVersion(fileId),
|
|
717
|
+
});
|
|
718
|
+
const existingIndex = file.routeCaches.findIndex((route) => route.nodeId === property.nodeId);
|
|
719
|
+
const newRoute = {
|
|
720
|
+
nodeId: property.nodeId,
|
|
721
|
+
lwr: value.lwr,
|
|
722
|
+
nlwr: value.nlwr,
|
|
723
|
+
};
|
|
724
|
+
if (existingIndex !== -1) {
|
|
725
|
+
file.routeCaches[existingIndex] = newRoute;
|
|
726
|
+
}
|
|
727
|
+
else {
|
|
728
|
+
file.routeCaches.push(newRoute);
|
|
729
|
+
}
|
|
730
|
+
changedFiles.push(file);
|
|
731
|
+
}
|
|
732
|
+
// The existence of routes is stored separately
|
|
733
|
+
const nodeMaskFile = await this._getFile(files_1.ProtocolRouteCacheExistsNodeMaskFileID)
|
|
734
|
+
?? new files_1.ProtocolRouteCacheExistsNodeMaskFile({
|
|
735
|
+
nodeIds: [],
|
|
736
|
+
fileVersion: this.getFileVersion(files_1.ProtocolRouteCacheExistsNodeMaskFileID),
|
|
737
|
+
});
|
|
738
|
+
if (!value && nodeMaskFile.nodeIdSet.has(property.nodeId)) {
|
|
739
|
+
nodeMaskFile.nodeIdSet.delete(property.nodeId);
|
|
740
|
+
changedFiles.push(nodeMaskFile);
|
|
741
|
+
}
|
|
742
|
+
else if (value && !nodeMaskFile.nodeIdSet.has(property.nodeId)) {
|
|
743
|
+
nodeMaskFile.nodeIdSet.add(property.nodeId);
|
|
744
|
+
changedFiles.push(nodeMaskFile);
|
|
745
|
+
}
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
default:
|
|
749
|
+
(0, helpers_1.assertNever)(property.type);
|
|
750
|
+
}
|
|
751
|
+
for (const file of changedFiles) {
|
|
752
|
+
const { key, data } = file.serialize();
|
|
753
|
+
this._pendingChanges.set(key, data);
|
|
754
|
+
}
|
|
755
|
+
for (const file of deletedFiles) {
|
|
756
|
+
this._pendingChanges.set(file, null);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
async delete(property) {
|
|
760
|
+
if (property.domain === "controller") {
|
|
761
|
+
switch (property.type) {
|
|
762
|
+
case "protocolVersion":
|
|
763
|
+
case "protocolFileFormat": {
|
|
764
|
+
this._pendingChanges.set(files_1.ProtocolVersionFileID, null);
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
case "applicationVersion":
|
|
768
|
+
case "applicationFileFormat": {
|
|
769
|
+
if (await this.hasFile(files_1.ApplicationVersionFileID)) {
|
|
770
|
+
this._pendingChanges.set(files_1.ApplicationVersionFileID, null);
|
|
771
|
+
}
|
|
772
|
+
if (await this.hasFile(files_1.ApplicationVersionFile800ID)) {
|
|
773
|
+
this._pendingChanges.set(files_1.ApplicationVersionFile800ID, null);
|
|
774
|
+
}
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
case "applicationData": {
|
|
778
|
+
this._pendingChanges.set(files_1.ApplicationDataFileID, null);
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
case "applicationName": {
|
|
782
|
+
this._pendingChanges.set(files_1.ApplicationNameFileID, null);
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
case "homeId":
|
|
786
|
+
case "nodeId":
|
|
787
|
+
case "lastNodeId":
|
|
788
|
+
case "staticControllerNodeId":
|
|
789
|
+
case "sucLastIndex":
|
|
790
|
+
case "controllerConfiguration":
|
|
791
|
+
case "sucAwarenessPushNeeded":
|
|
792
|
+
case "maxNodeId":
|
|
793
|
+
case "reservedId":
|
|
794
|
+
case "systemState":
|
|
795
|
+
case "lastNodeIdLR":
|
|
796
|
+
case "maxNodeIdLR":
|
|
797
|
+
case "reservedIdLR":
|
|
798
|
+
case "primaryLongRangeChannelId":
|
|
799
|
+
case "dcdcConfig": {
|
|
800
|
+
this._pendingChanges.set(files_1.ControllerInfoFileID, null);
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
case "includedInsecurely":
|
|
804
|
+
case "includedSecurelyInsecureCCs":
|
|
805
|
+
case "includedSecurelySecureCCs": {
|
|
806
|
+
this._pendingChanges.set(files_1.ApplicationCCsFileID, null);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
case "rfRegion":
|
|
810
|
+
case "txPower":
|
|
811
|
+
case "measured0dBm":
|
|
812
|
+
case "enablePTI":
|
|
813
|
+
case "maxTXPower":
|
|
814
|
+
case "nodeIdType": {
|
|
815
|
+
this._pendingChanges.set(files_1.ApplicationRFConfigFileID, null);
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
case "isListening":
|
|
819
|
+
case "optionalFunctionality":
|
|
820
|
+
case "genericDeviceClass":
|
|
821
|
+
case "specificDeviceClass": {
|
|
822
|
+
this._pendingChanges.set(files_1.ApplicationTypeFileID, null);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
case "nodeIds": {
|
|
826
|
+
this._pendingChanges.set(files_1.ProtocolNodeListFileID, null);
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
case "lrNodeIds": {
|
|
830
|
+
this._pendingChanges.set(files_1.ProtocolLRNodeListFileID, null);
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
case "virtualNodeIds": {
|
|
834
|
+
this._pendingChanges.set(files_1.ProtocolVirtualNodeMaskFileID, null);
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
case "preferredRepeaters": {
|
|
838
|
+
this._pendingChanges.set(files_1.ProtocolPreferredRepeatersFileID, null);
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
case "appRouteLock": {
|
|
842
|
+
this._pendingChanges.set(files_1.ProtocolAppRouteLockNodeMaskFileID, null);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
case "routeSlaveSUC": {
|
|
846
|
+
this._pendingChanges.set(files_1.ProtocolRouteSlaveSUCNodeMaskFileID, null);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
case "sucPendingUpdate": {
|
|
850
|
+
this._pendingChanges.set(files_1.ProtocolSUCPendingUpdateNodeMaskFileID, null);
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
case "pendingDiscovery": {
|
|
854
|
+
this._pendingChanges.set(files_1.ProtocolPendingDiscoveryNodeMaskFileID, null);
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
case "sucUpdateEntries": {
|
|
858
|
+
if (this._protocolInfo.format < 5) {
|
|
859
|
+
this._pendingChanges.set(files_1.SUCUpdateEntriesFileIDV0, null);
|
|
860
|
+
}
|
|
861
|
+
else {
|
|
862
|
+
for (let id = files_1.SUCUpdateEntriesFileV5IDBase; id <= files_1.SUCUpdateEntriesFileV5IDMax; id++) {
|
|
863
|
+
if (await this.hasFile(id)) {
|
|
864
|
+
this._pendingChanges.set(id, null);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
case "learnedHomeId":
|
|
871
|
+
case "commandClasses":
|
|
872
|
+
case "watchdogStarted":
|
|
873
|
+
case "powerLevelNormal":
|
|
874
|
+
case "powerLevelLow":
|
|
875
|
+
case "powerMode":
|
|
876
|
+
case "powerModeExtintEnable":
|
|
877
|
+
case "powerModeWutTimeout":
|
|
878
|
+
// 500 series only, not supported on 700+
|
|
879
|
+
return;
|
|
880
|
+
default:
|
|
881
|
+
(0, helpers_1.assertNever)(property);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
else if (property.domain === "lrnode") {
|
|
885
|
+
// Node properties are handled by set(..., undefined) because
|
|
886
|
+
// it requires both modifying and deleting files
|
|
887
|
+
return this.setLRNodeNVMProperty(property, undefined);
|
|
888
|
+
}
|
|
889
|
+
else if (property.domain === "node") {
|
|
890
|
+
// Node properties are handled by set(..., undefined) because
|
|
891
|
+
// it requires both modifying and deleting files
|
|
892
|
+
return this.setNodeNVMProperty(property, undefined);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
hasPendingChanges() {
|
|
896
|
+
return this._pendingChanges.size > 0;
|
|
897
|
+
}
|
|
898
|
+
async commit() {
|
|
899
|
+
await this._nvm.setMany([...this._pendingChanges]);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
exports.NVM3Adapter = NVM3Adapter;
|
|
903
|
+
//# sourceMappingURL=adapter.js.map
|