node-red-contrib-knx-ultimate 8.1.0 → 8.3.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/CHANGELOG.md +17 -0
- package/nodes/commonFunctions.js +13 -151
- package/nodes/knxUltimate-config.html +96 -158
- package/nodes/knxUltimate-config.js +64 -58
- package/nodes/knxUltimate.html +4 -0
- package/nodes/knxUltimateUtility.html +7 -0
- package/nodes/knxUltimateViewer.html +3 -0
- package/nodes/knxUltimateViewer.js +3 -1
- package/nodes/locales/de/knxUltimate-config.html +8 -5
- package/nodes/locales/de/knxUltimate-config.json +22 -20
- package/nodes/locales/de/knxUltimate.html +2 -0
- package/nodes/locales/de/knxUltimateUtility.html +6 -0
- package/nodes/locales/de/knxUltimateViewer.html +2 -0
- package/nodes/locales/en/knxUltimate-config.html +8 -5
- package/nodes/locales/en/knxUltimate-config.json +22 -20
- package/nodes/locales/en/knxUltimate.html +2 -0
- package/nodes/locales/en/knxUltimateUtility.html +6 -0
- package/nodes/locales/en/knxUltimateViewer.html +2 -0
- package/nodes/locales/es/knxUltimate-config.html +12 -6
- package/nodes/locales/es/knxUltimate-config.json +22 -20
- package/nodes/locales/es/knxUltimate.html +2 -0
- package/nodes/locales/es/knxUltimateUtility.html +6 -0
- package/nodes/locales/es/knxUltimateViewer.html +2 -0
- package/nodes/locales/fr/knxUltimate-config.html +10 -7
- package/nodes/locales/fr/knxUltimate-config.json +22 -20
- package/nodes/locales/fr/knxUltimate.html +2 -0
- package/nodes/locales/fr/knxUltimateUtility.html +6 -0
- package/nodes/locales/fr/knxUltimateViewer.html +2 -0
- package/nodes/locales/it/knxUltimate-config.html +8 -5
- package/nodes/locales/it/knxUltimate-config.json +22 -20
- package/nodes/locales/it/knxUltimate.html +2 -0
- package/nodes/locales/it/knxUltimateUtility.html +6 -0
- package/nodes/locales/it/knxUltimateViewer.html +2 -0
- package/nodes/locales/zh-CN/knxUltimate-config.html +8 -5
- package/nodes/locales/zh-CN/knxUltimate-config.json +22 -20
- package/nodes/locales/zh-CN/knxUltimate.html +2 -0
- package/nodes/locales/zh-CN/knxUltimateUtility.html +6 -0
- package/nodes/locales/zh-CN/knxUltimateViewer.html +2 -0
- package/nodes/utils/fileStorage.js +376 -0
- package/nodes/utils/knxUtilityProfiles/runtime/autoresponder.js +15 -19
- package/nodes/utils/knxUtilityProfiles/runtime/logger.js +7 -4
- package/nodes/utils/knxUtilityProfiles/runtime/scenecontroller.js +12 -44
- package/nodes/utils/knxViewerHistory.js +49 -77
- package/package.json +2 -2
- package/resources/htmlUtils.js +24 -2
|
@@ -25,6 +25,7 @@ const loggerClass = require('./utils/sysLogger')
|
|
|
25
25
|
const payloadRounder = require('./utils/payloadManipulation')
|
|
26
26
|
const utils = require('./utils/utils')
|
|
27
27
|
const dispatchWatchDogNodeError = require('./utils/watchDogErrorDispatcher')
|
|
28
|
+
const { createFileStorage } = require('./utils/fileStorage')
|
|
28
29
|
|
|
29
30
|
// Versions logged once at startup (node package + KNXUltimate engine)
|
|
30
31
|
let NODE_VERSION = 'unknown'
|
|
@@ -32,6 +33,19 @@ try { NODE_VERSION = require('../package.json').version } catch (e) { /* empty *
|
|
|
32
33
|
let KNX_ENGINE_VERSION = 'unknown'
|
|
33
34
|
try { KNX_ENGINE_VERSION = require('knxultimate/package.json').version } catch (e) { /* empty */ }
|
|
34
35
|
|
|
36
|
+
// Returns the group service of a bus telegram, or null when it is not one:
|
|
37
|
+
// transport control TPDUs (T_Connect, T_Disconnect, T_ACK, T_NAK: TPCI only, no APCI)
|
|
38
|
+
// and point-to-point telegrams (cEMI Ctrl2 address type 0 = individual destination).
|
|
39
|
+
const getGroupServiceEvent = (cEMIMessage) => {
|
|
40
|
+
const npdu = cEMIMessage?.npdu
|
|
41
|
+
if (!npdu || npdu.isTransportControl === true) return null
|
|
42
|
+
if (cEMIMessage.control?.addressType === 0) return null
|
|
43
|
+
if (npdu.isGroupRead) return 'GroupValue_Read'
|
|
44
|
+
if (npdu.isGroupResponse) return 'GroupValue_Response'
|
|
45
|
+
if (npdu.isGroupWrite) return 'GroupValue_Write'
|
|
46
|
+
return null
|
|
47
|
+
}
|
|
48
|
+
|
|
35
49
|
// DATAPONT MANIPULATION HELPERS
|
|
36
50
|
// ####################
|
|
37
51
|
const sortBy = (field) => (a, b) => {
|
|
@@ -210,6 +224,8 @@ module.exports = (RED) => {
|
|
|
210
224
|
node.port = parseInt(config.port)
|
|
211
225
|
node.physAddr = config.physAddr // the KNX physical address we'd like to use
|
|
212
226
|
node.suppressACKRequest = typeof config.suppressACKRequest === 'undefined' ? true : config.suppressACKRequest // enable this option to suppress the acknowledge flag with outgoing L_Data.req requests. LoxOne needs this
|
|
227
|
+
// TunnelUDP: wait for the TUNNELLING_ACK of each request (yes/no). "auto" leaves it to the KNX engine, which follows suppressACKRequest.
|
|
228
|
+
node.waitForTunnelingAck = config.waitForTunnelingAck === 'yes' ? true : config.waitForTunnelingAck === 'no' ? false : undefined
|
|
213
229
|
node.linkStatus = 'disconnected' // Can be: connected or disconnected
|
|
214
230
|
node.nodeClients = [] // Stores the registered clients
|
|
215
231
|
node.KNXEthInterface = typeof config.KNXEthInterface === 'undefined' ? 'Auto' : config.KNXEthInterface
|
|
@@ -226,6 +242,16 @@ module.exports = (RED) => {
|
|
|
226
242
|
try {
|
|
227
243
|
node.sysLogger = new loggerClass({ loglevel: node.loglevel, setPrefix: node.type + ' <' + (node.name || node.id || '') + '>' })
|
|
228
244
|
} catch (error) { console.log(error.stack) }
|
|
245
|
+
// File Cache Control: every file written by this gateway and by its nodes goes through this storage.
|
|
246
|
+
node.fileCacheMode = config.fileCacheMode || 'freshness'
|
|
247
|
+
node.fileStorage = createFileStorage({
|
|
248
|
+
ownerId: node.id,
|
|
249
|
+
mode: node.fileCacheMode,
|
|
250
|
+
interval: config.fileCacheInterval,
|
|
251
|
+
intervalUnit: config.fileCacheIntervalUnit,
|
|
252
|
+
log: (level, message) => node.sysLogger?.[level]?.(message)
|
|
253
|
+
})
|
|
254
|
+
node.persistFile = path.join(node.userDir, 'knxpersistvalues', 'knxpersist' + node.id + '.json')
|
|
229
255
|
node.csv = readCSV(config.csv) // Array from ETS CSV Group Addresses {ga:group address, dpt: datapoint, devicename: full device name with main and subgroups}
|
|
230
256
|
node.csvByGa = new Map()
|
|
231
257
|
if (Array.isArray(node.csv)) {
|
|
@@ -247,15 +273,27 @@ module.exports = (RED) => {
|
|
|
247
273
|
return node.exposedGAsByGa.get(ga)
|
|
248
274
|
}
|
|
249
275
|
|
|
276
|
+
// The persist file is serialized only when the storage commits it.
|
|
277
|
+
const saveExposedGAs = () => {
|
|
278
|
+
node.fileStorage.writeFile(node.persistFile, () => JSON.stringify(node.exposedGAs))
|
|
279
|
+
}
|
|
280
|
+
const rawValueKey = (rawValue) => {
|
|
281
|
+
try { return Buffer.from(rawValue?.data ?? rawValue).toString('hex') } catch (error) { return undefined }
|
|
282
|
+
}
|
|
283
|
+
|
|
250
284
|
node.upsertExposedGAEntry = (entry) => {
|
|
251
285
|
if (!entry || typeof entry.ga !== 'string' || entry.ga === '') return undefined
|
|
252
286
|
const existing = node.exposedGAsByGa.get(entry.ga)
|
|
253
287
|
if (existing) {
|
|
288
|
+
// A repeated value does not need to be written again.
|
|
289
|
+
const changed = rawValueKey(existing.rawValue) !== rawValueKey(entry.rawValue) || existing.dpt !== entry.dpt || existing.devicename !== entry.devicename
|
|
254
290
|
Object.assign(existing, entry)
|
|
291
|
+
if (changed) saveExposedGAs()
|
|
255
292
|
return existing
|
|
256
293
|
}
|
|
257
294
|
node.exposedGAs.push(entry)
|
|
258
295
|
node.exposedGAsByGa.set(entry.ga, entry)
|
|
296
|
+
saveExposedGAs()
|
|
259
297
|
return entry
|
|
260
298
|
}
|
|
261
299
|
|
|
@@ -263,7 +301,10 @@ module.exports = (RED) => {
|
|
|
263
301
|
if (typeof ga !== 'string' || ga === '') return
|
|
264
302
|
node.exposedGAsByGa.delete(ga)
|
|
265
303
|
const index = node.exposedGAs.findIndex((item) => item.ga === ga)
|
|
266
|
-
if (index > -1)
|
|
304
|
+
if (index > -1) {
|
|
305
|
+
node.exposedGAs.splice(index, 1)
|
|
306
|
+
saveExposedGAs()
|
|
307
|
+
}
|
|
267
308
|
}
|
|
268
309
|
|
|
269
310
|
// 12/11/2021 Connect at start delay
|
|
@@ -520,7 +561,6 @@ module.exports = (RED) => {
|
|
|
520
561
|
node.delaybetweentelegrams = (config.delaybetweentelegrams === undefined || config.delaybetweentelegrams === null || config.delaybetweentelegrams === '') ? 25 : Number(config.delaybetweentelegrams)
|
|
521
562
|
if (node.delaybetweentelegrams < 25) node.delaybetweentelegrams = 25 // Protection avoiding handleKNXQueue hangs
|
|
522
563
|
if (node.delaybetweentelegrams > 100) node.delaybetweentelegrams = 100 // Protection avoiding handleKNXQueue hangs
|
|
523
|
-
node.timerSaveExposedGAs = null // Timer to save the exposed GA every once in a while
|
|
524
564
|
|
|
525
565
|
// 05/12/2021 Set the protocol (this is undefined if coming from ild versions
|
|
526
566
|
if (node.hostProtocol === 'Auto') {
|
|
@@ -781,50 +821,18 @@ module.exports = (RED) => {
|
|
|
781
821
|
}
|
|
782
822
|
})()
|
|
783
823
|
|
|
784
|
-
// 04/04/2021 Supergiovane,
|
|
785
|
-
//
|
|
824
|
+
// 04/04/2021 Supergiovane, persistent GA values. The file is written by the
|
|
825
|
+
// File Cache Control storage, according to the selected disk-wearing mode.
|
|
786
826
|
// ************************
|
|
787
|
-
|
|
788
|
-
if (!fs.existsSync(_aPath)) {
|
|
789
|
-
// Create the path
|
|
790
|
-
try {
|
|
791
|
-
fs.mkdirSync(_aPath)
|
|
792
|
-
return true
|
|
793
|
-
} catch (error) {
|
|
794
|
-
return false
|
|
795
|
-
}
|
|
796
|
-
} else {
|
|
797
|
-
return true
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
if (!setupDirectory(node.userDir)) {
|
|
801
|
-
node.sysLogger?.error('Unable to set up MAIN directory: ' + node.userDir)
|
|
802
|
-
}
|
|
803
|
-
if (!setupDirectory(path.join(node.userDir, 'knxpersistvalues'))) {
|
|
804
|
-
node.sysLogger?.error('Unable to set up cache directory: ' + path.join(node.userDir, 'knxpersistvalues'))
|
|
805
|
-
} else {
|
|
806
|
-
node.sysLogger?.info('payload cache set to ' + path.join(node.userDir, 'knxpersistvalues'))
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
async function saveExposedGAs () {
|
|
810
|
-
const sFile = path.join(node.userDir, 'knxpersistvalues', 'knxpersist' + node.id + '.json')
|
|
811
|
-
try {
|
|
812
|
-
if (node.exposedGAs.length > 0) {
|
|
813
|
-
fs.writeFileSync(sFile, JSON.stringify(node.exposedGAs))
|
|
814
|
-
// node.sysLogger?.debug("wrote peristent values to the file " + sFile);
|
|
815
|
-
}
|
|
816
|
-
} catch (err) {
|
|
817
|
-
node.sysLogger?.error('unable to write peristent values to the file ' + sFile + ' ' + err.message)
|
|
818
|
-
}
|
|
819
|
-
}
|
|
827
|
+
node.sysLogger?.info('payload cache set to ' + node.persistFile + ', file cache mode ' + node.fileStorage.mode)
|
|
820
828
|
function loadExposedGAs () {
|
|
821
|
-
const sFile = path.join(node.userDir, 'knxpersistvalues', 'knxpersist' + node.id + '.json')
|
|
822
829
|
try {
|
|
823
|
-
|
|
830
|
+
// The storage returns the values not yet written to disk, too.
|
|
831
|
+
node.exposedGAs = JSON.parse(node.fileStorage.readFile(node.persistFile, 'utf8'))
|
|
824
832
|
if (!Array.isArray(node.exposedGAs)) node.exposedGAs = []
|
|
825
833
|
} catch (err) {
|
|
826
834
|
node.exposedGAs = []
|
|
827
|
-
node.sysLogger?.info('unable to read peristent file ' +
|
|
835
|
+
node.sysLogger?.info('unable to read peristent file ' + node.persistFile + ' ' + err.message)
|
|
828
836
|
}
|
|
829
837
|
node.rebuildExposedGAIndex()
|
|
830
838
|
}
|
|
@@ -900,12 +908,6 @@ module.exports = (RED) => {
|
|
|
900
908
|
loadExposedGAs() // 04/04/2021 load the current values of GA payload
|
|
901
909
|
node.sysLogger?.info('Loaded persist GA values', node.exposedGAs?.length)
|
|
902
910
|
|
|
903
|
-
if (node.timerSaveExposedGAs !== null) clearInterval(node.timerSaveExposedGAs)
|
|
904
|
-
node.timerSaveExposedGAs = setInterval(async () => {
|
|
905
|
-
await saveExposedGAs()
|
|
906
|
-
}, 5000)
|
|
907
|
-
node.sysLogger?.info('Started timerSaveExposedGAs with array lenght ', node.exposedGAs?.length)
|
|
908
|
-
|
|
909
911
|
try {
|
|
910
912
|
const readHistory = []
|
|
911
913
|
|
|
@@ -1151,6 +1153,7 @@ module.exports = (RED) => {
|
|
|
1151
1153
|
ipPort: node.port,
|
|
1152
1154
|
physAddr: node.physAddr, // the KNX physical address we'd like to use
|
|
1153
1155
|
suppress_ack_ldatareq: node.suppressACKRequest,
|
|
1156
|
+
waitForTunnelingAck: node.waitForTunnelingAck,
|
|
1154
1157
|
loglevel: node.loglevel,
|
|
1155
1158
|
hostProtocol: node.hostProtocol,
|
|
1156
1159
|
isSecureKNXEnabled: node.knxSecureSelected,
|
|
@@ -1338,6 +1341,7 @@ module.exports = (RED) => {
|
|
|
1338
1341
|
})
|
|
1339
1342
|
node.knxConnection.on(knx.KNXClientEvents.connected, (info) => {
|
|
1340
1343
|
node.linkStatus = 'connected'
|
|
1344
|
+
node.fileStorage.handleGatewayEvent()
|
|
1341
1345
|
|
|
1342
1346
|
// Track serial driver for forced close on redeploy
|
|
1343
1347
|
if (node.hostProtocol === 'SerialFT12' && node.knxConnection && node.knxConnection._serialDriver) {
|
|
@@ -1399,18 +1403,20 @@ module.exports = (RED) => {
|
|
|
1399
1403
|
return
|
|
1400
1404
|
}
|
|
1401
1405
|
|
|
1402
|
-
let _evt = null
|
|
1403
|
-
if (_datagram.cEMIMessage.npdu.isGroupRead) _evt = 'GroupValue_Read'
|
|
1404
|
-
if (_datagram.cEMIMessage.npdu.isGroupResponse) _evt = 'GroupValue_Response'
|
|
1405
|
-
if (_datagram.cEMIMessage.npdu.isGroupWrite) _evt = 'GroupValue_Write'
|
|
1406
|
-
|
|
1407
1406
|
let _src = null
|
|
1408
1407
|
_src = _datagram.cEMIMessage.srcAddress.toString()
|
|
1409
1408
|
|
|
1410
1409
|
let _dest = null
|
|
1411
1410
|
_dest = _datagram.cEMIMessage.dstAddress.toString()
|
|
1412
1411
|
|
|
1413
|
-
|
|
1412
|
+
// Point-to-point and transport control telegrams (e.g. an ETS device scan) are valid, but not for us
|
|
1413
|
+
const _evt = getGroupServiceEvent(_datagram.cEMIMessage)
|
|
1414
|
+
if (_evt === null) {
|
|
1415
|
+
node.sysLogger?.debug(`HandleBusEvent: ignored non group telegram src=${_src} dest=${_dest}`)
|
|
1416
|
+
return
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
if (_src === null || _dest === null) {
|
|
1414
1420
|
node.sysLogger?.warn(`HandleBusEvent: unable to parse telegram, ignored (evt=${_evt || 'n/a'} src=${_src || 'n/a'} dest=${_dest || 'n/a'})`)
|
|
1415
1421
|
return
|
|
1416
1422
|
};
|
|
@@ -2660,10 +2666,6 @@ module.exports = (RED) => {
|
|
|
2660
2666
|
}, 10000)
|
|
2661
2667
|
|
|
2662
2668
|
node.Disconnect = async (_sNodeStatus = '', _sColor = 'grey') => {
|
|
2663
|
-
if (node.timerSaveExposedGAs !== null) {
|
|
2664
|
-
clearInterval(node.timerSaveExposedGAs)
|
|
2665
|
-
node.timerSaveExposedGAs = null
|
|
2666
|
-
}
|
|
2667
2669
|
if (node.timerDoInitialRead !== null) {
|
|
2668
2670
|
clearTimeout(node.timerDoInitialRead) // 17/02/2020 Stop the initial read timer
|
|
2669
2671
|
node.timerDoInitialRead = null
|
|
@@ -2724,7 +2726,7 @@ module.exports = (RED) => {
|
|
|
2724
2726
|
}
|
|
2725
2727
|
|
|
2726
2728
|
node.setAllClientsStatus('Disconnected', _sColor, _sNodeStatus)
|
|
2727
|
-
|
|
2729
|
+
node.fileStorage.handleGatewayEvent() // 04/04/2021 save the current values of GA payload
|
|
2728
2730
|
node.sysLogger?.debug('Disconnected, node.autoReconnect:' + node.autoReconnect)
|
|
2729
2731
|
}
|
|
2730
2732
|
|
|
@@ -2736,6 +2738,9 @@ module.exports = (RED) => {
|
|
|
2736
2738
|
}
|
|
2737
2739
|
await node.Disconnect()
|
|
2738
2740
|
} catch (error) { /* empty */ }
|
|
2741
|
+
try {
|
|
2742
|
+
node.fileStorage.close()
|
|
2743
|
+
} catch (error) { /* empty */ }
|
|
2739
2744
|
node.nodeClients = [] // 05/04/2022 Nullify
|
|
2740
2745
|
try {
|
|
2741
2746
|
node.sysLogger?.destroy()
|
|
@@ -2754,5 +2759,6 @@ module.exports = (RED) => {
|
|
|
2754
2759
|
}
|
|
2755
2760
|
|
|
2756
2761
|
module.exports.__test = {
|
|
2757
|
-
resolveHostAddress
|
|
2762
|
+
resolveHostAddress,
|
|
2763
|
+
getGroupServiceEvent
|
|
2758
2764
|
}
|
package/nodes/knxUltimate.html
CHANGED
|
@@ -790,6 +790,9 @@ return msg;`
|
|
|
790
790
|
node.initialread = 0;
|
|
791
791
|
$("#node-input-initialread").val(0)
|
|
792
792
|
}
|
|
793
|
+
// Reading the initial value from file is limited when the gateway does not write files.
|
|
794
|
+
const refreshFileCacheTip = KNX_bindFileCacheDisabledTip($("#knxUltimate-file-cache-tip"), $("#node-input-server"), () => ['2', '3'].includes(String($("#node-input-initialread").val())));
|
|
795
|
+
$("#node-input-initialread").on('change', refreshFileCacheTip);
|
|
793
796
|
|
|
794
797
|
oNodeServer = RED.nodes.node($("#node-input-server").val());
|
|
795
798
|
if (oNodeServer === undefined) {
|
|
@@ -1352,6 +1355,7 @@ return msg;`
|
|
|
1352
1355
|
<option value=2 data-i18n="knxUltimate.properties.node-input-initialread2"></option>
|
|
1353
1356
|
<option value=3 data-i18n="knxUltimate.properties.node-input-initialread3"></option>
|
|
1354
1357
|
</select>
|
|
1358
|
+
<div class="form-tips" id="knxUltimate-file-cache-tip" style="display:none; margin-top:6px;"></div>
|
|
1355
1359
|
|
|
1356
1360
|
</div>
|
|
1357
1361
|
<div class="form-row" id="divInputRBE">
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
const text = (key) => RED._('node-red-contrib-knx-ultimate/knxUltimateUtility:knxUltimateUtility.' + key);
|
|
13
13
|
const activeType = (node) => node._utilityEditor ? node._utilityEditor.type() : node.utilityType;
|
|
14
14
|
const validationContext = (node) => typeof node._utilityEditor?.values === 'function' ? node._utilityEditor.values() : node;
|
|
15
|
+
// Functions that save files through the gateway's File Cache Control.
|
|
16
|
+
const usesFiles = (type) => type === 'autoresponder' || type === 'scenecontroller' || (type === 'logger' && $('#node-input-saveMode').val() === 'emit_save');
|
|
15
17
|
|
|
16
18
|
function buildDefaults() {
|
|
17
19
|
// Node-RED must know every persistable field and the real config-node
|
|
@@ -136,6 +138,7 @@
|
|
|
136
138
|
let closed = false;
|
|
137
139
|
let helpTimer;
|
|
138
140
|
const container = $('#knx-utility-profile-editor');
|
|
141
|
+
const refreshFileCacheTip = KNX_bindFileCacheDisabledTip($('#knx-utility-file-cache-tip'), $('#node-input-server'), () => usesFiles(selectedType));
|
|
139
142
|
|
|
140
143
|
// Edit a separate context: profile hooks (including asynchronous ETS
|
|
141
144
|
// suggestions) must never mutate the saved node before Done is pressed.
|
|
@@ -201,6 +204,8 @@
|
|
|
201
204
|
$('#knx-utility-pin-description').text(text('pins.' + type));
|
|
202
205
|
$('#node-input-name').attr('placeholder', isGlobalContext ? mounted.defaults.name.value : 'KNX Utility · ' + text('types.' + type));
|
|
203
206
|
if (typeof mounted.oneditprepare === 'function') mounted.oneditprepare.call(context);
|
|
207
|
+
$('#node-input-saveMode').on('change.knxFileCacheTip', refreshFileCacheTip);
|
|
208
|
+
refreshFileCacheTip();
|
|
204
209
|
// These controls are mounted after Node-RED attaches its initial
|
|
205
210
|
// validation handlers. Trigger a shared field's standard handler so
|
|
206
211
|
// the complete editor validates again while the user edits a profile.
|
|
@@ -250,6 +255,7 @@
|
|
|
250
255
|
closed = true;
|
|
251
256
|
dispose();
|
|
252
257
|
$('#node-input-utilityType').off('.knxUtility');
|
|
258
|
+
$('#node-input-server').off('.knxFileCacheTip');
|
|
253
259
|
}
|
|
254
260
|
};
|
|
255
261
|
const initialType = node.utilityType || 'alerter';
|
|
@@ -311,6 +317,7 @@
|
|
|
311
317
|
<label for="node-input-server"><i class="fa fa-circle-o"></i> <span data-i18n="knxUltimateUtility.gateway"></span></label>
|
|
312
318
|
<input type="text" id="node-input-server">
|
|
313
319
|
</div>
|
|
320
|
+
<div class="form-tips" id="knx-utility-file-cache-tip" style="display:none"></div>
|
|
314
321
|
<div class="form-row">
|
|
315
322
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span id="knx-utility-name-label" data-i18n="knxUltimateUtility.name"></span></label>
|
|
316
323
|
<input type="text" id="node-input-name">
|
|
@@ -77,6 +77,8 @@
|
|
|
77
77
|
const base = raw.split("-")[0];
|
|
78
78
|
return ["en", "it", "de", "fr", "es"].includes(base) ? base : "en";
|
|
79
79
|
};
|
|
80
|
+
// The history is kept only in memory when the gateway does not write files.
|
|
81
|
+
KNX_bindFileCacheDisabledTip($("#knx-viewer-file-cache-tip"), $("#node-input-server"));
|
|
80
82
|
$("#knx-viewer-open-web-page").on("click", function (evt) {
|
|
81
83
|
evt.preventDefault();
|
|
82
84
|
const adminRoot = resolveAdminRoot();
|
|
@@ -128,6 +130,7 @@
|
|
|
128
130
|
</label>
|
|
129
131
|
<input type="text" id="node-input-server" />
|
|
130
132
|
</div>
|
|
133
|
+
<div class="form-tips" id="knx-viewer-file-cache-tip" style="display:none;"></div>
|
|
131
134
|
|
|
132
135
|
<div class="form-row">
|
|
133
136
|
<label for="node-input-name">
|
|
@@ -4,6 +4,7 @@ const KNXAddress = require('knxultimate').KNXAddress
|
|
|
4
4
|
const _ = require('lodash')
|
|
5
5
|
const { getRequestAccessToken, normalizeAuthFromAccessTokenQuery } = require('./utils/httpAdminAccessToken')
|
|
6
6
|
const createViewerHistory = require('./utils/knxViewerHistory')
|
|
7
|
+
const { storageOf } = require('./utils/fileStorage')
|
|
7
8
|
|
|
8
9
|
const viewerRuntimeContexts = new WeakMap()
|
|
9
10
|
const knxUltimateViewerVueDistDir = path.join(__dirname, 'plugins', 'knxUltimateViewer-vue')
|
|
@@ -314,7 +315,8 @@ module.exports = function (RED) {
|
|
|
314
315
|
userDir: RED.settings.userDir,
|
|
315
316
|
nodeId: node.id,
|
|
316
317
|
gatewayId: node.serverKNX.id,
|
|
317
|
-
onError: reportHistoryError
|
|
318
|
+
onError: reportHistoryError,
|
|
319
|
+
storage: storageOf(node.serverKNX)
|
|
318
320
|
})
|
|
319
321
|
node.viewerHistory.ready.catch(reportHistoryError)
|
|
320
322
|
} catch (error) {
|
|
@@ -39,10 +39,10 @@ Dieser Node stellt die Verbindung zu deinem KNX/IP-Gateway her.
|
|
|
39
39
|
|Eigenschaft|Beschreibung|
|
|
40
40
|
|--|--|
|
|
41
41
|
| Suppress repeated (R-Flag) telegrams fom BUS | Wiederholte BUS-Telegramme (R-Flag) ignorieren. |
|
|
42
|
-
|
|
|
42
|
+
| Bus-ACK-Anforderung unterdrücken | Bus-ACK. Wenn aktiviert, fordern die an den KNX-Bus gesendeten Telegramme (Tunnel UDP, Multicast und Serial FT1.2) keine Bestätigung der empfangenden Geräte mehr an. Bei Tunnel UDP und "Auf Tunnelling-ACK warten" auf Automatisch wartet der Knoten außerdem nicht mehr auf die Bestätigung der Schnittstelle. Nur aktivieren, wenn Ihre Schnittstelle es erfordert, z. B. einige alte oder Weinzierl-KNX/IP-Schnittstellen, eibPORT und Loxone. Standard: deaktiviert. |
|
|
43
|
+
| Auf Tunnelling-ACK warten (Tunnel UDP) | Schnittstellen-ACK. Bei Tunnel UDP wartet der Knoten, bis die KNX/IP-Schnittstelle jedes Telegramm bestätigt: Ein unbestätigtes Telegramm wird noch einmal gesendet, dann wird die Verbindung geschlossen und neu aufgebaut. Automatisch wartet nur, wenn "Bus-ACK-Anforderung unterdrücken" deaktiviert ist, wie in früheren Versionen. Ja wartet immer, Nein nie. eibPORT- und Loxone-Gateways benötigen "Bus-ACK-Anforderung unterdrücken" zusammen mit Ja. |
|
|
43
44
|
| Flow-Bubbles-Plugin aktivieren | Zeigt im Editor neben jedem KNX Device Node eine kleine farbige Bubble an. Die Bubble spiegelt den zuletzt vom Gateway empfangenen Live-Status wider und wird abgeblendet, wenn die Daten veraltet sind. Nützlich bei Inbetriebnahme und Debugging. Standard: deaktiviert. |
|
|
44
45
|
| Delay between each telegram (ms) | KNX erlaubt max. 50 Telegramme/s. 25-50 ms sind üblich; bei langsamen Verbindungen höher (z. B. 200-500 ms). |
|
|
45
|
-
| Loglevel | Log-Detailgrad. Standard: "Error". |
|
|
46
46
|
| Aktualisierung der Status-Badges | Legt fest, wie oft die Statusanzeige der Nodes erneuert wird. Mit einer Verzögerung werden Zwischenstände verworfen und nur der letzte Wert nach dem gewählten Intervall angezeigt. Wählen Sie **Sofort**, um das bisherige Echtzeitverhalten beizubehalten. |
|
|
47
47
|
| Status Datum/Uhrzeit-Format | Legt fest, wie Datum/Uhrzeit im Status-Badge angezeigt werden (nützlich, wenn das OS-Locale nicht konfigurierbar ist). |
|
|
48
48
|
| Benutzerdefiniertes Format | Wird verwendet, wenn **Benutzerdefiniert (Tokens)** gewählt ist. Tokens: `YYYY`, `YY`, `MMM`, `MM`, `DD`, `HH`, `mm`, `ss`, `A`, `a`, `Z`. Verwenden Sie `[Text]` für Literale. |
|
|
@@ -59,12 +59,15 @@ Dieser Node stellt die Verbindung zu deinem KNX/IP-Gateway her.
|
|
|
59
59
|
|
|
60
60
|
<br/>
|
|
61
61
|
|
|
62
|
-
**
|
|
62
|
+
**Datei-Cache-Steuerung**
|
|
63
63
|
|
|
64
64
|
|Eigenschaft|Beschreibung|
|
|
65
65
|
|--|--|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
66
|
+
| Loglevel | Log-Detailgrad. Standard: "Error". Das Log ist von der Schreibverschleiß-Verwaltung nicht betroffen. |
|
|
67
|
+
| Schreibverschleiß-Verwaltung | Legt fest, wie oft KNX Ultimate seine Dateien auf den Datenträger schreibt: GA-Werte, Szenen des Scene Controllers, AutoResponder-Werte, Logger-Datei und Viewer-Verlauf. Nützlich, um den Verschleiß von SD-Karten zu verringern. Dateien werden nur geschrieben, wenn sich ihr Inhalt geändert hat. **Aktualität zuerst** (Standard) speichert Änderungen alle 5 Sekunden. **Ausgewogen** speichert sie nur beim Verbinden oder Trennen des Gateways sowie wenn Node-RED stoppt oder das Gateway neu bereitgestellt wird. **Schreiben deaktivieren** schreibt nie auf den Datenträger: Die Daten bleiben nur im Speicher, und bei jedem Neustart von Node-RED gehen alle aktuellen GA-Werte und die von den KNX-Ultimate-Knoten gespeicherten Daten verloren. **Benutzerdefiniertes Intervall** speichert Änderungen im gewählten Intervall (5 Sekunden bis 30 Tage) sowie wenn Node-RED stoppt oder das Gateway neu bereitgestellt wird. |
|
|
68
|
+
| Schreibintervall | Sichtbar bei **Benutzerdefiniertes Intervall**. Wert und Einheit (Sekunden, Minuten, Stunden, Tage) des Schreibintervalls. |
|
|
69
|
+
|
|
70
|
+
> Ist das Schreiben deaktiviert, zeigen die KNX-Ultimate-Knoten, die Dateien verwenden (Device mit initialem Lesen aus Datei, Scene Controller, AutoResponder, Logger mit Speicherung in Datei, Viewer), einen Hinweis in ihrem Editor.
|
|
68
71
|
|
|
69
72
|
<br/>
|
|
70
73
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"discovering": "Suche...",
|
|
20
20
|
"interfaces_found": "Schnittstellen gefunden.",
|
|
21
21
|
"discovery_failed": "Suche fehlgeschlagen.",
|
|
22
|
-
"weinzierl_ack_autoenabled": "Weinzierl-Interface erkannt: '
|
|
22
|
+
"weinzierl_ack_autoenabled": "Weinzierl-Interface erkannt: 'Bus-ACK-Anforderung unterdrücken' wurde automatisch aktiviert. Du kannst es im Tab 'Erweitert' deaktivieren.",
|
|
23
23
|
"address": "Adresse",
|
|
24
24
|
"iface_auto": "Auto",
|
|
25
25
|
"iface_manual": "Schnittstellennamen manuell eingeben",
|
|
@@ -63,15 +63,20 @@
|
|
|
63
63
|
"configuration": "Konfiguration",
|
|
64
64
|
"advanced": "Erweitert",
|
|
65
65
|
"ets_import": "ETS-Import",
|
|
66
|
-
"
|
|
66
|
+
"file_cache": "Datei-Cache-Steuerung"
|
|
67
67
|
},
|
|
68
68
|
"advanced": {
|
|
69
69
|
"knx_phy_addr": "KNX-Adresse",
|
|
70
70
|
"show_date_status": "Tag und Uhrzeit des letzten Updates im Status anzeigen",
|
|
71
71
|
"show_device_status": "Gerätenamen im Status anzeigen (\"Alle Gruppenadressen abhören\" erforderlich)",
|
|
72
72
|
"show_datapoint_status": "Datenpunkt im Status anzeigen",
|
|
73
|
-
"suppress_ack": "ACK-
|
|
74
|
-
"suppress_ack_help": "
|
|
73
|
+
"suppress_ack": "Bus-ACK-Anforderung unterdrücken",
|
|
74
|
+
"suppress_ack_help": "Bus-ACK. Wenn aktiviert, fordern die an den KNX-Bus gesendeten Telegramme (Tunnel UDP, Multicast und Serial FT1.2) keine Bestätigung der empfangenden Geräte mehr an. Bei Tunnel UDP und \"Auf Tunnelling-ACK warten\" auf Automatisch wartet der Knoten außerdem nicht mehr auf die Bestätigung der Schnittstelle. Nur aktivieren, wenn Ihre Schnittstelle es erfordert, z. B. einige alte oder Weinzierl-KNX/IP-Schnittstellen, eibPORT und Loxone. Standard: deaktiviert.",
|
|
75
|
+
"wait_tunneling_ack": "Auf Tunnelling-ACK warten (Tunnel UDP)",
|
|
76
|
+
"wait_tunneling_ack_auto": "Automatisch (nur wenn die Bus-ACK-Anforderung nicht unterdrückt ist)",
|
|
77
|
+
"wait_tunneling_ack_yes": "Ja (einmal wiederholen, dann trennen)",
|
|
78
|
+
"wait_tunneling_ack_no": "Nein",
|
|
79
|
+
"wait_tunneling_ack_help": "Schnittstellen-ACK. Bei Tunnel UDP wartet der Knoten, bis die KNX/IP-Schnittstelle jedes Telegramm bestätigt: Ein unbestätigtes Telegramm wird noch einmal gesendet, dann wird die Verbindung geschlossen und neu aufgebaut. Automatisch wartet nur, wenn \"Bus-ACK-Anforderung unterdrücken\" deaktiviert ist, wie in früheren Versionen. Ja wartet immer, Nein nie. eibPORT- und Loxone-Gateways benötigen \"Bus-ACK-Anforderung unterdrücken\" zusammen mit Ja.",
|
|
75
80
|
"ignoreTelegramsWithRepeatedFlag": "Wiederholt (R-Flag) telegramme vom BUS unterdrücken",
|
|
76
81
|
"enable_flow_bubbles": "Flow-Bubbles-Plugin aktivieren",
|
|
77
82
|
"enable_flow_bubbles_help": "Zeigt Live-Status-Bubbles neben KNX Device Nodes im Editor an. Nützlich bei Inbetriebnahme und Debugging.",
|
|
@@ -133,22 +138,19 @@
|
|
|
133
138
|
"tunnel_user_password": "Tunnel-Benutzerpasswort",
|
|
134
139
|
"ga_list_label": "ETS-Gruppenadressliste"
|
|
135
140
|
},
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"reveal_keyring_button": "Anzeigen",
|
|
150
|
-
"reveal_keyring_loading": "Keyring wird dekodiert, bitte warten...",
|
|
151
|
-
"reveal_keyring_fail": "Keyring konnte nicht dekodiert werden. Prüfen Sie die Keyring-Datei und das allgemeine Passwort."
|
|
141
|
+
"file_cache": {
|
|
142
|
+
"mode": "Schreibverschleiß-Verwaltung",
|
|
143
|
+
"mode_freshness": "Aktualität zuerst",
|
|
144
|
+
"mode_balanced": "Ausgewogen",
|
|
145
|
+
"mode_disabled": "Schreiben deaktivieren",
|
|
146
|
+
"mode_custom": "Benutzerdefiniertes Intervall",
|
|
147
|
+
"interval": "Schreibintervall",
|
|
148
|
+
"unit_seconds": "Sekunden",
|
|
149
|
+
"unit_minutes": "Minuten",
|
|
150
|
+
"unit_hours": "Stunden",
|
|
151
|
+
"unit_days": "Tage",
|
|
152
|
+
"disabled_tip": "Das Schreiben auf den Datenträger ist deaktiviert (Datei-Cache-Steuerung des KNX-Gateways): Bei jedem Neustart von Node-RED gehen alle aktuellen GA-Werte und die von den KNX-Ultimate-Knoten gespeicherten Daten verloren.",
|
|
153
|
+
"description": "Legt fest, wie oft KNX Ultimate seine Dateien auf den Datenträger schreibt (GA-Werte, Szenen des Scene Controllers, AutoResponder-Werte, Logger-Datei, Viewer-Verlauf), um den Verschleiß von SD-Karten zu verringern. Dateien werden nur geschrieben, wenn sich ihr Inhalt geändert hat. Das Log ist nicht betroffen: Verwenden Sie dafür die Protokollstufe.<br/><b>Aktualität zuerst</b>: Änderungen werden alle 5 Sekunden gespeichert.<br/><b>Ausgewogen</b>: Änderungen werden nur beim Verbinden oder Trennen des Gateways gespeichert sowie wenn Node-RED stoppt oder das Gateway neu bereitgestellt wird.<br/><b>Schreiben deaktivieren</b>: Es wird nichts auf den Datenträger geschrieben.<br/><b>Benutzerdefiniertes Intervall</b>: Änderungen werden im gewählten Intervall (5 Sekunden bis 30 Tage) gespeichert sowie wenn Node-RED stoppt oder das Gateway neu bereitgestellt wird."
|
|
152
154
|
}
|
|
153
155
|
}
|
|
154
156
|
}
|
|
@@ -54,6 +54,8 @@ Der Button wird nur eingeblendet, wenn die Option aktiv ist. Im Universalmodus i
|
|
|
54
54
|
| Auf Lese-Telegramme reagieren | Sendet bei Read eine Nachricht an den Flow (z. B. um eigene Werte zu liefern). |
|
|
55
55
|
| Multiply/Decimals/Negatives | Skaliert, rundet und behandelt negative Werte (nur numerische Werte). |
|
|
56
56
|
|
|
57
|
+
> 💾 Wann die von **Bei Verbindung/Wiederverbindung der Wert lesen** (aus Datei) genutzten GA-Werte auf den Datenträger geschrieben werden, bestimmt die **Datei-Cache-Steuerung** des KNX-Gateways. Mit **Schreiben deaktivieren** bleiben sie nur im Speicher und gehen bei jedem Neustart von Node-RED verloren. Siehe den Tab **Datei-Cache-Steuerung** des KNX-Gateways.
|
|
58
|
+
|
|
57
59
|
<br/>
|
|
58
60
|
<br/>
|
|
59
61
|
|
|
@@ -163,6 +163,8 @@ msg = {
|
|
|
163
163
|
|
|
164
164
|
## AutoResponder
|
|
165
165
|
|
|
166
|
+
> 💾 Wann die gespeicherten Werte auf den Datenträger geschrieben werden, bestimmt die **Datei-Cache-Steuerung** des KNX-Gateways. Mit **Schreiben deaktivieren** bleiben sie nur im Speicher und gehen bei jedem Neustart von Node-RED verloren. Siehe den Tab **Datei-Cache-Steuerung** des KNX-Gateways.
|
|
167
|
+
|
|
166
168
|
Dieser Knoten antwortet auf Leseanfragen aus dem KNX -Bus.
|
|
167
169
|
|
|
168
170
|
Der Knoten zeichnet alle an den KNX -Bus übertragenen Telegramme auf und speichert die Werte im Speicher.
|
|
@@ -502,6 +504,8 @@ global.set("KNXContextBanana_WRITE", toSend);
|
|
|
502
504
|
|
|
503
505
|
## Logger
|
|
504
506
|
|
|
507
|
+
> 💾 Wann die Daten der XML-Datei von **Payload senden und in Datei speichern** auf den Datenträger geschrieben werden, bestimmt die **Datei-Cache-Steuerung** des KNX-Gateways. Mit **Schreiben deaktivieren** bleiben sie nur im Speicher und gehen bei jedem Neustart von Node-RED verloren. Siehe den Tab **Datei-Cache-Steuerung** des KNX-Gateways.
|
|
508
|
+
|
|
505
509
|
### Logger
|
|
506
510
|
|
|
507
511
|
Der Logger-Node zeichnet alle Telegramme auf und erzeugt eine ETS-Busmonitor-kompatible XML-Datei.
|
|
@@ -761,6 +765,8 @@ return msg;
|
|
|
761
765
|
|
|
762
766
|
## Szenensteuerung
|
|
763
767
|
|
|
768
|
+
> 💾 Wann die gespeicherten Szenen auf den Datenträger geschrieben werden, bestimmt die **Datei-Cache-Steuerung** des KNX-Gateways. Mit **Schreiben deaktivieren** bleiben sie nur im Speicher und gehen bei jedem Neustart von Node-RED verloren. Siehe den Tab **Datei-Cache-Steuerung** des KNX-Gateways.
|
|
769
|
+
|
|
764
770
|
### Scene Controller
|
|
765
771
|
|
|
766
772
|
Der Scene-Controller-Node verhält sich wie ein KNX-Szenencontroller: Szenen speichern und abrufen.
|
|
@@ -19,6 +19,8 @@ Wählen Sie einen Viewer, durchsuchen Sie die Liste oder blättern Sie zu älter
|
|
|
19
19
|
|
|
20
20
|
Der aktive Viewer-Knoten speichert den Verlauf automatisch in Dateien unter `userDir/knxultimatestorage/viewer`, getrennt nach Viewer und Gateway. Änderungen, die älter als 24 Stunden sind, werden automatisch entfernt. Nach einem Neustart von Node-RED lädt der Viewer den noch in diesem Zeitraum liegenden Verlauf.
|
|
21
21
|
|
|
22
|
+
> 💾 Wann die Verlaufsdateien auf den Datenträger geschrieben werden, bestimmt die **Datei-Cache-Steuerung** des KNX-Gateways. Mit **Schreiben deaktivieren** bleiben sie nur im Speicher und gehen bei jedem Neustart von Node-RED verloren. Siehe den Tab **Datei-Cache-Steuerung** des KNX-Gateways.
|
|
23
|
+
|
|
22
24
|
Die Aufzeichnung beginnt, sobald der aktualisierte Viewer bereitgestellt ist und läuft. Frühere Bustelegramme werden nicht nachträglich rekonstruiert.
|
|
23
25
|
|
|
24
26
|
## Flow-Ausgänge
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
|Property|Description|
|
|
40
40
|
|--|--|
|
|
41
41
|
| Suppress repeated (R-Flag) telegrams fom BUS | Ignore repeated KNX telegrams coming from the bus. Default is unchecked. |
|
|
42
|
-
| Suppress ACK request
|
|
42
|
+
| Suppress the bus ACK request | Bus ACK. When checked, the telegrams sent to the KNX bus (Tunnel UDP, Multicast and Serial FT1.2) no longer ask the receiving devices for an acknowledgement. With Tunnel UDP and "Wait for the tunnelling ACK" set to Auto, the node also stops waiting for the interface's confirmation. Enable it only if your interface needs it, for example some old or Weinzierl KNX/IP interfaces, eibPORT and Loxone. Default is unchecked. |
|
|
43
|
+
| Wait for the tunnelling ACK (Tunnel UDP) | Interface ACK. With Tunnel UDP, the node waits for the KNX/IP interface to confirm every telegram: a telegram that is not confirmed is sent once more, then the connection is closed and opened again. Auto waits only when "Suppress the bus ACK request" is unchecked, as in previous versions. Yes always waits, No never waits. eibPORT and Loxone gateways need "Suppress the bus ACK request" checked together with Yes. |
|
|
43
44
|
| Enable flow bubbles plugin | Draw a small coloured bubble next to each KNX Device node in the editor. The bubble reflects the latest live state received from the gateway and becomes dim when the data is stale. Useful during commissioning and debugging. Default is unchecked. |
|
|
44
45
|
| Delay between each telegram (in milliseconds) | KNX specs states, that the maximum telegram sending speed is 50 telegrams per second. A speed between 25 and 50ms should be fine, unless you're connecting to a remote KNX Gateway via a slow internet connection (in this case, you should increase the value by, for example, 200 to 500ms or more). |
|
|
45
|
-
| Loglevel | Log level, in case you need to debug something with the dev. Default is "Error", |
|
|
46
46
|
| Node status throttle | Delay how often node badges are refreshed. When a delay is selected, intermediate status changes are discarded and the last one is shown after the chosen interval. Select **Immediate** to keep the legacy real-time behaviour. |
|
|
47
47
|
| Status date/time format | Choose how the timestamp is shown in node status badges (useful when the host OS locale cannot be configured). |
|
|
48
48
|
| Custom format | Used when **Custom (tokens)** is selected. Tokens: `YYYY`, `YY`, `MMM`, `MM`, `DD`, `HH`, `mm`, `ss`, `A`, `a`, `Z`. Use `[text]` for literals. |
|
|
@@ -59,12 +59,15 @@
|
|
|
59
59
|
|
|
60
60
|
<br/>
|
|
61
61
|
|
|
62
|
-
**
|
|
62
|
+
**File Cache Control**
|
|
63
63
|
|
|
64
64
|
|Property|Description|
|
|
65
65
|
|--|--|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
66
|
+
| Loglevel | Log level, in case you need to debug something with the dev. Default is "Error". The log is not affected by the disk-wear management. |
|
|
67
|
+
| Disk-wear management | Sets how often KNX Ultimate writes its files to disk: GA values, Scene Controller scenes, AutoResponder values, Logger file and Viewer history. Useful to reduce the wear of SD cards. Files are written only when their content has changed. **Freshness priority** (default) saves the changes every 5 seconds. **Balanced** saves them only when the gateway connects or disconnects, and when Node-RED stops or the gateway is redeployed. **Disable writing** never writes to disk: the data is kept in memory only and, at every restart of Node-RED, all the current GA values and the data saved by the KNX Ultimate nodes are lost. **Custom interval** saves the changes at the chosen interval, from 5 seconds to 30 days, and when Node-RED stops or the gateway is redeployed. |
|
|
68
|
+
| Write interval | Visible with **Custom interval**. Number and unit (seconds, minutes, hours, days) of the write interval. |
|
|
69
|
+
|
|
70
|
+
> When writing is disabled, the KNX Ultimate nodes that use files (Device with initial read from file, Scene Controller, AutoResponder, Logger saving to file, Viewer) show a reminder in their editor.
|
|
68
71
|
|
|
69
72
|
<br/>
|
|
70
73
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"discovering": "Discovering...",
|
|
20
20
|
"interfaces_found": "interfaces found.",
|
|
21
21
|
"discovery_failed": "Discovery failed.",
|
|
22
|
-
"weinzierl_ack_autoenabled": "Weinzierl interface detected: 'Suppress ACK request' has been enabled automatically. You can disable it in the Advanced tab.",
|
|
22
|
+
"weinzierl_ack_autoenabled": "Weinzierl interface detected: 'Suppress the bus ACK request' has been enabled automatically. You can disable it in the Advanced tab.",
|
|
23
23
|
"address": "Address",
|
|
24
24
|
"iface_auto": "Auto",
|
|
25
25
|
"iface_manual": "Manually enter interface's name",
|
|
@@ -64,15 +64,20 @@
|
|
|
64
64
|
"configuration": "Configuration",
|
|
65
65
|
"advanced": "Advanced",
|
|
66
66
|
"ets_import": "ETS file import",
|
|
67
|
-
"
|
|
67
|
+
"file_cache": "File Cache Control"
|
|
68
68
|
},
|
|
69
69
|
"advanced": {
|
|
70
70
|
"knx_phy_addr": "KNX Physical Address",
|
|
71
71
|
"show_date_status": "Show last update day and time in status",
|
|
72
72
|
"show_device_status": "Show device name in status (require \"Listen all Group Address\" )",
|
|
73
73
|
"show_datapoint_status": "Show datapoint in status",
|
|
74
|
-
"suppress_ack": "Suppress ACK request
|
|
75
|
-
"suppress_ack_help": "
|
|
74
|
+
"suppress_ack": "Suppress the bus ACK request",
|
|
75
|
+
"suppress_ack_help": "Bus ACK. When checked, the telegrams sent to the KNX bus (Tunnel UDP, Multicast and Serial FT1.2) no longer ask the receiving devices for an acknowledgement. With Tunnel UDP and \"Wait for the tunnelling ACK\" set to Auto, the node also stops waiting for the interface's confirmation. Enable it only if your interface needs it, for example some old or Weinzierl KNX/IP interfaces, eibPORT and Loxone. Default is unchecked.",
|
|
76
|
+
"wait_tunneling_ack": "Wait for the tunnelling ACK (Tunnel UDP)",
|
|
77
|
+
"wait_tunneling_ack_auto": "Auto (only if the bus ACK request is not suppressed)",
|
|
78
|
+
"wait_tunneling_ack_yes": "Yes (repeat once, then disconnect)",
|
|
79
|
+
"wait_tunneling_ack_no": "No",
|
|
80
|
+
"wait_tunneling_ack_help": "Interface ACK. With Tunnel UDP, the node waits for the KNX/IP interface to confirm every telegram: a telegram that is not confirmed is sent once more, then the connection is closed and opened again. Auto waits only when \"Suppress the bus ACK request\" is unchecked, as in previous versions. Yes always waits, No never waits. eibPORT and Loxone gateways need \"Suppress the bus ACK request\" checked together with Yes.",
|
|
76
81
|
"ignoreTelegramsWithRepeatedFlag": "Suppress repeated (R-Flag) telegrams fom BUS",
|
|
77
82
|
"enable_flow_bubbles": "Enable flow bubbles plugin",
|
|
78
83
|
"enable_flow_bubbles_help": "Draw live status bubbles next to KNX Device nodes in the editor. Useful during commissioning and debugging.",
|
|
@@ -137,22 +142,19 @@
|
|
|
137
142
|
"tunnel_user_password": "Tunnel user password",
|
|
138
143
|
"ga_list_label": "ETS group address list"
|
|
139
144
|
},
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"
|
|
150
|
-
"
|
|
151
|
-
"
|
|
152
|
-
"
|
|
153
|
-
"reveal_keyring_button": "Reveal",
|
|
154
|
-
"reveal_keyring_loading": "Decoding keyring, please wait...",
|
|
155
|
-
"reveal_keyring_fail": "Unable to decode the keyring. Check the keyring file and the general password."
|
|
145
|
+
"file_cache": {
|
|
146
|
+
"mode": "Disk-wear management",
|
|
147
|
+
"mode_freshness": "Freshness priority",
|
|
148
|
+
"mode_balanced": "Balanced",
|
|
149
|
+
"mode_disabled": "Disable writing",
|
|
150
|
+
"mode_custom": "Custom interval",
|
|
151
|
+
"interval": "Write interval",
|
|
152
|
+
"unit_seconds": "seconds",
|
|
153
|
+
"unit_minutes": "minutes",
|
|
154
|
+
"unit_hours": "hours",
|
|
155
|
+
"unit_days": "days",
|
|
156
|
+
"disabled_tip": "Writing to disk is disabled (File Cache Control of the KNX gateway): at every restart of Node-RED, all the current GA values and the data saved by the KNX Ultimate nodes will be lost.",
|
|
157
|
+
"description": "Sets how often KNX Ultimate writes its files to disk (GA values, Scene Controller scenes, AutoResponder values, Logger file, Viewer history), to reduce the wear of SD cards. Files are written only when their content has changed. The log is not affected: use the log level for it.<br/><b>Freshness priority</b>: changes are saved every 5 seconds.<br/><b>Balanced</b>: changes are saved only when the gateway connects or disconnects, and when Node-RED stops or the gateway is redeployed.<br/><b>Disable writing</b>: nothing is written to disk.<br/><b>Custom interval</b>: changes are saved at the chosen interval (5 seconds to 30 days), and when Node-RED stops or the gateway is redeployed."
|
|
156
158
|
}
|
|
157
159
|
}
|
|
158
160
|
}
|