node-red-contrib-knx-ultimate 6.3.22 → 6.3.25
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 +19 -0
- package/examples/IoT Bridge - Modbus Flex Adapter.json +361 -0
- package/examples/KNX AI - Telegrambot Direct Chat.json +1 -17
- package/nodes/knxUltimate-config.js +13 -4
- package/nodes/knxUltimateAI.html +142 -15
- package/nodes/knxUltimateAI.js +734 -163
- package/nodes/knxUltimateIoTBridge.html +349 -20
- package/nodes/knxUltimateIoTBridge.js +474 -44
- package/nodes/locales/de/knxUltimateAI.html +26 -8
- package/nodes/locales/de/knxUltimateAI.json +11 -1
- package/nodes/locales/de/knxUltimateIoTBridge.html +28 -2
- package/nodes/locales/de/knxUltimateIoTBridge.json +20 -2
- package/nodes/locales/en/knxUltimateAI.html +26 -8
- package/nodes/locales/en/knxUltimateAI.json +11 -1
- package/nodes/locales/en/knxUltimateIoTBridge.html +28 -2
- package/nodes/locales/en/knxUltimateIoTBridge.json +20 -2
- package/nodes/locales/es/knxUltimateAI.html +26 -8
- package/nodes/locales/es/knxUltimateAI.json +11 -1
- package/nodes/locales/es/knxUltimateIoTBridge.html +28 -2
- package/nodes/locales/es/knxUltimateIoTBridge.json +20 -2
- package/nodes/locales/fr/knxUltimateAI.html +26 -8
- package/nodes/locales/fr/knxUltimateAI.json +11 -1
- package/nodes/locales/fr/knxUltimateIoTBridge.html +28 -2
- package/nodes/locales/fr/knxUltimateIoTBridge.json +20 -2
- package/nodes/locales/it/knxUltimateAI.html +26 -8
- package/nodes/locales/it/knxUltimateAI.json +11 -1
- package/nodes/locales/it/knxUltimateIoTBridge.html +28 -2
- package/nodes/locales/it/knxUltimateIoTBridge.json +20 -2
- package/nodes/locales/zh-CN/knxUltimateAI.html +26 -8
- package/nodes/locales/zh-CN/knxUltimateAI.json +11 -1
- package/nodes/locales/zh-CN/knxUltimateIoTBridge.html +28 -2
- package/nodes/locales/zh-CN/knxUltimateIoTBridge.json +20 -2
- package/nodes/plugins/knxUltimateAI-vue/assets/app.css +1 -1
- package/nodes/plugins/knxUltimateAI-vue/assets/app.js +4 -4
- package/nodes/utils/knxAiChatContext.js +181 -84
- package/nodes/utils/knxAiEventHistory.js +275 -0
- package/package.json +3 -3
- package/resources/KNXAIChatAdapterMappings.js +14 -12
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,25 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
+
**Version 6.3.25** - August 2026<br/>
|
|
10
|
+
|
|
11
|
+
- **IoT Bridge — direct Modbus Flex adapter without a bundled Modbus client**: Modbus mappings can now emit the exact `modbus-flex-write` request consumed by `node-red-contrib-modbus` and decode `modbus-read` / `modbus-flex-getter` responses back to KNX. The protocol-specific editor asks only for Unit ID, zero-based address, Modbus area and Boolean/unsigned 16-bit/signed 16-bit format; FC1–FC6 and quantity are derived automatically. TCP/RTU connections, polling, queues and reconnects remain in the external Modbus nodes. KNX responses never become Modbus commands, write acknowledgements never become KNX state, unchanged polls can be suppressed with **Emit on change only**, and local KNX echoes are loop-protected. Existing scalar Modbus mappings remain on the legacy contract until explicitly switched to Flex. A safe manual example and the six localized help/wiki sets document the wiring and host-version compatibility.<br/>
|
|
12
|
+
- **Dependency cleanup — native asynchronous gateway DNS resolution**: replaced `dns-sync` and its obsolete `shelljs` → `glob@7` → `inflight` production chain with Node's built-in promise-based OS resolver. KNX gateway hostnames and `/etc/hosts` resolution remain supported in verbatim address order, while connection startup no longer launches a blocking child process.<br/>
|
|
13
|
+
|
|
14
|
+
**Version 6.3.24** - August 2026<br/>
|
|
15
|
+
|
|
16
|
+
- **KNX AI — working Telegram confirmation buttons**: changed the `windkh/node-red-contrib-telegrambot` preset from inline callbacks to a one-time Telegram reply keyboard. **Confirm** and **Cancel** now return as normal localized messages through the already connected `telegram receiver`, eliminating the silent no-op caused by a missing `callback_query` event node. Existing saved preset output mappings are upgraded at runtime, the keyboard is removed after the decision, and legacy callback events remain accepted. The importable direct-chat example no longer requires extra callback wiring; help and wiki documentation were updated in EN, IT, DE, FR, ES and zh-CN.<br/>
|
|
17
|
+
- **KNX AI — native CHAT learning memory**: replaced the verbose Markdown/JSON V2 learning file with the direct line-oriented `knxai-chat-context.knxctx` V3 format. Sessions, instructions, turns and camera watches are stored as editable tab-separated `SESSION`, `INSTRUCTION`, `TURN`, `CAMERA_WATCH` and `END_SESSION` records with escaped text fields, without JSON serialization or a regenerated preview. The Web UI keeps copy, download, restore, revision-safe save and protected reinitialization. Previous `.md` Markdown/JSON V2 and Base64 V1 files are deliberately not read, imported, migrated or deleted; KNX AI starts a new native context instead. Help and wiki documentation were updated in EN, IT, DE, FR, ES and zh-CN.<br/>
|
|
18
|
+
- **KNX AI — compact LLM settings layout**: constrained the assistant connection form to a readable responsive width and removed the fixed 290 px indentation that allowed the local-context hint and status line to widen the complete Node-RED properties panel. The model autocomplete now reopens after mouse release, so the full provider list remains visible after a normal click instead of appearing only while the button is held.<br/>
|
|
19
|
+
- **KNX AI — resettable CHAT learning**: added a protected **Reinitialize Memory** action to **Settings → AI Chat Learning**. After explicit confirmation it atomically replaces the shared learning file with a new empty native context, clears sessions, persistent instructions, camera watches and pending chat confirmations across every KNX AI node using the same storage, and refreshes the editor immediately. Concurrent changes remain protected by the existing content revision check.<br/>
|
|
20
|
+
- **KNX AI — complete model picker**: clicking the model field now opens the complete list returned by the selected provider regardless of the text already present, while typed text can still filter the same list and custom model names remain accepted.<br/>
|
|
21
|
+
- **KNX AI — native compact context archives**: replaced JSONL serialization for KNX telegram and detected-adapter history with KNX AI's direct line-oriented `.knxctx` format. Typed payloads, flags and bounded adapter metadata round-trip without repeated JSON property names, while bus and archive summaries are rendered as compact `key=value` context instead of JSON before reaching the model. Existing JSONL archives are deliberately not read or migrated; new daily files use `YYYY-MM-DD.knxctx`. The user-editable CHAT learning file remains separate because it is also a portable user backup surface. Context cards, editor help and wiki documentation were updated in EN, IT, DE, FR, ES and zh-CN.<br/>
|
|
22
|
+
- **KNX AI — user-selectable local chat context**: added a localized **Chat context amount** selector for Ollama and Bionic LM Studio with 4K, 8K and 16K choices; 16K remains the default. The selected budget proportionally bounds KNX traffic, archives, ETS catalog, Node-RED inventory, memory and adapter context, and is also sent as Ollama's `num_ctx`, while the complete agent tool contract stays available without phrase classifiers, keyword gates or linguistic intent routing. The context overview now reports the configured operational limit. Editor help and wiki documentation were updated in EN, IT, DE, FR, ES and zh-CN.<br/>
|
|
23
|
+
- **KNX AI — reliable conversational recall**: verified that session IDs and recent turns were already persisted correctly, then moved the current session memory next to the current request in the operational prompt so small local models do not lose user-supplied facts inside large KNX context. The structured memory tool now explicitly covers durable user facts such as preferred name and language as well as preferences and instructions, while remaining model-selected with no phrase classifiers or intent routing; credentials, security codes and API keys are excluded.<br/>
|
|
24
|
+
- **KNX AI — editable and portable CHAT learning**: added **Settings → AI Chat Learning** to the Vue web UI for viewing the exact absolute path and editing, copying, downloading or restoring the shared learning file. The **Conversations & home** tab in the Node-RED node configuration includes a localized shortcut that opens the Web UI directly on this editor for the current node. Saves are validated, bounded to 512 KB, written atomically and applied immediately to every KNX AI node sharing the same storage, while revision checks prevent stale editors from overwriting newer learning. UI strings, editor help and wiki documentation were updated in EN, IT, DE, FR, ES and zh-CN.<br/>
|
|
25
|
+
- **KNX AI — intent-free agentic chat tools**: removed hard-coded semantic phrase classifiers from conversational routing. Every Ask/CHAT request now lets the model reason directly over the current goal, persistent user guidance, AI Education and the available structured KNX, camera, TTS Ultimate and memory tools. Routine planning no longer depends on a multilingual keyword list, TTS announcements no longer require an action alias, and durable chat instructions are remembered or forgotten through model-selected structured actions instead of regular-expression intent detection. Runtime argument validation, adapter availability checks, ETS/DPT safeguards and command confirmation remain unchanged.<br/>
|
|
26
|
+
- **KNX AI — learned KNX group-address roles**: a `neutral` GA is now treated as unresolved rather than permanently uncontrollable. The conversational model can learn or forget the exact `command`, `status` or `neutral` role from trusted user teaching, persistent chat guidance, AI Education or unequivocal ETS semantics through the structured `gaRoleActions` tool. Learned role, reason and evidence are persisted per node in `knxai-config-<node-id>.json`, synchronized into bounded semantic home memory and reused after restart. A command role learned in the current answer can validate a write in that same turn, while exact ETS membership, immutable DPT, payload validation and configured confirmation still apply. Help and wiki documentation were aligned in EN, IT, DE, FR, ES and zh-CN.<br/>
|
|
27
|
+
|
|
9
28
|
**Version 6.3.22** - August 2026<br/>
|
|
10
29
|
|
|
11
30
|
- **KNX AI — visible context size and real prompt weight**: the “Chat context overview” card now shows the current operational context limit and the actual UTF-8 size of the last operational chat prompt. Ollama, Bionic, OpenAI-compatible and Claude token-usage fields are captured when returned by the provider; otherwise the UI clearly labels the token count as an estimate. Local limits reflect the active context without exceeding KNX AI's 16K cap.<br/>
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "mb_flex_tab",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "IoT Bridge - Modbus Flex Adapter",
|
|
6
|
+
"disabled": true,
|
|
7
|
+
"info": "Safe starter flow for the IoT Bridge and node-red-contrib-modbus. The tab is disabled on import and every Inject node is manual. Configure the KNX gateway, group addresses and Modbus client before enabling it."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "mb_knx_cfg",
|
|
11
|
+
"type": "knxUltimate-config",
|
|
12
|
+
"z": "",
|
|
13
|
+
"host": "224.0.23.12",
|
|
14
|
+
"port": "3671",
|
|
15
|
+
"physAddr": "15.15.215",
|
|
16
|
+
"suppressACKRequest": false,
|
|
17
|
+
"csv": "",
|
|
18
|
+
"KNXEthInterface": "Auto",
|
|
19
|
+
"KNXEthInterfaceManuallyInput": "",
|
|
20
|
+
"autoReconnect": "no"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "mb_client",
|
|
24
|
+
"type": "modbus-client",
|
|
25
|
+
"name": "LOCALHOST placeholder - configure me",
|
|
26
|
+
"clienttype": "tcp",
|
|
27
|
+
"bufferCommands": true,
|
|
28
|
+
"stateLogEnabled": false,
|
|
29
|
+
"queueLogEnabled": false,
|
|
30
|
+
"failureLogEnabled": true,
|
|
31
|
+
"tcpHost": "127.0.0.1",
|
|
32
|
+
"tcpPort": "1502",
|
|
33
|
+
"tcpType": "DEFAULT",
|
|
34
|
+
"serialPort": "/dev/ttyUSB",
|
|
35
|
+
"serialType": "RTU-BUFFERD",
|
|
36
|
+
"serialBaudrate": "9600",
|
|
37
|
+
"serialDatabits": "8",
|
|
38
|
+
"serialStopbits": "1",
|
|
39
|
+
"serialParity": "none",
|
|
40
|
+
"serialConnectionDelay": "100",
|
|
41
|
+
"serialAsciiResponseStartDelimiter": "0x3A",
|
|
42
|
+
"unit_id": "1",
|
|
43
|
+
"commandDelay": "1",
|
|
44
|
+
"clientTimeout": "1000",
|
|
45
|
+
"reconnectOnTimeout": false,
|
|
46
|
+
"reconnectTimeout": "2000",
|
|
47
|
+
"parallelUnitIdsAllowed": true,
|
|
48
|
+
"showWarnings": true,
|
|
49
|
+
"showLogs": false
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"id": "mb_intro",
|
|
53
|
+
"type": "comment",
|
|
54
|
+
"z": "mb_flex_tab",
|
|
55
|
+
"name": "START HERE - disabled and manual-only",
|
|
56
|
+
"info": "1. Install a node-red-contrib-modbus version compatible with your Node-RED runtime.\n2. Configure the KNX gateway and replace the LOCALHOST Modbus client placeholder.\n3. Adapt every GA, Unit ID and zero-based address.\n4. Enable this tab only after reviewing the mappings.\n\nThere is no automatic Inject or polling in this example.",
|
|
57
|
+
"x": 300,
|
|
58
|
+
"y": 40,
|
|
59
|
+
"wires": []
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"id": "mb_address_note",
|
|
63
|
+
"type": "comment",
|
|
64
|
+
"z": "mb_flex_tab",
|
|
65
|
+
"name": "Target is zero-based: manual reference 40010 is commonly address 9",
|
|
66
|
+
"info": "Always verify the addressing convention in the device manual. The bridge supports one bit or one 16-bit register per mapping.",
|
|
67
|
+
"x": 390,
|
|
68
|
+
"y": 80,
|
|
69
|
+
"wires": []
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "mb_bridge",
|
|
73
|
+
"type": "knxUltimateIoTBridge",
|
|
74
|
+
"z": "mb_flex_tab",
|
|
75
|
+
"server": "mb_knx_cfg",
|
|
76
|
+
"name": "KNX ↔ Modbus Flex adapter",
|
|
77
|
+
"outputtopic": "",
|
|
78
|
+
"emitOnChangeOnly": true,
|
|
79
|
+
"readOnDeploy": false,
|
|
80
|
+
"acceptFlowInput": true,
|
|
81
|
+
"nodeMode": "iot",
|
|
82
|
+
"haBusMode": "standalone",
|
|
83
|
+
"inputs": 1,
|
|
84
|
+
"outputs": 2,
|
|
85
|
+
"mappings": [
|
|
86
|
+
{
|
|
87
|
+
"id": "mb_map_coil",
|
|
88
|
+
"enabled": true,
|
|
89
|
+
"label": "Light command coil",
|
|
90
|
+
"ga": "3/1/1",
|
|
91
|
+
"dpt": "1.001",
|
|
92
|
+
"direction": "bidirectional",
|
|
93
|
+
"iotType": "modbus",
|
|
94
|
+
"target": "0",
|
|
95
|
+
"method": "POST",
|
|
96
|
+
"modbusFunction": "writeCoil",
|
|
97
|
+
"modbusMessageFormat": "flex",
|
|
98
|
+
"modbusUnitId": 1,
|
|
99
|
+
"modbusAddress": 0,
|
|
100
|
+
"modbusArea": "coil",
|
|
101
|
+
"modbusDataType": "bool",
|
|
102
|
+
"scale": 1,
|
|
103
|
+
"offset": 0,
|
|
104
|
+
"template": "",
|
|
105
|
+
"property": "",
|
|
106
|
+
"timeout": 0,
|
|
107
|
+
"retry": 0
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "mb_map_temperature",
|
|
111
|
+
"enabled": true,
|
|
112
|
+
"label": "Temperature x10 holding register",
|
|
113
|
+
"ga": "3/1/2",
|
|
114
|
+
"dpt": "9.001",
|
|
115
|
+
"direction": "bidirectional",
|
|
116
|
+
"iotType": "modbus",
|
|
117
|
+
"target": "9",
|
|
118
|
+
"method": "POST",
|
|
119
|
+
"modbusFunction": "writeHoldingRegister",
|
|
120
|
+
"modbusMessageFormat": "flex",
|
|
121
|
+
"modbusUnitId": 1,
|
|
122
|
+
"modbusAddress": 9,
|
|
123
|
+
"modbusArea": "holding-register",
|
|
124
|
+
"modbusDataType": "uint16",
|
|
125
|
+
"scale": 10,
|
|
126
|
+
"offset": 0,
|
|
127
|
+
"template": "",
|
|
128
|
+
"property": "",
|
|
129
|
+
"timeout": 0,
|
|
130
|
+
"retry": 0
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"id": "mb_map_contact",
|
|
134
|
+
"enabled": true,
|
|
135
|
+
"label": "Read-only contact",
|
|
136
|
+
"ga": "3/1/3",
|
|
137
|
+
"dpt": "1.001",
|
|
138
|
+
"direction": "iot-to-knx",
|
|
139
|
+
"iotType": "modbus",
|
|
140
|
+
"target": "4",
|
|
141
|
+
"method": "POST",
|
|
142
|
+
"modbusFunction": "readDiscreteInputs",
|
|
143
|
+
"modbusMessageFormat": "flex",
|
|
144
|
+
"modbusUnitId": 1,
|
|
145
|
+
"modbusAddress": 4,
|
|
146
|
+
"modbusArea": "discrete-input",
|
|
147
|
+
"modbusDataType": "bool",
|
|
148
|
+
"scale": 1,
|
|
149
|
+
"offset": 0,
|
|
150
|
+
"template": "",
|
|
151
|
+
"property": "",
|
|
152
|
+
"timeout": 0,
|
|
153
|
+
"retry": 0
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"x": 650,
|
|
157
|
+
"y": 260,
|
|
158
|
+
"wires": [
|
|
159
|
+
[
|
|
160
|
+
"mb_flex_write",
|
|
161
|
+
"mb_debug_flex_payload"
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
"mb_debug_knx_ack"
|
|
165
|
+
]
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"id": "mb_manual_read",
|
|
170
|
+
"type": "inject",
|
|
171
|
+
"z": "mb_flex_tab",
|
|
172
|
+
"name": "MANUAL read holding register 9",
|
|
173
|
+
"props": [
|
|
174
|
+
{
|
|
175
|
+
"p": "payload",
|
|
176
|
+
"v": "{\"fc\":3,\"unitid\":1,\"address\":9,\"quantity\":1}",
|
|
177
|
+
"vt": "json"
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
"repeat": "",
|
|
181
|
+
"crontab": "",
|
|
182
|
+
"once": false,
|
|
183
|
+
"onceDelay": 0.1,
|
|
184
|
+
"x": 230,
|
|
185
|
+
"y": 180,
|
|
186
|
+
"wires": [
|
|
187
|
+
[
|
|
188
|
+
"mb_flex_getter"
|
|
189
|
+
]
|
|
190
|
+
]
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"id": "mb_flex_getter",
|
|
194
|
+
"type": "modbus-flex-getter",
|
|
195
|
+
"z": "mb_flex_tab",
|
|
196
|
+
"name": "Flex Getter (manual request)",
|
|
197
|
+
"showStatusActivities": false,
|
|
198
|
+
"showErrors": true,
|
|
199
|
+
"showWarnings": true,
|
|
200
|
+
"logIOActivities": false,
|
|
201
|
+
"server": "mb_client",
|
|
202
|
+
"useIOFile": false,
|
|
203
|
+
"ioFile": "",
|
|
204
|
+
"useIOForPayload": false,
|
|
205
|
+
"emptyMsgOnFail": false,
|
|
206
|
+
"keepMsgProperties": true,
|
|
207
|
+
"delayOnStart": false,
|
|
208
|
+
"enableDeformedMessages": false,
|
|
209
|
+
"startDelayTime": "",
|
|
210
|
+
"x": 490,
|
|
211
|
+
"y": 180,
|
|
212
|
+
"wires": [
|
|
213
|
+
[
|
|
214
|
+
"mb_bridge",
|
|
215
|
+
"mb_debug_read"
|
|
216
|
+
],
|
|
217
|
+
[
|
|
218
|
+
"mb_debug_modbus_error"
|
|
219
|
+
]
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"id": "mb_simulated_read",
|
|
224
|
+
"type": "inject",
|
|
225
|
+
"z": "mb_flex_tab",
|
|
226
|
+
"name": "MANUAL simulate raw 215 → KNX 21.5 °C",
|
|
227
|
+
"props": [
|
|
228
|
+
{
|
|
229
|
+
"p": "payload",
|
|
230
|
+
"v": "[215]",
|
|
231
|
+
"vt": "json"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"p": "modbusRequest",
|
|
235
|
+
"v": "{\"fc\":3,\"unitid\":1,\"address\":9,\"quantity\":1}",
|
|
236
|
+
"vt": "json"
|
|
237
|
+
}
|
|
238
|
+
],
|
|
239
|
+
"repeat": "",
|
|
240
|
+
"crontab": "",
|
|
241
|
+
"once": false,
|
|
242
|
+
"onceDelay": 0.1,
|
|
243
|
+
"x": 270,
|
|
244
|
+
"y": 300,
|
|
245
|
+
"wires": [
|
|
246
|
+
[
|
|
247
|
+
"mb_bridge"
|
|
248
|
+
]
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"id": "mb_flex_write",
|
|
253
|
+
"type": "modbus-flex-write",
|
|
254
|
+
"z": "mb_flex_tab",
|
|
255
|
+
"name": "Direct Flex Write",
|
|
256
|
+
"showStatusActivities": false,
|
|
257
|
+
"showErrors": true,
|
|
258
|
+
"showWarnings": true,
|
|
259
|
+
"logIOActivities": false,
|
|
260
|
+
"server": "mb_client",
|
|
261
|
+
"emptyMsgOnFail": false,
|
|
262
|
+
"keepMsgProperties": true,
|
|
263
|
+
"delayOnStart": false,
|
|
264
|
+
"startDelayTime": "",
|
|
265
|
+
"x": 930,
|
|
266
|
+
"y": 220,
|
|
267
|
+
"wires": [
|
|
268
|
+
[
|
|
269
|
+
"mb_debug_write"
|
|
270
|
+
],
|
|
271
|
+
[
|
|
272
|
+
"mb_debug_modbus_error"
|
|
273
|
+
]
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"id": "mb_debug_flex_payload",
|
|
278
|
+
"type": "debug",
|
|
279
|
+
"z": "mb_flex_tab",
|
|
280
|
+
"name": "Flex payload from bridge",
|
|
281
|
+
"active": true,
|
|
282
|
+
"tosidebar": true,
|
|
283
|
+
"console": false,
|
|
284
|
+
"tostatus": false,
|
|
285
|
+
"complete": "payload",
|
|
286
|
+
"targetType": "msg",
|
|
287
|
+
"statusVal": "",
|
|
288
|
+
"statusType": "auto",
|
|
289
|
+
"x": 960,
|
|
290
|
+
"y": 280,
|
|
291
|
+
"wires": []
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"id": "mb_debug_knx_ack",
|
|
295
|
+
"type": "debug",
|
|
296
|
+
"z": "mb_flex_tab",
|
|
297
|
+
"name": "Modbus → KNX ack",
|
|
298
|
+
"active": true,
|
|
299
|
+
"tosidebar": true,
|
|
300
|
+
"console": false,
|
|
301
|
+
"tostatus": false,
|
|
302
|
+
"complete": "true",
|
|
303
|
+
"targetType": "full",
|
|
304
|
+
"statusVal": "",
|
|
305
|
+
"statusType": "auto",
|
|
306
|
+
"x": 950,
|
|
307
|
+
"y": 340,
|
|
308
|
+
"wires": []
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"id": "mb_debug_read",
|
|
312
|
+
"type": "debug",
|
|
313
|
+
"z": "mb_flex_tab",
|
|
314
|
+
"name": "Raw Modbus read response",
|
|
315
|
+
"active": false,
|
|
316
|
+
"tosidebar": true,
|
|
317
|
+
"console": false,
|
|
318
|
+
"tostatus": false,
|
|
319
|
+
"complete": "true",
|
|
320
|
+
"targetType": "full",
|
|
321
|
+
"statusVal": "",
|
|
322
|
+
"statusType": "auto",
|
|
323
|
+
"x": 780,
|
|
324
|
+
"y": 140,
|
|
325
|
+
"wires": []
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"id": "mb_debug_write",
|
|
329
|
+
"type": "debug",
|
|
330
|
+
"z": "mb_flex_tab",
|
|
331
|
+
"name": "Modbus write response",
|
|
332
|
+
"active": false,
|
|
333
|
+
"tosidebar": true,
|
|
334
|
+
"console": false,
|
|
335
|
+
"tostatus": false,
|
|
336
|
+
"complete": "true",
|
|
337
|
+
"targetType": "full",
|
|
338
|
+
"statusVal": "",
|
|
339
|
+
"statusType": "auto",
|
|
340
|
+
"x": 1190,
|
|
341
|
+
"y": 200,
|
|
342
|
+
"wires": []
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"id": "mb_debug_modbus_error",
|
|
346
|
+
"type": "debug",
|
|
347
|
+
"z": "mb_flex_tab",
|
|
348
|
+
"name": "Modbus response / error",
|
|
349
|
+
"active": true,
|
|
350
|
+
"tosidebar": true,
|
|
351
|
+
"console": false,
|
|
352
|
+
"tostatus": false,
|
|
353
|
+
"complete": "true",
|
|
354
|
+
"targetType": "full",
|
|
355
|
+
"statusVal": "",
|
|
356
|
+
"statusType": "auto",
|
|
357
|
+
"x": 1190,
|
|
358
|
+
"y": 260,
|
|
359
|
+
"wires": []
|
|
360
|
+
}
|
|
361
|
+
]
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "tab",
|
|
5
5
|
"label": "KNX AI - Telegrambot direct chat",
|
|
6
6
|
"disabled": false,
|
|
7
|
-
"info": "Direct chat wiring for windkh/node-red-contrib-telegrambot using the KNX AI chat-adapter preset."
|
|
7
|
+
"info": "Direct chat wiring for windkh/node-red-contrib-telegrambot using the KNX AI chat-adapter preset. Confirmation buttons return through the same receiver; no callback event node is required."
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
"id": "comment_knx_ai_telegram_setup",
|
|
@@ -53,22 +53,6 @@
|
|
|
53
53
|
[]
|
|
54
54
|
]
|
|
55
55
|
},
|
|
56
|
-
{
|
|
57
|
-
"id": "telegram_callback_knx_ai",
|
|
58
|
-
"type": "telegram event",
|
|
59
|
-
"z": "tab_knx_ai_telegram",
|
|
60
|
-
"name": "Confirm / Cancel buttons",
|
|
61
|
-
"bot": "telegram_bot_knx_ai",
|
|
62
|
-
"event": "callback_query",
|
|
63
|
-
"autoanswer": true,
|
|
64
|
-
"x": 190,
|
|
65
|
-
"y": 240,
|
|
66
|
-
"wires": [
|
|
67
|
-
[
|
|
68
|
-
"node_knx_ai_telegram"
|
|
69
|
-
]
|
|
70
|
-
]
|
|
71
|
-
},
|
|
72
56
|
{
|
|
73
57
|
"id": "node_knx_ai_telegram",
|
|
74
58
|
"type": "knxUltimateAI",
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
const fs = require('fs')
|
|
7
7
|
const path = require('path')
|
|
8
8
|
const net = require('net')
|
|
9
|
+
const dns = require('dns/promises')
|
|
9
10
|
const os = require('os')
|
|
10
11
|
const _ = require('lodash')
|
|
11
12
|
const knx = require('knxultimate')
|
|
@@ -195,6 +196,11 @@ const findAutoEthernetInterface = (targetIP) => {
|
|
|
195
196
|
return bestMatch
|
|
196
197
|
}
|
|
197
198
|
|
|
199
|
+
const resolveHostAddress = async (hostname, lookup = dns.lookup) => {
|
|
200
|
+
const { address } = await lookup(hostname, { order: 'verbatim' })
|
|
201
|
+
return address
|
|
202
|
+
}
|
|
203
|
+
|
|
198
204
|
module.exports = (RED) => {
|
|
199
205
|
// Log node and KNXUltimate engine versions once, at Node-RED startup.
|
|
200
206
|
try {
|
|
@@ -1142,7 +1148,7 @@ module.exports = (RED) => {
|
|
|
1142
1148
|
}
|
|
1143
1149
|
}
|
|
1144
1150
|
|
|
1145
|
-
node.setKnxConnectionProperties = () => {
|
|
1151
|
+
node.setKnxConnectionProperties = async () => {
|
|
1146
1152
|
// 25/08/2021 Moved out of node.initKNXConnection
|
|
1147
1153
|
node.knxConnectionProperties = {
|
|
1148
1154
|
ipAddr: node.host,
|
|
@@ -1183,10 +1189,9 @@ module.exports = (RED) => {
|
|
|
1183
1189
|
switch (net.isIP(node.host)) {
|
|
1184
1190
|
case 0:
|
|
1185
1191
|
// Invalid IP, resolve the DNS name.
|
|
1186
|
-
const dns = require('dns-sync')
|
|
1187
1192
|
let resolvedIP = null
|
|
1188
1193
|
try {
|
|
1189
|
-
resolvedIP =
|
|
1194
|
+
resolvedIP = await resolveHostAddress(node.host)
|
|
1190
1195
|
} catch (error) {
|
|
1191
1196
|
throw new Error('net.isIP: INVALID IP OR DNS NAME. Error checking the Gateway Host in Config node. ' + error.message)
|
|
1192
1197
|
}
|
|
@@ -1258,7 +1263,7 @@ module.exports = (RED) => {
|
|
|
1258
1263
|
|
|
1259
1264
|
node.initKNXConnection = async () => {
|
|
1260
1265
|
try {
|
|
1261
|
-
node.setKnxConnectionProperties() // 28/12/2021 Added
|
|
1266
|
+
await node.setKnxConnectionProperties() // 28/12/2021 Added
|
|
1262
1267
|
} catch (error) {
|
|
1263
1268
|
node.sysLogger?.error('setKnxConnectionProperties: ' + error.message)
|
|
1264
1269
|
if (node.linkStatus !== 'disconnected') await node.Disconnect()
|
|
@@ -2764,3 +2769,7 @@ module.exports = (RED) => {
|
|
|
2764
2769
|
}
|
|
2765
2770
|
})
|
|
2766
2771
|
}
|
|
2772
|
+
|
|
2773
|
+
module.exports.__test = {
|
|
2774
|
+
resolveHostAddress
|
|
2775
|
+
}
|