node-red-contrib-knx-ultimate 4.3.5 → 4.3.7
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 +13 -0
- package/nodes/knxUltimate-config.js +45 -10
- package/nodes/knxUltimate.html +71 -35
- package/nodes/knxUltimateAI.html +87 -106
- package/nodes/knxUltimateAI.js +345 -23
- package/nodes/locales/de/knxUltimateAI.html +18 -11
- package/nodes/locales/de/knxUltimateAI.json +9 -12
- package/nodes/locales/en/knxUltimateAI.html +18 -11
- package/nodes/locales/en/knxUltimateAI.json +9 -12
- package/nodes/locales/es/knxUltimateAI.html +18 -11
- package/nodes/locales/es/knxUltimateAI.json +9 -12
- package/nodes/locales/fr/knxUltimateAI.html +18 -11
- package/nodes/locales/fr/knxUltimateAI.json +9 -12
- package/nodes/locales/it/knxUltimateAI.html +18 -11
- package/nodes/locales/it/knxUltimateAI.json +9 -12
- package/nodes/locales/zh-CN/knxUltimateAI.html +18 -11
- package/nodes/locales/zh-CN/knxUltimateAI.json +9 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,19 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
+
**Version 4.3.7** - April 2026<br/>
|
|
10
|
+
|
|
11
|
+
- FIX: **KNX DEVICE** in universal mode (`listenAllGA`) now falls back to `raw` instead of raising a datapoint-detection error when no ETS DPT is available and automatic inference fails; raw bytes remain available in `msg.knx.rawValue`.<br/>
|
|
12
|
+
- NEW: **KNX AI** can now optionally archive captured telegrams to disk under `knxultimatestorage`, with configurable retention in days and automatic reuse of the archive for `Ask` queries.<br/>
|
|
13
|
+
- CHANGE: **KNX AI** `Ask` now uses the disk archive by default when enabled, honoring explicit time references and otherwise searching the last 24 hours plus current RAM events.<br/>
|
|
14
|
+
- CHANGE: **KNX AI** flow context for the AI prompt now includes the whole **Node-RED project inventory**, not only KNX nodes or the current flow, so `function`/`change`/`inject`/`template` nodes with KNX-related logic are visible to the assistant.<br/>
|
|
15
|
+
- UI: **KNX AI** editor options were reorganized into clearer sections, with technical tuning moved under **Advanced**, several low-value LLM tuning fields removed from the editor, and localized tab labels/help/docs updated in all supported languages.<br/>
|
|
16
|
+
- UI: **KNX AI Web Assistant** `Ask` panel now uses the full available page width instead of being capped to half-page width on desktop.<br/>
|
|
17
|
+
|
|
18
|
+
**Version 4.3.6** - April 2026<br/>
|
|
19
|
+
|
|
20
|
+
- UI: when **KNX DEVICE** is set to **`dpt = raw`**, the editor now hides decoded-payload options that do not apply to raw telegrams, including **RBE**, **periodic send**, **format numeric values**, manual write button modes, and **notifyreadrequestalsorespondtobus**.<br/>
|
|
21
|
+
|
|
9
22
|
**Version 4.3.5** - April 2026<br/>
|
|
10
23
|
|
|
11
24
|
- NEW: **KNX DEVICE** now supports explicit **`dpt = raw`** mode for incoming telegrams: decoding is skipped, `msg.payload` is `null`, and raw bytes remain available in `msg.knx.rawValue`.<br/>
|
|
@@ -2067,6 +2067,15 @@ module.exports = (RED) => {
|
|
|
2067
2067
|
}
|
|
2068
2068
|
|
|
2069
2069
|
const isRawMode = typeof _inputDpt === 'string' && _inputDpt.trim().toLowerCase() === 'raw'
|
|
2070
|
+
const isUniversalNode = _oNode?.listenallga === true || _oNode?.listenallga === 'true'
|
|
2071
|
+
const hasKnownInputDpt = !(_inputDpt === null || _inputDpt === undefined || _inputDpt === '')
|
|
2072
|
+
const shouldFallbackToRaw = isUniversalNode && !hasKnownInputDpt
|
|
2073
|
+
const setRawModeMetadata = () => {
|
|
2074
|
+
sInputDpt = 'raw'
|
|
2075
|
+
sPayloadmeasureunit = ''
|
|
2076
|
+
sDptdesc = 'Raw value'
|
|
2077
|
+
sPayloadsubtypevalue = ''
|
|
2078
|
+
}
|
|
2070
2079
|
|
|
2071
2080
|
const errorMessage = {
|
|
2072
2081
|
topic: _outputtopic,
|
|
@@ -2091,14 +2100,43 @@ module.exports = (RED) => {
|
|
|
2091
2100
|
// Resolve DPT and convert value if available
|
|
2092
2101
|
if (_Rawvalue !== null) {
|
|
2093
2102
|
if (isRawMode) {
|
|
2094
|
-
|
|
2095
|
-
sPayloadmeasureunit = ''
|
|
2096
|
-
sDptdesc = 'Raw value'
|
|
2097
|
-
sPayloadsubtypevalue = ''
|
|
2103
|
+
setRawModeMetadata()
|
|
2098
2104
|
} else {
|
|
2099
2105
|
try {
|
|
2100
|
-
sInputDpt =
|
|
2106
|
+
sInputDpt = !hasKnownInputDpt ? tryToFigureOutDataPointFromRawValue(_Rawvalue) : _inputDpt
|
|
2101
2107
|
} catch (error) {
|
|
2108
|
+
if (shouldFallbackToRaw) {
|
|
2109
|
+
setRawModeMetadata()
|
|
2110
|
+
jsValue = null
|
|
2111
|
+
node.sysLogger?.debug(`buildInputMessage: falling back to RAW for universal node ${_oNode?.id || ''} destination ${_destGA}`)
|
|
2112
|
+
try {
|
|
2113
|
+
const finalMessage = {
|
|
2114
|
+
topic: _outputtopic,
|
|
2115
|
+
devicename: typeof _devicename !== 'undefined' ? _devicename : '',
|
|
2116
|
+
payload: jsValue,
|
|
2117
|
+
payloadmeasureunit: sPayloadmeasureunit,
|
|
2118
|
+
payloadsubtypevalue: sPayloadsubtypevalue,
|
|
2119
|
+
gainfo,
|
|
2120
|
+
echoed: _echoed,
|
|
2121
|
+
repeated: _repeated === true,
|
|
2122
|
+
repeat: _repeated === true,
|
|
2123
|
+
knx: {
|
|
2124
|
+
event: _event,
|
|
2125
|
+
dpt: sInputDpt,
|
|
2126
|
+
dptdesc: sDptdesc,
|
|
2127
|
+
source: _srcGA,
|
|
2128
|
+
destination: _destGA,
|
|
2129
|
+
rawValue: _Rawvalue,
|
|
2130
|
+
repeated: _repeated === true,
|
|
2131
|
+
repeat: _repeated === true
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
return finalMessage
|
|
2135
|
+
} catch (buildError) {
|
|
2136
|
+
node.sysLogger?.error('buildInputMessage error: ' + buildError.message)
|
|
2137
|
+
return errorMessage
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2102
2140
|
// Here comes if no datapoint has beeen found
|
|
2103
2141
|
node.sysLogger?.error(
|
|
2104
2142
|
'buildInputMessage: Error returning from tryToFigureOutDataPointFromRawValue. Device ' +
|
|
@@ -2216,11 +2254,8 @@ module.exports = (RED) => {
|
|
|
2216
2254
|
}
|
|
2217
2255
|
} else {
|
|
2218
2256
|
// Don't care, it's a READ REQUEST
|
|
2219
|
-
if (isRawMode) {
|
|
2220
|
-
|
|
2221
|
-
sPayloadmeasureunit = ''
|
|
2222
|
-
sDptdesc = 'Raw value'
|
|
2223
|
-
sPayloadsubtypevalue = ''
|
|
2257
|
+
if (isRawMode || shouldFallbackToRaw) {
|
|
2258
|
+
setRawModeMetadata()
|
|
2224
2259
|
}
|
|
2225
2260
|
}
|
|
2226
2261
|
|
package/nodes/knxUltimate.html
CHANGED
|
@@ -171,16 +171,24 @@
|
|
|
171
171
|
$buttonToggleInitial.val(coerceBoolean(node.buttonToggleInitial) ? 'true' : 'false');
|
|
172
172
|
$buttonStaticValue.val(node.buttonStaticValue || '');
|
|
173
173
|
|
|
174
|
+
const isRawDptSelected = () => String($("#node-input-dpt").val() || '').trim().toLowerCase() === 'raw';
|
|
175
|
+
|
|
174
176
|
const refreshButtonOptions = () => {
|
|
175
177
|
const enabled = $buttonEnabled.prop('checked');
|
|
176
|
-
const
|
|
178
|
+
const rawMode = isRawDptSelected();
|
|
179
|
+
let mode = $buttonMode.val() || 'read';
|
|
180
|
+
if (rawMode && mode !== 'read') {
|
|
181
|
+
mode = 'read';
|
|
182
|
+
$buttonMode.val('read');
|
|
183
|
+
}
|
|
184
|
+
$buttonMode.find("option[value='toggle'], option[value='value']").prop('disabled', rawMode);
|
|
177
185
|
if (enabled) {
|
|
178
186
|
$buttonOptions.show();
|
|
179
187
|
} else {
|
|
180
188
|
$buttonOptions.hide();
|
|
181
189
|
}
|
|
182
|
-
$buttonToggleRow.toggle(enabled && mode === 'toggle');
|
|
183
|
-
$buttonValueRow.toggle(enabled && mode === 'value');
|
|
190
|
+
$buttonToggleRow.toggle(enabled && !rawMode && mode === 'toggle');
|
|
191
|
+
$buttonValueRow.toggle(enabled && !rawMode && mode === 'value');
|
|
184
192
|
|
|
185
193
|
node.buttonEnabled = enabled;
|
|
186
194
|
node.buttonMode = mode;
|
|
@@ -188,6 +196,52 @@
|
|
|
188
196
|
node.buttonStaticValue = $buttonStaticValue.val();
|
|
189
197
|
};
|
|
190
198
|
|
|
199
|
+
const refreshRawModeUI = () => {
|
|
200
|
+
const rawMode = isRawDptSelected();
|
|
201
|
+
const isUniversal = $("#node-input-setTopicType").val() === 'listenAllGA';
|
|
202
|
+
|
|
203
|
+
if (isUniversal) {
|
|
204
|
+
refreshButtonOptions();
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (rawMode) {
|
|
209
|
+
$("#divOutputRBE").hide();
|
|
210
|
+
$("#node-input-outputRBE").val("false");
|
|
211
|
+
$("#divInputRBE").hide();
|
|
212
|
+
$("#node-input-inputRBE").val("false");
|
|
213
|
+
$("#divPeriodicSend").hide();
|
|
214
|
+
$("#divPeriodicSendInterval").hide();
|
|
215
|
+
$("#node-input-periodicSend").prop('checked', false);
|
|
216
|
+
$("#divnotifyreadrequestautoreact").hide();
|
|
217
|
+
$("#node-input-notifyreadrequestalsorespondtobus").prop('checked', false);
|
|
218
|
+
$("#divFormatSectionHeader").hide();
|
|
219
|
+
$("#divFormatMultiply").hide();
|
|
220
|
+
$("#divFormatDecimals").hide();
|
|
221
|
+
$("#divFormatNegative").hide();
|
|
222
|
+
} else {
|
|
223
|
+
$("#divOutputRBE").show();
|
|
224
|
+
$("#divInputRBE").show();
|
|
225
|
+
$("#divPeriodicSend").show();
|
|
226
|
+
$("#divFormatSectionHeader").show();
|
|
227
|
+
$("#divFormatMultiply").show();
|
|
228
|
+
$("#divFormatDecimals").show();
|
|
229
|
+
$("#divFormatNegative").show();
|
|
230
|
+
if ($("#node-input-periodicSend").is(':checked')) {
|
|
231
|
+
$("#divPeriodicSendInterval").show();
|
|
232
|
+
} else {
|
|
233
|
+
$("#divPeriodicSendInterval").hide();
|
|
234
|
+
}
|
|
235
|
+
if ($("#node-input-notifyreadrequest").is(":checked")) {
|
|
236
|
+
$("#divnotifyreadrequestautoreact").show();
|
|
237
|
+
} else {
|
|
238
|
+
$("#divnotifyreadrequestautoreact").hide();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
refreshButtonOptions();
|
|
243
|
+
};
|
|
244
|
+
|
|
191
245
|
$buttonEnabled.on('change', refreshButtonOptions);
|
|
192
246
|
$buttonMode.on('change', refreshButtonOptions);
|
|
193
247
|
$buttonToggleInitial.on('change', refreshButtonOptions);
|
|
@@ -773,6 +827,7 @@ return msg;`
|
|
|
773
827
|
$("#node-input-dpt").val(node.dpt);
|
|
774
828
|
// Load help sample
|
|
775
829
|
knxUltimateDptsGetHelp(node.dpt, true);
|
|
830
|
+
refreshRawModeUI();
|
|
776
831
|
})
|
|
777
832
|
}
|
|
778
833
|
|
|
@@ -791,7 +846,9 @@ return msg;`
|
|
|
791
846
|
}
|
|
792
847
|
|
|
793
848
|
$("#node-input-notifyreadrequest").on('change', function () {
|
|
794
|
-
if (
|
|
849
|
+
if (isRawDptSelected()) {
|
|
850
|
+
$("#divnotifyreadrequestautoreact").hide();
|
|
851
|
+
} else if ($("#node-input-notifyreadrequest").is(":checked")) {
|
|
795
852
|
if ($("#node-input-setTopicType").val() === "listenAllGA") {
|
|
796
853
|
} else {
|
|
797
854
|
$("#divnotifyreadrequestautoreact").show();
|
|
@@ -918,14 +975,7 @@ return msg;`
|
|
|
918
975
|
};
|
|
919
976
|
$("#divDatapointSelection").show();
|
|
920
977
|
$("#divNode-input-initialread").show();
|
|
921
|
-
|
|
922
|
-
$("#divInputRBE").show()
|
|
923
|
-
$("#divPeriodicSend").show()
|
|
924
|
-
if ($("#node-input-periodicSend").is(':checked')) {
|
|
925
|
-
$("#divPeriodicSendInterval").show()
|
|
926
|
-
} else {
|
|
927
|
-
$("#divPeriodicSendInterval").hide()
|
|
928
|
-
}
|
|
978
|
+
refreshRawModeUI()
|
|
929
979
|
} else if ($("#node-input-setTopicType").val() === 'listenAllGA') {
|
|
930
980
|
$("#node-input-topic").hide();
|
|
931
981
|
$("#divDatapointSelection").hide()
|
|
@@ -947,21 +997,9 @@ return msg;`
|
|
|
947
997
|
|
|
948
998
|
// 15/09/2020 Supergiovane, load the help sample of the current datapoint
|
|
949
999
|
knxUltimateDptsGetHelp($("#node-input-dpt").val(), false); // 15/09/2020 Supergiovane, load sample help
|
|
950
|
-
$("#divOutputRBE").show()
|
|
951
|
-
$("#divInputRBE").show()
|
|
952
1000
|
$("#divTopic").show()
|
|
953
|
-
$("#divPeriodicSend").show()
|
|
954
|
-
if ($("#node-input-periodicSend").is(':checked')) {
|
|
955
|
-
$("#divPeriodicSendInterval").show()
|
|
956
|
-
} else {
|
|
957
|
-
$("#divPeriodicSendInterval").hide()
|
|
958
|
-
}
|
|
959
|
-
if ($("#node-input-notifyreadrequest").is(":checked")) {
|
|
960
|
-
$("#divnotifyreadrequestautoreact").show();
|
|
961
|
-
} else {
|
|
962
|
-
$("#divnotifyreadrequestautoreact").hide();
|
|
963
|
-
}
|
|
964
1001
|
$("#divNode-input-initialread").show();
|
|
1002
|
+
refreshRawModeUI()
|
|
965
1003
|
|
|
966
1004
|
$("#node-input-topic").prop('placeholder', $("#node-input-setTopicType").val());
|
|
967
1005
|
if ($("#node-input-topic").val() === '') $("#node-input-topic").val('MyVariable');
|
|
@@ -1011,6 +1049,7 @@ return msg;`
|
|
|
1011
1049
|
$("#node-input-dpt").on("change", function (event) {
|
|
1012
1050
|
// Load help sample
|
|
1013
1051
|
knxUltimateDptsGetHelp(event.target.value, false);
|
|
1052
|
+
refreshRawModeUI();
|
|
1014
1053
|
});
|
|
1015
1054
|
// ###########################
|
|
1016
1055
|
|
|
@@ -1033,12 +1072,7 @@ return msg;`
|
|
|
1033
1072
|
$("#divPeriodicSendInterval").hide()
|
|
1034
1073
|
$("#node-input-periodicSend").prop('checked', false)
|
|
1035
1074
|
} else {
|
|
1036
|
-
|
|
1037
|
-
if ($("#node-input-periodicSend").is(':checked')) {
|
|
1038
|
-
$("#divPeriodicSendInterval").show()
|
|
1039
|
-
} else {
|
|
1040
|
-
$("#divPeriodicSendInterval").hide()
|
|
1041
|
-
}
|
|
1075
|
+
refreshRawModeUI()
|
|
1042
1076
|
}
|
|
1043
1077
|
} catch (e) { }
|
|
1044
1078
|
|
|
@@ -1059,6 +1093,8 @@ return msg;`
|
|
|
1059
1093
|
}
|
|
1060
1094
|
} catch (e) { }
|
|
1061
1095
|
|
|
1096
|
+
refreshRawModeUI();
|
|
1097
|
+
|
|
1062
1098
|
},
|
|
1063
1099
|
oneditsave: function () {
|
|
1064
1100
|
// Return to the info tab
|
|
@@ -1392,12 +1428,12 @@ return msg;`
|
|
|
1392
1428
|
</div>
|
|
1393
1429
|
</dd>
|
|
1394
1430
|
</div>
|
|
1395
|
-
<div class="form-row">
|
|
1431
|
+
<div class="form-row" id="divFormatSectionHeader">
|
|
1396
1432
|
<dt>
|
|
1397
1433
|
<i class="fa fa-sort-numeric-asc"></i> Format numeric values coming from the KNX BUS
|
|
1398
1434
|
</dt>
|
|
1399
1435
|
</div>
|
|
1400
|
-
<div class="form-row">
|
|
1436
|
+
<div class="form-row" id="divFormatMultiply">
|
|
1401
1437
|
<label style="width:180px" for="node-input-formatmultiplyvalue">
|
|
1402
1438
|
<i class="fa fa-calculator"></i>
|
|
1403
1439
|
<span data-i18n="knxUltimate.properties.node-input-formatmultiplyvalue"></span>
|
|
@@ -1412,7 +1448,7 @@ return msg;`
|
|
|
1412
1448
|
<option value=1000 data-i18n="knxUltimate.selectlists.Multiply_multiply1000"></option>
|
|
1413
1449
|
</select>
|
|
1414
1450
|
</div>
|
|
1415
|
-
<div class="form-row">
|
|
1451
|
+
<div class="form-row" id="divFormatDecimals">
|
|
1416
1452
|
<label style="width:180px" for="node-input-formatdecimalsvalue">
|
|
1417
1453
|
<i class="fa fa-expand"></i>
|
|
1418
1454
|
<span data-i18n="knxUltimate.properties.node-input-formatdecimalsvalue"></span>
|
|
@@ -1426,7 +1462,7 @@ return msg;`
|
|
|
1426
1462
|
<option value=4 data-i18n="knxUltimate.selectlists.Decimals_round4"></option>
|
|
1427
1463
|
</select>
|
|
1428
1464
|
</div>
|
|
1429
|
-
<div class="form-row">
|
|
1465
|
+
<div class="form-row" id="divFormatNegative">
|
|
1430
1466
|
<label style="width:180px" for="node-input-formatnegativevalue">
|
|
1431
1467
|
<i class="fa fa-minus-circle"></i>
|
|
1432
1468
|
<span data-i18n="knxUltimate.properties.node-input-formatnegativevalue"></span>
|
package/nodes/knxUltimateAI.html
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
align-items: flex-start;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
#knx-ai-ollama-install-row
|
|
12
|
+
#knx-ai-ollama-install-row>label {
|
|
13
13
|
padding-top: 6px;
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
@media (max-width: 900px) {
|
|
35
|
-
#knx-ai-ollama-install-row
|
|
35
|
+
#knx-ai-ollama-install-row>label {
|
|
36
36
|
width: 100% !important;
|
|
37
37
|
padding-top: 0;
|
|
38
38
|
margin-bottom: 6px;
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
|
|
65
65
|
analysisWindowSec: { value: 120, required: true, validate: RED.validators.number() },
|
|
66
66
|
historyWindowSec: { value: 600, required: true, validate: RED.validators.number() },
|
|
67
|
+
historyStoreToDisk: { value: true },
|
|
68
|
+
historyStoreRetentionDays: { value: 10, required: true, validate: RED.validators.number() },
|
|
67
69
|
emitIntervalSec: { value: 0, required: true, validate: RED.validators.number() },
|
|
68
70
|
topN: { value: 10, required: true, validate: RED.validators.number() },
|
|
69
71
|
maxEvents: { value: 50000, required: true, validate: RED.validators.number() },
|
|
@@ -84,17 +86,10 @@
|
|
|
84
86
|
llmBaseUrl: { value: "https://api.openai.com/v1/chat/completions" },
|
|
85
87
|
llmModel: { value: "gpt-5.4" },
|
|
86
88
|
llmSystemPrompt: { value: "" },
|
|
87
|
-
llmTemperature: { value: 0.2, required: false, validate: RED.validators.number() },
|
|
88
|
-
llmMaxTokens: { value: 50000, required: false, validate: RED.validators.number() },
|
|
89
|
-
llmTimeoutMs: { value: 120000, required: false, validate: RED.validators.number() },
|
|
90
|
-
llmMaxEventsInPrompt: { value: 120, required: false, validate: RED.validators.number() },
|
|
91
89
|
llmIncludeRaw: { value: false },
|
|
92
90
|
llmIncludeFlowContext: { value: true },
|
|
93
|
-
llmMaxFlowNodesInPrompt: { value: 400, required: false, validate: RED.validators.number() },
|
|
94
91
|
llmIncludeDocsSnippets: { value: true },
|
|
95
|
-
llmDocsLanguage: { value: "en" }
|
|
96
|
-
llmDocsMaxSnippets: { value: 5, required: false, validate: RED.validators.number() },
|
|
97
|
-
llmDocsMaxChars: { value: 60000, required: false, validate: RED.validators.number() }
|
|
92
|
+
llmDocsLanguage: { value: "en" }
|
|
98
93
|
},
|
|
99
94
|
credentials: {
|
|
100
95
|
llmApiKey: { type: "password" }
|
|
@@ -121,14 +116,6 @@
|
|
|
121
116
|
const OPENAI_COMPAT_DEFAULT_MODELS = ["gpt-5.4", "gpt-4o-mini"];
|
|
122
117
|
const OLLAMA_DEFAULT_MODEL = "llama3.1";
|
|
123
118
|
|
|
124
|
-
const $accordion = $("#knx-ai-accordion");
|
|
125
|
-
const $llmContent = $accordion.find("#node-input-llmEnabled").closest("#knx-ai-accordion > div").first();
|
|
126
|
-
const $llmHeader = $llmContent.prev("h3");
|
|
127
|
-
if ($llmHeader.length && $llmContent.length) {
|
|
128
|
-
$llmContent.prependTo($accordion);
|
|
129
|
-
$llmHeader.prependTo($accordion);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
119
|
$("#knx-ai-accordion").accordion({
|
|
133
120
|
header: "h3",
|
|
134
121
|
heightStyle: "content",
|
|
@@ -138,14 +125,26 @@
|
|
|
138
125
|
|
|
139
126
|
const toggleLLM = () => {
|
|
140
127
|
const enabled = $("#node-input-llmEnabled").is(":checked");
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
} else {
|
|
144
|
-
$("#knx-ai-llm-settings").hide();
|
|
145
|
-
}
|
|
128
|
+
$("#knx-ai-llm-connection-settings").toggle(enabled);
|
|
129
|
+
$("#knx-ai-llm-context-settings").toggle(enabled);
|
|
146
130
|
};
|
|
147
131
|
$("#node-input-llmEnabled").on("change", toggleLLM);
|
|
132
|
+
|
|
133
|
+
const toggleHistoryArchive = () => {
|
|
134
|
+
const enabled = $("#node-input-historyStoreToDisk").is(":checked");
|
|
135
|
+
$("#knx-ai-history-retention-row").toggle(enabled);
|
|
136
|
+
};
|
|
137
|
+
$("#node-input-historyStoreToDisk").on("change", toggleHistoryArchive);
|
|
138
|
+
|
|
139
|
+
const toggleDocsContext = () => {
|
|
140
|
+
const enabled = $("#node-input-llmIncludeDocsSnippets").is(":checked");
|
|
141
|
+
$("#knx-ai-docs-language-row").toggle(enabled);
|
|
142
|
+
};
|
|
143
|
+
$("#node-input-llmIncludeDocsSnippets").on("change", toggleDocsContext);
|
|
144
|
+
|
|
148
145
|
toggleLLM();
|
|
146
|
+
toggleHistoryArchive();
|
|
147
|
+
toggleDocsContext();
|
|
149
148
|
|
|
150
149
|
const nodeId = this.id;
|
|
151
150
|
const resolveAdminRoot = () => {
|
|
@@ -422,74 +421,42 @@
|
|
|
422
421
|
</div>
|
|
423
422
|
</div>
|
|
424
423
|
|
|
425
|
-
<h3><span data-i18n="knxUltimateAI.sections.
|
|
424
|
+
<h3><span data-i18n="knxUltimateAI.sections.storage"></span></h3>
|
|
426
425
|
<div>
|
|
427
|
-
<div class="form-row">
|
|
428
|
-
<label style="width:290px" for="node-input-analysisWindowSec"><i class="fa fa-clock-o"></i> <span data-i18n="knxUltimateAI.properties.analysisWindowSec"></span></label>
|
|
429
|
-
<input style="width:90px" type="number" id="node-input-analysisWindowSec">
|
|
430
|
-
</div>
|
|
431
426
|
<div class="form-row">
|
|
432
427
|
<label style="width:290px" for="node-input-historyWindowSec"><i class="fa fa-history"></i> <span data-i18n="knxUltimateAI.properties.historyWindowSec"></span></label>
|
|
433
428
|
<input style="width:90px" type="number" id="node-input-historyWindowSec">
|
|
434
429
|
</div>
|
|
435
430
|
<div class="form-row">
|
|
436
|
-
<
|
|
437
|
-
<
|
|
431
|
+
<input type="checkbox" id="node-input-historyStoreToDisk" style="display:inline-block; width:auto; vertical-align:top;">
|
|
432
|
+
<label style="width:auto" for="node-input-historyStoreToDisk"> <span data-i18n="knxUltimateAI.properties.historyStoreToDisk"></span></label>
|
|
433
|
+
</div>
|
|
434
|
+
<div class="form-row" id="knx-ai-history-retention-row">
|
|
435
|
+
<label style="width:290px" for="node-input-historyStoreRetentionDays"><i class="fa fa-calendar"></i> <span data-i18n="knxUltimateAI.properties.historyStoreRetentionDays"></span></label>
|
|
436
|
+
<input style="width:90px" type="number" id="node-input-historyStoreRetentionDays">
|
|
438
437
|
</div>
|
|
439
438
|
<div class="form-row">
|
|
440
439
|
<label style="width:290px" for="node-input-emitIntervalSec"><i class="fa fa-send"></i> <span data-i18n="knxUltimateAI.properties.emitIntervalSec"></span></label>
|
|
441
440
|
<input style="width:90px" type="number" id="node-input-emitIntervalSec">
|
|
442
441
|
</div>
|
|
443
|
-
<div class="form-row">
|
|
444
|
-
<label style="width:290px" for="node-input-topN"><i class="fa fa-list-ol"></i> <span data-i18n="knxUltimateAI.properties.topN"></span></label>
|
|
445
|
-
<input style="width:90px" type="number" id="node-input-topN">
|
|
446
|
-
</div>
|
|
447
|
-
<div class="form-row">
|
|
448
|
-
<input type="checkbox" id="node-input-enablePattern" style="display:inline-block; width:auto; vertical-align:top;">
|
|
449
|
-
<label style="width:auto" for="node-input-enablePattern"> <span data-i18n="knxUltimateAI.properties.enablePattern"></span></label>
|
|
450
|
-
</div>
|
|
451
|
-
<div class="form-row">
|
|
452
|
-
<label style="width:290px" for="node-input-patternMaxLagMs"><i class="fa fa-arrows-h"></i> <span data-i18n="knxUltimateAI.properties.patternMaxLagMs"></span></label>
|
|
453
|
-
<input style="width:120px" type="number" id="node-input-patternMaxLagMs">
|
|
454
|
-
</div>
|
|
455
|
-
<div class="form-row">
|
|
456
|
-
<label style="width:290px" for="node-input-patternMinCount"><i class="fa fa-filter"></i> <span data-i18n="knxUltimateAI.properties.patternMinCount"></span></label>
|
|
457
|
-
<input style="width:90px" type="number" id="node-input-patternMinCount">
|
|
458
|
-
</div>
|
|
459
442
|
</div>
|
|
460
443
|
|
|
461
|
-
<h3><span data-i18n="knxUltimateAI.sections.
|
|
444
|
+
<h3><span data-i18n="knxUltimateAI.sections.detection"></span></h3>
|
|
462
445
|
<div>
|
|
463
446
|
<div class="form-row">
|
|
464
|
-
<
|
|
465
|
-
<
|
|
466
|
-
</div>
|
|
467
|
-
<div class="form-row">
|
|
468
|
-
<label style="width:290px" for="node-input-maxTelegramPerSecOverall"><i class="fa fa-tachometer"></i> <span data-i18n="knxUltimateAI.properties.maxTelegramPerSecOverall"></span></label>
|
|
469
|
-
<input style="width:90px" type="number" id="node-input-maxTelegramPerSecOverall">
|
|
470
|
-
</div>
|
|
471
|
-
<div class="form-row">
|
|
472
|
-
<label style="width:290px" for="node-input-maxTelegramPerSecPerGA"><i class="fa fa-bolt"></i> <span data-i18n="knxUltimateAI.properties.maxTelegramPerSecPerGA"></span></label>
|
|
473
|
-
<input style="width:90px" type="number" id="node-input-maxTelegramPerSecPerGA">
|
|
474
|
-
</div>
|
|
475
|
-
<div class="form-row">
|
|
476
|
-
<label style="width:290px" for="node-input-flapWindowSec"><i class="fa fa-exchange"></i> <span data-i18n="knxUltimateAI.properties.flapWindowSec"></span></label>
|
|
477
|
-
<input style="width:90px" type="number" id="node-input-flapWindowSec">
|
|
478
|
-
</div>
|
|
479
|
-
<div class="form-row">
|
|
480
|
-
<label style="width:290px" for="node-input-flapMaxChanges"><i class="fa fa-random"></i> <span data-i18n="knxUltimateAI.properties.flapMaxChanges"></span></label>
|
|
481
|
-
<input style="width:90px" type="number" id="node-input-flapMaxChanges">
|
|
447
|
+
<input type="checkbox" id="node-input-enablePattern" style="display:inline-block; width:auto; vertical-align:top;">
|
|
448
|
+
<label style="width:auto" for="node-input-enablePattern"> <span data-i18n="knxUltimateAI.properties.enablePattern"></span></label>
|
|
482
449
|
</div>
|
|
483
450
|
</div>
|
|
484
451
|
|
|
485
|
-
<h3><span data-i18n="knxUltimateAI.sections.
|
|
452
|
+
<h3><span data-i18n="knxUltimateAI.sections.llmConnection"></span></h3>
|
|
486
453
|
<div>
|
|
487
454
|
<div class="form-row">
|
|
488
455
|
<input type="checkbox" id="node-input-llmEnabled" style="display:inline-block; width:auto; vertical-align:top;">
|
|
489
456
|
<label style="width:auto" for="node-input-llmEnabled"> <span data-i18n="knxUltimateAI.properties.llmEnabled"></span></label>
|
|
490
457
|
</div>
|
|
491
458
|
|
|
492
|
-
<div id="knx-ai-llm-settings">
|
|
459
|
+
<div id="knx-ai-llm-connection-settings">
|
|
493
460
|
<div class="form-row">
|
|
494
461
|
<label style="width:290px" for="node-input-llmProvider"><i class="fa fa-cog"></i> <span data-i18n="knxUltimateAI.properties.llmProvider"></span></label>
|
|
495
462
|
<select style="width:100%" id="node-input-llmProvider">
|
|
@@ -540,31 +507,12 @@
|
|
|
540
507
|
<code>ollama pull llama3.1</code>
|
|
541
508
|
</div>
|
|
542
509
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
<textarea style="width:100%; height:110px;" id="node-input-llmSystemPrompt" data-i18n="[placeholder]knxUltimateAI.placeholder.llmSystemPrompt"></textarea>
|
|
546
|
-
</div>
|
|
547
|
-
|
|
548
|
-
<div class="form-row">
|
|
549
|
-
<label style="width:290px" for="node-input-llmTemperature"><i class="fa fa-sliders"></i> <span data-i18n="knxUltimateAI.properties.llmTemperature"></span></label>
|
|
550
|
-
<input style="width:90px" type="number" id="node-input-llmTemperature">
|
|
551
|
-
</div>
|
|
552
|
-
|
|
553
|
-
<div class="form-row">
|
|
554
|
-
<label style="width:290px" for="node-input-llmMaxTokens"><i class="fa fa-align-left"></i> <span data-i18n="knxUltimateAI.properties.llmMaxTokens"></span></label>
|
|
555
|
-
<input style="width:90px" type="number" id="node-input-llmMaxTokens">
|
|
556
|
-
</div>
|
|
557
|
-
|
|
558
|
-
<div class="form-row">
|
|
559
|
-
<label style="width:290px" for="node-input-llmTimeoutMs"><i class="fa fa-hourglass-half"></i> <span data-i18n="knxUltimateAI.properties.llmTimeoutMs"></span></label>
|
|
560
|
-
<input style="width:120px" type="number" id="node-input-llmTimeoutMs">
|
|
561
|
-
</div>
|
|
562
|
-
|
|
563
|
-
<div class="form-row">
|
|
564
|
-
<label style="width:290px" for="node-input-llmMaxEventsInPrompt"><i class="fa fa-list"></i> <span data-i18n="knxUltimateAI.properties.llmMaxEventsInPrompt"></span></label>
|
|
565
|
-
<input style="width:90px" type="number" id="node-input-llmMaxEventsInPrompt">
|
|
566
|
-
</div>
|
|
510
|
+
</div>
|
|
511
|
+
</div>
|
|
567
512
|
|
|
513
|
+
<h3><span data-i18n="knxUltimateAI.sections.llmContext"></span></h3>
|
|
514
|
+
<div>
|
|
515
|
+
<div id="knx-ai-llm-context-settings">
|
|
568
516
|
<div class="form-row">
|
|
569
517
|
<input type="checkbox" id="node-input-llmIncludeRaw" style="display:inline-block; width:auto; vertical-align:top;">
|
|
570
518
|
<label style="width:auto" for="node-input-llmIncludeRaw"> <span data-i18n="knxUltimateAI.properties.llmIncludeRaw"></span></label>
|
|
@@ -575,17 +523,12 @@
|
|
|
575
523
|
<label style="width:auto" for="node-input-llmIncludeFlowContext"> <span data-i18n="knxUltimateAI.properties.llmIncludeFlowContext"></span></label>
|
|
576
524
|
</div>
|
|
577
525
|
|
|
578
|
-
<div class="form-row">
|
|
579
|
-
<label style="width:290px" for="node-input-llmMaxFlowNodesInPrompt"><i class="fa fa-sitemap"></i> <span data-i18n="knxUltimateAI.properties.llmMaxFlowNodesInPrompt"></span></label>
|
|
580
|
-
<input style="width:90px" type="number" id="node-input-llmMaxFlowNodesInPrompt">
|
|
581
|
-
</div>
|
|
582
|
-
|
|
583
526
|
<div class="form-row">
|
|
584
527
|
<input type="checkbox" id="node-input-llmIncludeDocsSnippets" style="display:inline-block; width:auto; vertical-align:top;">
|
|
585
528
|
<label style="width:auto" for="node-input-llmIncludeDocsSnippets"> <span data-i18n="knxUltimateAI.properties.llmIncludeDocsSnippets"></span></label>
|
|
586
529
|
</div>
|
|
587
530
|
|
|
588
|
-
<div class="form-row">
|
|
531
|
+
<div class="form-row" id="knx-ai-docs-language-row">
|
|
589
532
|
<label style="width:290px" for="node-input-llmDocsLanguage"><i class="fa fa-language"></i> <span data-i18n="knxUltimateAI.properties.llmDocsLanguage"></span></label>
|
|
590
533
|
<select style="width:100%" id="node-input-llmDocsLanguage">
|
|
591
534
|
<option value="it">Italiano</option>
|
|
@@ -596,16 +539,54 @@
|
|
|
596
539
|
<option value="zh-CN">简体中文</option>
|
|
597
540
|
</select>
|
|
598
541
|
</div>
|
|
542
|
+
</div>
|
|
543
|
+
</div>
|
|
599
544
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
545
|
+
<h3><span data-i18n="knxUltimateAI.sections.advanced"></span></h3>
|
|
546
|
+
<div>
|
|
547
|
+
<div class="form-row">
|
|
548
|
+
<label style="width:290px" for="node-input-analysisWindowSec"><i class="fa fa-clock-o"></i> <span data-i18n="knxUltimateAI.properties.analysisWindowSec"></span></label>
|
|
549
|
+
<input style="width:90px" type="number" id="node-input-analysisWindowSec">
|
|
550
|
+
</div>
|
|
551
|
+
<div class="form-row">
|
|
552
|
+
<label style="width:290px" for="node-input-maxEvents"><i class="fa fa-bars"></i> <span data-i18n="knxUltimateAI.properties.maxEvents"></span></label>
|
|
553
|
+
<input style="width:90px" type="number" id="node-input-maxEvents">
|
|
554
|
+
</div>
|
|
555
|
+
<div class="form-row">
|
|
556
|
+
<label style="width:290px" for="node-input-topN"><i class="fa fa-list-ol"></i> <span data-i18n="knxUltimateAI.properties.topN"></span></label>
|
|
557
|
+
<input style="width:90px" type="number" id="node-input-topN">
|
|
558
|
+
</div>
|
|
559
|
+
<div class="form-row">
|
|
560
|
+
<label style="width:290px" for="node-input-patternMaxLagMs"><i class="fa fa-arrows-h"></i> <span data-i18n="knxUltimateAI.properties.patternMaxLagMs"></span></label>
|
|
561
|
+
<input style="width:120px" type="number" id="node-input-patternMaxLagMs">
|
|
562
|
+
</div>
|
|
563
|
+
<div class="form-row">
|
|
564
|
+
<label style="width:290px" for="node-input-patternMinCount"><i class="fa fa-filter"></i> <span data-i18n="knxUltimateAI.properties.patternMinCount"></span></label>
|
|
565
|
+
<input style="width:90px" type="number" id="node-input-patternMinCount">
|
|
566
|
+
</div>
|
|
567
|
+
<div class="form-row">
|
|
568
|
+
<label style="width:290px" for="node-input-rateWindowSec"><i class="fa fa-clock-o"></i> <span data-i18n="knxUltimateAI.properties.rateWindowSec"></span></label>
|
|
569
|
+
<input style="width:90px" type="number" id="node-input-rateWindowSec">
|
|
570
|
+
</div>
|
|
571
|
+
<div class="form-row">
|
|
572
|
+
<label style="width:290px" for="node-input-maxTelegramPerSecOverall"><i class="fa fa-tachometer"></i> <span data-i18n="knxUltimateAI.properties.maxTelegramPerSecOverall"></span></label>
|
|
573
|
+
<input style="width:90px" type="number" id="node-input-maxTelegramPerSecOverall">
|
|
574
|
+
</div>
|
|
575
|
+
<div class="form-row">
|
|
576
|
+
<label style="width:290px" for="node-input-maxTelegramPerSecPerGA"><i class="fa fa-bolt"></i> <span data-i18n="knxUltimateAI.properties.maxTelegramPerSecPerGA"></span></label>
|
|
577
|
+
<input style="width:90px" type="number" id="node-input-maxTelegramPerSecPerGA">
|
|
578
|
+
</div>
|
|
579
|
+
<div class="form-row">
|
|
580
|
+
<label style="width:290px" for="node-input-flapWindowSec"><i class="fa fa-exchange"></i> <span data-i18n="knxUltimateAI.properties.flapWindowSec"></span></label>
|
|
581
|
+
<input style="width:90px" type="number" id="node-input-flapWindowSec">
|
|
582
|
+
</div>
|
|
583
|
+
<div class="form-row">
|
|
584
|
+
<label style="width:290px" for="node-input-flapMaxChanges"><i class="fa fa-random"></i> <span data-i18n="knxUltimateAI.properties.flapMaxChanges"></span></label>
|
|
585
|
+
<input style="width:90px" type="number" id="node-input-flapMaxChanges">
|
|
586
|
+
</div>
|
|
587
|
+
<div class="form-row">
|
|
588
|
+
<label style="width:290px" for="node-input-llmSystemPrompt"><i class="fa fa-commenting-o"></i> <span data-i18n="knxUltimateAI.properties.llmSystemPrompt"></span></label>
|
|
589
|
+
<textarea style="width:100%; height:110px;" id="node-input-llmSystemPrompt" data-i18n="[placeholder]knxUltimateAI.placeholder.llmSystemPrompt"></textarea>
|
|
609
590
|
</div>
|
|
610
591
|
</div>
|
|
611
592
|
</div>
|