node-red-contrib-knx-ultimate 6.1.0 → 6.2.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/examples/KNX AI - Conversational Control with Confirmation.json +374 -0
  3. package/examples/KNX AI - Telegrambot Direct Chat.json +221 -0
  4. package/examples/Matter Controller - Semantic Flow Input.json +248 -0
  5. package/nodes/commonFunctions.js +0 -174
  6. package/nodes/knxUltimateAI.html +254 -90
  7. package/nodes/knxUltimateAI.js +1286 -61
  8. package/nodes/knxUltimateMatterBridge.html +144 -11
  9. package/nodes/knxUltimateMatterControllerDevice.html +80 -55
  10. package/nodes/locales/de/knxUltimateAI.html +38 -2
  11. package/nodes/locales/de/knxUltimateAI.json +16 -3
  12. package/nodes/locales/de/knxUltimateMatterBridge.html +1 -1
  13. package/nodes/locales/de/knxUltimateMatterBridge.json +14 -0
  14. package/nodes/locales/de/knxUltimateMatterControllerDevice.html +2 -2
  15. package/nodes/locales/de/knxUltimateMatterControllerDevice.json +2 -1
  16. package/nodes/locales/en/knxUltimateAI.html +38 -2
  17. package/nodes/locales/en/knxUltimateAI.json +16 -3
  18. package/nodes/locales/en/knxUltimateMatterBridge.html +1 -1
  19. package/nodes/locales/en/knxUltimateMatterBridge.json +14 -0
  20. package/nodes/locales/en/knxUltimateMatterControllerDevice.html +2 -2
  21. package/nodes/locales/en/knxUltimateMatterControllerDevice.json +2 -1
  22. package/nodes/locales/es/knxUltimateAI.html +38 -2
  23. package/nodes/locales/es/knxUltimateAI.json +16 -3
  24. package/nodes/locales/es/knxUltimateMatterBridge.html +1 -1
  25. package/nodes/locales/es/knxUltimateMatterBridge.json +14 -0
  26. package/nodes/locales/es/knxUltimateMatterControllerDevice.html +2 -2
  27. package/nodes/locales/es/knxUltimateMatterControllerDevice.json +2 -1
  28. package/nodes/locales/fr/knxUltimateAI.html +38 -2
  29. package/nodes/locales/fr/knxUltimateAI.json +16 -3
  30. package/nodes/locales/fr/knxUltimateMatterBridge.html +1 -1
  31. package/nodes/locales/fr/knxUltimateMatterBridge.json +14 -0
  32. package/nodes/locales/fr/knxUltimateMatterControllerDevice.html +2 -2
  33. package/nodes/locales/fr/knxUltimateMatterControllerDevice.json +2 -1
  34. package/nodes/locales/it/knxUltimateAI.html +38 -2
  35. package/nodes/locales/it/knxUltimateAI.json +16 -3
  36. package/nodes/locales/it/knxUltimateMatterBridge.html +1 -1
  37. package/nodes/locales/it/knxUltimateMatterBridge.json +14 -0
  38. package/nodes/locales/it/knxUltimateMatterControllerDevice.html +2 -2
  39. package/nodes/locales/it/knxUltimateMatterControllerDevice.json +2 -1
  40. package/nodes/locales/zh-CN/knxUltimateAI.html +38 -2
  41. package/nodes/locales/zh-CN/knxUltimateAI.json +16 -3
  42. package/nodes/locales/zh-CN/knxUltimateMatterBridge.html +1 -1
  43. package/nodes/locales/zh-CN/knxUltimateMatterBridge.json +14 -0
  44. package/nodes/locales/zh-CN/knxUltimateMatterControllerDevice.html +2 -2
  45. package/nodes/locales/zh-CN/knxUltimateMatterControllerDevice.json +2 -1
  46. package/nodes/utils/sysLogger.js +0 -109
  47. package/package.json +1 -2
  48. package/resources/KNXAIChatAdapterMappings.js +87 -0
  49. package/nodes/plugins/knxUltimateMonitor-sidebar-plugin.html +0 -922
@@ -17,6 +17,7 @@
17
17
  "input_help_endpoint_hint": "Der Knoten kennt Node ID und Endpoint ID bereits; einfache Nachrichten benötigen sie nicht.",
18
18
  "input_help_simple_title": "Einfache Nachrichten",
19
19
  "input_help_simple_hint": "Diese Funktionen verwenden verständliche Einheiten und werden in den Matter-Cluster, Befehl oder das Attribut des ausgewählten Endpunkts übersetzt.",
20
+ "input_help_light_hint": "Licht-Endpunkte akzeptieren Lichtzustands-Eigenschaften direkt in msg (nicht in msg.payload). Es werden nur die von der ausgewählten Leuchte unterstützten Steuerungen angezeigt.",
20
21
  "input_help_advanced_title": "Erweiterte Matter-Details",
21
22
  "input_help_advanced_hint": "Es werden nur angekündigte Attribute und Befehle aufgelistet. Schreibbeispiele verwenden 0 als Platzhalter; Befehlsargumente müssen eventuell an den Matter-Datentyp angepasst werden.",
22
23
  "input_help_operation": "Operation",
@@ -31,7 +32,7 @@
31
32
  "input_help_no_simple": "Dieser Endpunkt besitzt keine bekannte einfache Eingangsfunktion.",
32
33
  "input_help_no_structure": "Die Matter-Struktur ist nicht verfügbar. Aktualisiere die Geräteliste, während der Endpunkt online ist.",
33
34
  "input_functions": {
34
- "onoff": "Ein / Aus", "level": "Stufe", "position": "Rollladenposition", "tiltposition": "Lamellenposition", "open": "Öffnen", "close": "Schließen", "stop": "Stopp", "setpoint": "Heizsollwert", "coolingsetpoint": "Kühlsollwert", "currenttemp": "Aktuelle Temperatur", "fanspeed": "Lüftergeschwindigkeit", "temperature": "Temperatur", "humidity": "Luftfeuchtigkeit", "illuminance": "Beleuchtungsstärke", "occupancy": "Belegung", "contact": "Kontakt", "battery": "Batterie", "activepower": "Wirkleistung", "importedenergy": "Bezogene Energie", "identify": "Identifizieren", "lock": "Verriegeln", "unlock": "Entriegeln"
35
+ "onoff": "Ein / Aus", "on": "Ein", "off": "Aus", "level": "Stufe", "brightness": "Helligkeit", "color_temperature": "Farbtemperatur", "xy_color": "XY-Farbe", "position": "Rollladenposition", "tiltposition": "Lamellenposition", "open": "Öffnen", "close": "Schließen", "stop": "Stopp", "setpoint": "Heizsollwert", "coolingsetpoint": "Kühlsollwert", "currenttemp": "Aktuelle Temperatur", "fanspeed": "Lüftergeschwindigkeit", "temperature": "Temperatur", "humidity": "Luftfeuchtigkeit", "illuminance": "Beleuchtungsstärke", "occupancy": "Belegung", "contact": "Kontakt", "battery": "Batterie", "activepower": "Wirkleistung", "importedenergy": "Bezogene Energie", "identify": "Identifizieren", "lock": "Verriegeln", "unlock": "Entriegeln"
35
36
  },
36
37
  "tabs": {
37
38
  "switch": "Schalten",
@@ -1,18 +1,48 @@
1
1
  <script type="text/markdown" data-help-name="knxUltimateAI">
2
2
  This node listens to **all KNX telegrams** from the selected KNX Ultimate gateway, builds traffic statistics, detects anomalies, and can optionally query an LLM.
3
3
 
4
+ The editor sections use the same left-hand vertical tabs as the Matter nodes. **Quick setup** contains only the common AI choices (enable, provider, credentials, model, KNX state reads/actuator control and confirmation); technical settings are grouped by topic in the other tabs.
5
+
4
6
  ## Outputs
5
7
  1. **Summary/Stats** (`msg.payload` JSON)
6
8
  2. **Anomalies** (`msg.payload` JSON)
7
9
  3. **AI Assistant** (`msg.payload` text, with `msg.summary`)
10
+ 4. **KNX operations** (one Universal Mode message per validated read or write)
11
+
12
+ Every message emitted by outputs 3 and 4 also contains a clone of the original input message in `msg.inputMessage`. This preserves the original payload, topic, chat metadata, and any other input properties for downstream nodes. Cloning and output errors are contained and reported instead of escaping into the Node-RED runtime.
8
13
 
9
14
  ## Commands (input)
10
15
  Send `msg.topic`:
11
16
  - `summary` (or empty): emit summary immediately
12
17
  - `reset`: clear internal history/counters
13
18
  - `ask`: send a question to the configured LLM
19
+ - `confirm` / `cancel`: confirm or cancel pending KNX commands without calling the LLM
20
+ - `clear_chat`: clear the conversation memory for the current session
21
+
22
+ For `ask`, provide the question in `msg.prompt` (preferred), `msg.payload` (string), or the common Telegram fields `msg.payload.content` / `msg.payload.text`.
23
+
24
+ When KNX control is enabled, recent turns are remembered in RAM per `msg.knxAi.sessionId`, `msg.sessionId`, or a detected Telegram chat ID. Wire output 3 back to the chat sender and output 4 to a KNX Ultimate node configured in **Universal mode**. With confirmation enabled, the first reply previews every write GA, DPT, and payload without emitting writes; the same session must then reply `CONFIRM`/`CANCEL` (localized equivalents are accepted) within 5 minutes. A new request replaces any older pending plan. Each confirmed command has `msg.destination`, `msg.dpt`, `msg.payload`, and `msg.event = "GroupValue_Write"`.
25
+ For DPT 1.xxx writes, safe AI equivalents `true`/`false`, `1`/`0`, and `on`/`off` are normalized to a real boolean before local validation and output.
26
+
27
+ ### Fresh KNX reads
28
+ When the user explicitly asks for a fresh/current state, the AI may query exact objects from the imported ETS catalog, including status and other read-only objects. Output 4 emits `msg.destination`, `msg.dpt`, `msg.event = "GroupValue_Read"`, and `msg.readstatus = true`. The node waits up to 6 seconds for each `GroupValue_Response` or fresh write, then returns the decoded values on output 3 and exposes details in `msg.knxAi.readResults`. Reads never require confirmation and never become writes.
29
+
30
+ ### Confirmation request for chat buttons
31
+ While a plan is pending, output 3 contains `msg.knxAi.confirmationRequest`. The object includes `required`, `status`, `sessionId`, `expiresAt`, `commandCount`, and two entries in `actions`. Use `action.label` as the Telegram button text, `action.callbackData` as its callback, and send `action.message` back to KNX AI to confirm or cancel without typed text.
32
+
33
+ ### Chat adapter presets
34
+ The **Chat adapters** tab loads its selectable mappings from `resources/KNXAIChatAdapterMappings.js`. Selecting a preset inserts two editable synchronous JavaScript mappings in full-width text boxes: one before KNX AI processes an input and one before output 3 is emitted. Return `msg` to continue or no value to discard the message. Syntax and execution failures are caught and reported without stopping Node-RED.
35
+
36
+ The included **windkh/node-red-contrib-telegrambot** preset follows the package's receiver/sender contract. Connect a `telegram receiver` directly to KNX AI, output 3 directly to a `telegram sender`, and—when inline confirmation buttons are required—connect a `telegram event` configured for `callback_query` to the same KNX AI input. The input mapping extracts `msg.payload.content`, `msg.payload.chatId`, and the Telegram language. The output mapping creates the required `msg.payload.chatId`, `type`, and `content`, adding `options.reply_markup` from `msg.knxAi.confirmationRequest` when writes await confirmation. The Telegram package remains a separate optional dependency.
14
37
 
15
- For `ask`, provide the question in `msg.prompt` (preferred) or `msg.payload` (string).
38
+ ## Quick workflow: KNX control
39
+ 1. Import the ETS CSV into the gateway and configure the LLM provider, model, and credentials.
40
+ 2. Enable **LLM assistant** and **KNX state reads and actuator control**; leave confirmation enabled.
41
+ 3. Connect the chat input to KNX AI while preserving a stable session/chat ID.
42
+ 4. Connect output 3 to the chat reply and output 4 to KNX Ultimate in **Universal mode**.
43
+ 5. The user sends a request; fresh state requests are read immediately, while writes first show the proposed GA, DPT, and value without writing to the bus.
44
+ 6. Within 5 minutes, the same chat replies exactly `CONFIRM` or `CANCEL`.
45
+ 7. Only `CONFIRM` revalidates and emits commands on output 4; verify execution through a KNX status GA.
16
46
 
17
47
  ## Configuration fields
18
48
  All fields exposed in the KNX AI editor are listed below.
@@ -53,7 +83,13 @@ All fields exposed in the KNX AI editor are listed below.
53
83
  - **Endpoint URL**: Chat/completions endpoint URL.
54
84
  - **API key**: API key (not required for local Ollama).
55
85
  - **Model**: Model ID/name.
86
+ - **Chat model compatibility**: The selected model must support the configured Chat Completions endpoint. Legacy completion-only models such as `gpt-3.5-turbo-instruct` are excluded when the model list is refreshed. If the provider rejects a custom temperature or token-limit parameter, KNX AI retries after removing or replacing only that incompatible field.
56
87
  - **System prompt**: Global instruction for KNX analysis behavior (Advanced).
88
+ - **Allow AI to read KNX states and control actuators**: Enables output 4 and is off by default. Exact ETS catalog objects may be read; writes are accepted only for objects classified as `command`. Unknown, DPT-mismatched, invalid, or excessive operations and writes to status/neutral objects are rejected locally.
89
+ - **Ask for confirmation before sending KNX commands**: Enabled by default. Shows the validated changes first and emits no KNX command until the same chat session confirms them. Whenever commands are awaiting confirmation, the response always appends the exact confirmation/cancellation instructions in the language of the current request. Commands are validated again immediately before output.
90
+ - **Adapter preset**: Loads an input/output mapping pair from the packaged chat-adapter file. Selecting a preset intentionally replaces both mapping text boxes; they remain editable afterwards.
91
+ - **Input mapping (chat → KNX AI)**: Synchronous JavaScript applied before input command processing.
92
+ - **Output mapping (KNX AI → chat)**: Synchronous JavaScript applied only to messages on output 3.
57
93
  - If disk archive is enabled, **Ask** uses the archive by default: explicit dates/ranges are honored, otherwise the assistant searches the last 24 hours plus current RAM events.
58
94
  - **Include raw payload hex**: Include raw telegram hex in prompt.
59
95
  - **Include Node-RED project inventory**: Include the whole Node-RED project inventory in the prompt, including KNX nodes and other useful nodes such as function/change/inject/template when they contain KNX-related logic or group addresses.
@@ -84,5 +120,5 @@ All fields exposed in the KNX AI editor are listed below.
84
120
  - If Node-RED runs in Docker, use `host.docker.internal` instead of `localhost` in the endpoint URL.
85
121
 
86
122
  ## Security note
87
- If LLM is enabled, KNX traffic context can be sent to the configured endpoint. Use local providers if you need strict on-prem data handling.
123
+ If LLM is enabled, KNX traffic context can be sent to the configured endpoint. Use local providers if you need strict on-prem data handling. A command emitted on output 4 passed local validation and was forwarded to the flow; it is not proof that the actuator executed it. Use a KNX status GA when confirmation is required.
88
124
  </script>
@@ -2,12 +2,14 @@
2
2
  "knxUltimateAI": {
3
3
  "title": "KNX AI (Traffic Analyzer)",
4
4
  "sections": {
5
+ "quickSetup": "Quick setup",
5
6
  "capture": "Capture",
6
7
  "storage": "Storage & Summary",
7
8
  "detection": "Detection & Alerts",
8
9
  "llmConnection": "AI Assistant Connection",
9
10
  "llmContext": "AI Assistant Context",
10
- "advanced": "Advanced Tuning"
11
+ "chatAdapter": "Chat adapters",
12
+ "advanced": "Advanced AI"
11
13
  },
12
14
  "properties": {
13
15
  "server": "Gateway",
@@ -39,19 +41,28 @@
39
41
  "llmSystemPrompt": "System prompt",
40
42
  "llmIncludeRaw": "Include raw payload hex",
41
43
  "llmIncludeFlowContext": "Include Node-RED project inventory",
44
+ "llmAllowKnxCommands": "Allow AI to read KNX states and control actuators",
45
+ "llmRequireCommandConfirmation": "Ask for confirmation before sending KNX commands",
46
+ "chatAdapterPreset": "Adapter preset",
47
+ "chatInputCode": "Input mapping (chat → KNX AI)",
48
+ "chatOutputCode": "Output mapping (KNX AI → chat)",
42
49
  "llmIncludeDocsSnippets": "Include documentation snippets (help/README/examples)",
43
50
  "llmDocsLanguage": "Docs language"
44
51
  },
45
52
  "outputs": {
46
53
  "summary": "Summary/Stats",
47
54
  "anomalies": "Anomalies",
48
- "assistant": "AI Assistant"
55
+ "assistant": "AI Assistant",
56
+ "knxCommands": "KNX operations"
49
57
  },
50
58
  "selectlists": {
51
59
  "llmProvider": {
52
60
  "openai_compat": "OpenAI-compatible (chat/completions)",
53
61
  "anthropic": "Anthropic (Claude)",
54
62
  "ollama": "Ollama (local, beta)"
63
+ },
64
+ "chatAdapter": {
65
+ "none": "No adapter"
55
66
  }
56
67
  },
57
68
  "buttons": {
@@ -69,7 +80,9 @@
69
80
  "installedOllamaModel": "Ollama model installed",
70
81
  "installOllamaModelFailed": "Failed to install Ollama model",
71
82
  "ollamaInstallSteps": "1) Open the model library and copy the model name (for example llama3.1). 2) Put the name in the Model field and click Install it.",
72
- "ollamaStartedAuto": "Ollama server started automatically."
83
+ "ollamaStartedAuto": "Ollama server started automatically.",
84
+ "chatAdapterIntro": "Choose a mapping preset to insert its input and output code. The list is loaded from the packaged chat-adapter mappings file; the generated code remains editable.",
85
+ "chatAdapterCodeHelp": "Mappings run synchronously. Return msg to continue or return no value to discard it. Errors are caught and reported without stopping Node-RED."
73
86
  },
74
87
  "placeholder": {
75
88
  "llmBaseUrl": "https://api.openai.com/v1/chat/completions (or your compatible endpoint)",
@@ -45,7 +45,7 @@ These options are hidden unless they apply to the selected type. Dimmable device
45
45
 
46
46
  ## Node PINs
47
47
 
48
- If you enable the node input/output PINs:
48
+ The PIN selector is outside the editor tabs. Enabling it reveals a contextual **Flow input/output** section directly below, with copyable examples filtered to the selected device type:
49
49
 
50
50
  - **Input**: update the Matter state from the flow, without the KNX bus: `msg.payload = { function: "onoff", value: true }` (`function` is one of `onoff`, `level`, `rgb`, `colortemp`, `position`, `temperature`, `humidity`, `illuminance`, `occupancy`, `contact`, `currenttemp`, `setpoint`, `fanspeed`, `smoke`, `co`, `leak`, `co2`, `rvcstate`, `rvcmode`). Useful to expose flow-computed values (e.g. a virtual sensor) to Alexa & Co.
51
51
  - **Output**: every command received from a Matter controller is forwarded to the flow: `msg.topic` = device name, `msg.payload` = value, `msg.matter` = the raw command. A device without command GAs becomes a **flow-only device**.
@@ -36,6 +36,20 @@
36
36
  "mappings": "KNX mappings",
37
37
  "advanced": "Advanced options"
38
38
  },
39
+ "flow_help": {
40
+ "title": "Flow input/output",
41
+ "intro": "These examples match the selected device type and are available while the node input/output PINs are enabled.",
42
+ "input_title": "Flow → Matter (node input)",
43
+ "input_hint": "Send one of these messages to update the exposed Matter state without writing to KNX.",
44
+ "output_title": "Matter → Flow (node output)",
45
+ "output_hint": "Commands received from a Matter controller are emitted with the value in msg.payload and raw routing details in msg.matter.",
46
+ "function": "Function",
47
+ "message": "Example message",
48
+ "copy": "Copy",
49
+ "copied": "Message copied",
50
+ "no_input": "This device type has no flow state-update examples.",
51
+ "no_output": "This device type does not emit controller commands; its output remains silent."
52
+ },
39
53
  "functions": {
40
54
  "fn_onoff_cmd": "On/Off command GA",
41
55
  "fn_onoff_status": "On/Off status GA",
@@ -19,11 +19,11 @@ It replaces the unpublished per-device Matter controller nodes and keeps the ful
19
19
  | Sensors | Sensor endpoints expose their measurement/status GA only when supported: temperature, humidity, illuminance, occupancy, contact and battery. |
20
20
  | Read at startup | Publishes the cached Matter value at deploy/startup or when the device reconnects. |
21
21
  | Update local state from KNX write | Updates the local Matter/KNX cache when a telegram is written on a configured KNX GA. |
22
- | Node Input/Output PINs | Shows Node-RED input/output pins. Non-light endpoints accept the simple `{function,value}` contract below as well as the advanced Matter fields; output emits state updates. The selection is preserved when the editor is reopened. |
22
+ | Node Input/Output PINs | Shows Node-RED input/output pins and reveals the **Flow input** section directly below this field. Lights show their supported top-level light-state messages; non-light endpoints show the simple `{function,value}` contract and advanced Matter fields. The selection is preserved when the editor is reopened. |
23
23
 
24
24
  ## Flow input
25
25
 
26
- For a selected non-light endpoint, open the **Flow input** tab in the editor. The tab is built from the endpoint's advertised structure and provides copyable examples, the selected Endpoint ID, every readable/writable attribute and every accepted command. It remains available when the node is used only by a flow without a KNX gateway.
26
+ Enable **Node Input/Output PINs** to reveal the **Flow input** section directly below the selector. For lights it shows copyable examples for the supported top-level properties, such as `msg.on`, `msg.dimming`, `msg.color_temperature` and `msg.color`. For non-light endpoints it is built from the advertised structure and provides the selected Endpoint ID, every readable/writable attribute and every accepted command. It remains available when the node is used only by a flow without a KNX gateway.
27
27
 
28
28
  Simple writes use `msg.payload = {function:"position",value:35}`. Omit `value` to read a supported state, for example `{function:"temperature"}`; the output uses human units and includes raw routing details in `msg.matter`. Supported functions include `onoff`, `level`, `position`, `tiltposition`, `open`, `close`, `stop`, `setpoint`, `coolingsetpoint`, `currenttemp`, `fanspeed`, sensor readings and `identify`, but only when advertised by that endpoint. Door Lock accepts `{function:"lock",value:true|false}`.
29
29
 
@@ -17,6 +17,7 @@
17
17
  "input_help_endpoint_hint": "The node already knows the Node ID and Endpoint ID, so the simple messages do not need them.",
18
18
  "input_help_simple_title": "Simple messages",
19
19
  "input_help_simple_hint": "These functions use human units and are translated to the Matter cluster, command or attribute shown by the selected endpoint.",
20
+ "input_help_light_hint": "Light endpoints accept light-state properties directly on msg (not inside msg.payload). Only controls supported by the selected light are shown.",
20
21
  "input_help_advanced_title": "Advanced Matter details",
21
22
  "input_help_advanced_hint": "Only advertised attributes and commands are listed. Attribute write examples use 0 as a placeholder; command arguments may need to be adapted to the Matter data type.",
22
23
  "input_help_operation": "Operation",
@@ -31,7 +32,7 @@
31
32
  "input_help_no_simple": "This endpoint has no known simple input functions.",
32
33
  "input_help_no_structure": "The Matter structure is unavailable. Refresh the device list while the endpoint is online.",
33
34
  "input_functions": {
34
- "onoff": "On / Off", "level": "Level", "position": "Cover position", "tiltposition": "Cover tilt", "open": "Open", "close": "Close", "stop": "Stop", "setpoint": "Heating setpoint", "coolingsetpoint": "Cooling setpoint", "currenttemp": "Current temperature", "fanspeed": "Fan speed", "temperature": "Temperature", "humidity": "Humidity", "illuminance": "Illuminance", "occupancy": "Occupancy", "contact": "Contact", "battery": "Battery", "activepower": "Active power", "importedenergy": "Imported energy", "identify": "Identify", "lock": "Lock", "unlock": "Unlock"
35
+ "onoff": "On / Off", "on": "On", "off": "Off", "level": "Level", "brightness": "Brightness", "color_temperature": "Colour temperature", "xy_color": "XY colour", "position": "Cover position", "tiltposition": "Cover tilt", "open": "Open", "close": "Close", "stop": "Stop", "setpoint": "Heating setpoint", "coolingsetpoint": "Cooling setpoint", "currenttemp": "Current temperature", "fanspeed": "Fan speed", "temperature": "Temperature", "humidity": "Humidity", "illuminance": "Illuminance", "occupancy": "Occupancy", "contact": "Contact", "battery": "Battery", "activepower": "Active power", "importedenergy": "Imported energy", "identify": "Identify", "lock": "Lock", "unlock": "Unlock"
35
36
  },
36
37
  "tabs": {
37
38
  "switch": "Switch",
@@ -1,18 +1,48 @@
1
1
  <script type="text/markdown" data-help-name="knxUltimateAI">
2
2
  Este nodo escucha **todos los telegramas KNX** del gateway KNX Ultimate seleccionado, genera estadísticas de tráfico, detecta anomalías y puede consultar opcionalmente un LLM.
3
3
 
4
+ Las secciones del editor utilizan las mismas pestañas verticales a la izquierda que los nodos Matter. **Configuración rápida** contiene solo las opciones habituales de AI (activación, proveedor, credenciales, modelo, lectura de estados/control de actuadores KNX y confirmación); los parámetros técnicos se agrupan por tema en las demás pestañas.
5
+
4
6
  ## Salidas
5
7
  1. **Resumen/Estadísticas** (`msg.payload` JSON)
6
8
  2. **Anomalías** (`msg.payload` JSON)
7
9
  3. **Asistente IA** (`msg.payload` texto, con `msg.summary`)
10
+ 4. **Operaciones KNX** (un mensaje Universal Mode por cada lectura o escritura validada)
11
+
12
+ Cada mensaje emitido por las salidas 3 y 4 también contiene una copia del mensaje de entrada original en `msg.inputMessage`. Así, el payload, el topic, los metadatos del chat y cualquier otra propiedad de entrada permanecen disponibles para los nodos posteriores. Los errores de clonación o envío se interceptan y notifican sin propagarse al runtime de Node-RED.
8
13
 
9
14
  ## Comandos (entrada)
10
15
  Envía `msg.topic`:
11
16
  - `summary` (o vacío): emite el resumen inmediatamente
12
17
  - `reset`: limpia historial y contadores internos
13
18
  - `ask`: envía una pregunta al LLM configurado
19
+ - `confirm` / `cancel`: confirma o cancela los comandos KNX pendientes sin volver a llamar al LLM
20
+ - `clear_chat`: borra la memoria de conversación de la sesión actual
21
+
22
+ Para `ask`, envía la pregunta en `msg.prompt` (recomendado), `msg.payload` (string), o los campos comunes de Telegram `msg.payload.content` / `msg.payload.text`.
23
+
24
+ Cuando el control KNX está habilitado, los turnos recientes se guardan en RAM por `msg.knxAi.sessionId`, `msg.sessionId` o el ID de chat Telegram detectado. Conecta la salida 3 al nodo emisor del chat y la salida 4 a un nodo KNX Ultimate en **modo universal**. Con la confirmación activa, la primera respuesta muestra GA, DPT y payload sin emitir escrituras; la misma sesión debe responder `CONFIRMAR` o `CANCELAR` en 5 minutos. Una solicitud nueva sustituye cualquier plan anterior. Cada comando confirmado contiene `msg.destination`, `msg.dpt`, `msg.payload` y `msg.event = "GroupValue_Write"`.
25
+ Para las escrituras DPT 1.xxx, los equivalentes seguros producidos por la IA `true`/`false`, `1`/`0` y `on`/`off` se normalizan a booleanos reales antes de la validación local y la salida.
26
+
27
+ ### Lecturas KNX actualizadas
28
+ Cuando el usuario solicita explícitamente un estado actual o actualizado, la IA puede consultar objetos exactos del catálogo ETS importado, incluidos objetos de estado y otros objetos de solo lectura. La salida 4 emite `msg.destination`, `msg.dpt`, `msg.event = "GroupValue_Read"` y `msg.readstatus = true`. El nodo espera hasta 6 segundos cada `GroupValue_Response` o escritura reciente, devuelve los valores decodificados por la salida 3 y expone los detalles en `msg.knxAi.readResults`. Las lecturas nunca requieren confirmación ni se convierten en escrituras.
29
+
30
+ ### Solicitud de confirmación para botones de chat
31
+ Mientras un plan está pendiente, la salida 3 contiene `msg.knxAi.confirmationRequest`. El objeto incluye `required`, `status`, `sessionId`, `expiresAt`, `commandCount` y dos elementos en `actions`. Usa `action.label` como texto del botón de Telegram, `action.callbackData` como callback y devuelve `action.message` a KNX AI para confirmar o cancelar sin escribir texto.
32
+
33
+ ### Preajustes del adaptador de chat
34
+ La pestaña **Adaptadores de chat** carga sus mapeos seleccionables desde `resources/KNXAIChatAdapterMappings.js`. Al elegir un preajuste se insertan dos mapeos JavaScript síncronos y editables en cuadros de texto de ancho completo: uno antes de que KNX AI procese la entrada y otro antes de emitir por la salida 3. Devuelve `msg` para continuar o ningún valor para descartar el mensaje. Los errores de sintaxis y ejecución se capturan y notifican sin detener Node-RED.
35
+
36
+ El preajuste incluido **windkh/node-red-contrib-telegrambot** sigue el contrato receiver/sender del paquete. Conecta directamente un `telegram receiver` a KNX AI y la salida 3 a un `telegram sender`. Para los botones inline de confirmación, conecta también un `telegram event` configurado como `callback_query` a la misma entrada KNX AI. El mapeo de entrada extrae `msg.payload.content`, `msg.payload.chatId` y el idioma de Telegram. El mapeo de salida crea `msg.payload.chatId`, `type` y `content`, y añade `options.reply_markup` desde `msg.knxAi.confirmationRequest` cuando una escritura espera confirmación. El paquete Telegram sigue siendo una dependencia opcional separada.
14
37
 
15
- Para `ask`, envía la pregunta en `msg.prompt` (recomendado) o `msg.payload` (string).
38
+ ## Flujo rápido: control KNX
39
+ 1. Importa el CSV de ETS en el gateway y configura el proveedor, el modelo y las credenciales LLM.
40
+ 2. Activa **Asistente LLM** y **lectura de estados KNX y control de actuadores**; deja activada la confirmación.
41
+ 3. Conecta la entrada del chat a KNX AI manteniendo un ID de sesión/chat estable.
42
+ 4. Conecta la salida 3 a la respuesta del chat y la salida 4 a KNX Ultimate en **modo universal**.
43
+ 5. El usuario envía una solicitud; los estados actuales se leen inmediatamente, mientras que las escrituras muestran primero GA, DPT y valor sin escribir en el bus.
44
+ 6. En un plazo de 5 minutos, el mismo chat responde exactamente `CONFIRMAR` o `CANCELAR`.
45
+ 7. Solo `CONFIRMAR` vuelve a validar y emite los comandos por la salida 4; verifica la ejecución mediante una GA de estado KNX.
16
46
 
17
47
  ## Campos de configuración
18
48
  Aquí tienes todos los campos tal como se muestran en el editor de KNX AI.
@@ -53,7 +83,13 @@ Aquí tienes todos los campos tal como se muestran en el editor de KNX AI.
53
83
  - **Endpoint URL**: URL endpoint chat/completions.
54
84
  - **API key**: clave API (no requerida con Ollama local).
55
85
  - **Model**: ID/nombre de modelo.
86
+ - **Compatibilidad del modelo de chat**: el modelo seleccionado debe admitir el endpoint Chat Completions configurado. Los modelos antiguos disponibles solo mediante completions, como `gpt-3.5-turbo-instruct`, se excluyen al actualizar la lista. Si el proveedor rechaza un valor personalizado de temperatura o el parámetro de límite de tokens, KNX AI vuelve a intentarlo eliminando o sustituyendo únicamente el campo incompatible.
56
87
  - **System prompt**: instrucción global para análisis KNX (Advanced).
88
+ - **Permitir que la IA lea estados KNX y controle actuadores**: habilita la salida 4 y está desactivado por defecto. Los objetos exactos del catálogo ETS se pueden leer; solo se aceptan escrituras hacia objetos clasificados como `command`. Las operaciones desconocidas, con DPT distinto, inválidas o excesivas, y las escrituras hacia objetos de estado o neutrales, se rechazan localmente.
89
+ - **Pedir confirmación antes de enviar comandos KNX**: activado por defecto. Muestra primero los cambios validados y no emite comandos hasta que la misma sesión de chat los confirme. Cuando hay comandos pendientes, la respuesta añade siempre las instrucciones exactas para confirmar o cancelar en el idioma de la solicitud actual. Los comandos se validan de nuevo justo antes de la salida.
90
+ - **Preajuste del adaptador**: carga una pareja de mapeos entrada/salida desde el archivo de adaptadores de chat incluido. La selección sustituye intencionadamente ambos cuadros de texto; el código sigue siendo editable.
91
+ - **Mapeo de entrada (chat → KNX AI)**: JavaScript síncrono aplicado antes de procesar el comando de entrada.
92
+ - **Mapeo de salida (KNX AI → chat)**: JavaScript síncrono aplicado solo a los mensajes de la salida 3.
57
93
  - Si el archivo en disco esta activo, **Ask** lo usa por defecto: respeta fechas/rangos explicitos y, si no los indicas, busca en las ultimas 24 horas mas los eventos actuales en RAM.
58
94
  - **Include raw payload hex**: incluye payload hex raw en el prompt.
59
95
  - **Incluir inventario del proyecto Node-RED**: incluye en el prompt el inventario de todo el proyecto Node-RED, con nodos KNX y otros nodos utiles como function/change/inject/template cuando contienen logica KNX o direcciones de grupo.
@@ -84,5 +120,5 @@ Aquí tienes todos los campos tal como se muestran en el editor de KNX AI.
84
120
  - Si Node-RED se ejecuta en Docker, usa `host.docker.internal` en lugar de `localhost` en el endpoint.
85
121
 
86
122
  ## Nota de seguridad
87
- Si el LLM está habilitado, el contexto de tráfico KNX puede enviarse al endpoint configurado. Para privacidad on-premise, usa proveedores locales.
123
+ Si el LLM está habilitado, el contexto de tráfico KNX puede enviarse al endpoint configurado. Para privacidad on-premise, usa proveedores locales. Un comando emitido por la salida 4 superó la validación local y fue enviado al flow, pero no confirma que el actuador lo ejecutara. Usa una GA de estado KNX para confirmarlo.
88
124
  </script>
@@ -2,12 +2,14 @@
2
2
  "knxUltimateAI": {
3
3
  "title": "KNX AI (Traffic Analyzer)",
4
4
  "sections": {
5
+ "quickSetup": "Configuracion rapida",
5
6
  "capture": "Capture",
6
7
  "storage": "Historial y Resumen",
7
8
  "detection": "Deteccion y Alertas",
8
9
  "llmConnection": "Conexion del Asistente IA",
9
10
  "llmContext": "Contexto del Asistente IA",
10
- "advanced": "Ajustes Avanzados"
11
+ "chatAdapter": "Adaptadores de chat",
12
+ "advanced": "IA avanzada"
11
13
  },
12
14
  "properties": {
13
15
  "server": "Gateway",
@@ -39,19 +41,28 @@
39
41
  "llmSystemPrompt": "System prompt",
40
42
  "llmIncludeRaw": "Include raw payload hex",
41
43
  "llmIncludeFlowContext": "Incluir inventario del proyecto Node-RED",
44
+ "llmAllowKnxCommands": "Permitir que la IA lea estados KNX y controle actuadores",
45
+ "llmRequireCommandConfirmation": "Pedir confirmación antes de enviar comandos KNX",
46
+ "chatAdapterPreset": "Preajuste del adaptador",
47
+ "chatInputCode": "Mapeo de entrada (chat → KNX AI)",
48
+ "chatOutputCode": "Mapeo de salida (KNX AI → chat)",
42
49
  "llmIncludeDocsSnippets": "Include documentation snippets (help/README/examples)",
43
50
  "llmDocsLanguage": "Docs language"
44
51
  },
45
52
  "outputs": {
46
53
  "summary": "Resumen/Estadísticas",
47
54
  "anomalies": "Anomalías",
48
- "assistant": "Asistente IA"
55
+ "assistant": "Asistente IA",
56
+ "knxCommands": "Operaciones KNX"
49
57
  },
50
58
  "selectlists": {
51
59
  "llmProvider": {
52
60
  "openai_compat": "OpenAI-compatible (chat/completions)",
53
61
  "anthropic": "Anthropic (Claude)",
54
62
  "ollama": "Ollama (local, beta)"
63
+ },
64
+ "chatAdapter": {
65
+ "none": "Sin adaptador"
55
66
  }
56
67
  },
57
68
  "messages": {
@@ -61,7 +72,9 @@
61
72
  "installedOllamaModel": "Ollama model installed",
62
73
  "installOllamaModelFailed": "Failed to install Ollama model",
63
74
  "ollamaInstallSteps": "1) Open the model library and copy the model name (for example llama3.1). 2) Put the name in the Model field and click Install it.",
64
- "ollamaStartedAuto": "Ollama server started automatically."
75
+ "ollamaStartedAuto": "Ollama server started automatically.",
76
+ "chatAdapterIntro": "Elige un preajuste para insertar su código de mapeo de entrada y salida. La lista se carga desde el archivo de adaptadores de chat incluido; el código generado sigue siendo editable.",
77
+ "chatAdapterCodeHelp": "Los mapeos se ejecutan de forma síncrona. Devuelve msg para continuar o ningún valor para descartarlo. Los errores se capturan y notifican sin detener Node-RED."
65
78
  },
66
79
  "placeholder": {
67
80
  "llmBaseUrl": "https://api.openai.com/v1/chat/completions (or your compatible endpoint)",
@@ -45,7 +45,7 @@ Estas opciones solo aparecen cuando tienen sentido para el tipo seleccionado. Lo
45
45
 
46
46
  ## PINes del nodo
47
47
 
48
- Si habilitas los PINes de entrada/salida del nodo:
48
+ El selector de PINes está fuera de las pestañas del editor. Al activarlo aparece justo debajo una sección contextual **Entrada/salida del flow**, con ejemplos copiables filtrados según el tipo de dispositivo:
49
49
 
50
50
  - **Entrada**: actualiza el estado Matter desde el flow, sin pasar por el bus KNX: `msg.payload = { function: "onoff", value: true }` (`function` es una de `onoff`, `level`, `rgb`, `colortemp`, `position`, `temperature`, `humidity`, `illuminance`, `occupancy`, `contact`, `currenttemp`, `setpoint`, `fanspeed`, `smoke`, `co`, `leak`, `co2`, `rvcstate`, `rvcmode`). Útil para exponer a Alexa y cía. valores calculados en el flow (p.ej. un sensor virtual).
51
51
  - **Salida**: cada comando recibido de un controlador Matter se reenvía al flow: `msg.topic` = nombre del dispositivo, `msg.payload` = valor, `msg.matter` = el comando en bruto. Un dispositivo sin GA de comando se convierte en un **dispositivo solo-flow**.
@@ -36,6 +36,20 @@
36
36
  "mappings": "Asignaciones KNX",
37
37
  "advanced": "Opciones avanzadas"
38
38
  },
39
+ "flow_help": {
40
+ "title": "Entrada/salida del flow",
41
+ "intro": "Estos ejemplos corresponden al tipo de dispositivo seleccionado y están disponibles mientras los pines de entrada/salida del nodo están activados.",
42
+ "input_title": "Flow → Matter (entrada del nodo)",
43
+ "input_hint": "Envía uno de estos mensajes para actualizar el estado Matter expuesto sin escribir en KNX.",
44
+ "output_title": "Matter → Flow (salida del nodo)",
45
+ "output_hint": "Los comandos recibidos de un controlador Matter se emiten con el valor en msg.payload y los detalles raw en msg.matter.",
46
+ "function": "Función",
47
+ "message": "Mensaje de ejemplo",
48
+ "copy": "Copiar",
49
+ "copied": "Mensaje copiado",
50
+ "no_input": "Este tipo de dispositivo no tiene ejemplos de actualización de estado desde el flow.",
51
+ "no_output": "Este tipo de dispositivo no emite comandos del controlador; su salida permanece inactiva."
52
+ },
39
53
  "functions": {
40
54
  "fn_onoff_cmd": "GA comando On/Off",
41
55
  "fn_onoff_status": "GA estado On/Off",
@@ -19,11 +19,11 @@ Sustituye a los nodos Matter separados no publicados y conserva toda la UI de lu
19
19
  | Sensores | Los endpoints de sensor muestran su GA de medida/estado solo cuando está soportado: temperatura, humedad, iluminancia, ocupación, contacto y batería. |
20
20
  | Read at startup | Publica el valor Matter en caché al desplegar/iniciar o cuando el dispositivo se reconecta. |
21
21
  | Update local state from KNX write | Actualiza la caché local Matter/KNX cuando se escribe un telegrama en una GA KNX configurada. |
22
- | Node Input/Output PINs | Muestra pines de entrada/salida Node-RED. Los endpoints que no son luces aceptan el formato simple `{function,value}` y los campos Matter avanzados; la salida emite estados. |
22
+ | Node Input/Output PINs | Muestra pines de entrada/salida Node-RED y la sección **Entrada del flow** justo debajo de este campo. Las luces muestran sus mensajes de estado compatibles en el nivel superior; los demás endpoints muestran el formato simple `{function,value}` y los campos Matter avanzados. |
23
23
 
24
24
  ## Entrada del flow
25
25
 
26
- Para un endpoint que no sea una luz, abre la pestaña **Entrada del flow**. La pestaña se construye con la estructura anunciada y muestra ejemplos copiables, el Endpoint ID, todos los atributos legibles/escribibles y los comandos aceptados. Sigue disponible cuando el nodo se usa solo desde el flow, sin gateway KNX.
26
+ Activa **Node Input/Output PINs** para mostrar la sección **Entrada del flow** justo debajo del selector. Para una luz, muestra ejemplos copiables de las propiedades compatibles en el nivel superior, como `msg.on`, `msg.dimming`, `msg.color_temperature` y `msg.color`. Para los demás endpoints, se construye con la estructura anunciada y muestra el Endpoint ID, todos los atributos legibles/escribibles y los comandos aceptados. Sigue disponible sin gateway KNX.
27
27
 
28
28
  Una escritura simple usa `msg.payload = {function:"position",value:35}`. Omite `value` para leer un estado, por ejemplo `{function:"temperature"}`; la salida usa unidades comprensibles e incluye los detalles raw en `msg.matter`. Las funciones `onoff`, `level`, `position`, `open`, `close`, `stop`, consignas, ventilador y sensores solo aparecen si el endpoint las anuncia. Una cerradura acepta `{function:"lock",value:true|false}`.
29
29
 
@@ -17,6 +17,7 @@
17
17
  "input_help_endpoint_hint": "El nodo ya conoce el Node ID y el Endpoint ID; los mensajes simples no los necesitan.",
18
18
  "input_help_simple_title": "Mensajes simples",
19
19
  "input_help_simple_hint": "Estas funciones usan unidades comprensibles y se traducen al clúster, comando o atributo Matter del endpoint seleccionado.",
20
+ "input_help_light_hint": "Los endpoints de luz aceptan propiedades de estado directamente en msg (no dentro de msg.payload). Solo se muestran los controles compatibles con la luz seleccionada.",
20
21
  "input_help_advanced_title": "Detalles Matter avanzados",
21
22
  "input_help_advanced_hint": "Solo se muestran atributos y comandos anunciados. Los ejemplos de escritura usan 0 como marcador; los argumentos de los comandos pueden requerir adaptación al tipo Matter.",
22
23
  "input_help_operation": "Operación",
@@ -31,7 +32,7 @@
31
32
  "input_help_no_simple": "Este endpoint no tiene funciones de entrada simples conocidas.",
32
33
  "input_help_no_structure": "La estructura Matter no está disponible. Actualiza la lista de dispositivos mientras el endpoint esté en línea.",
33
34
  "input_functions": {
34
- "onoff": "Encender / Apagar", "level": "Nivel", "position": "Posición de persiana", "tiltposition": "Inclinación de persiana", "open": "Abrir", "close": "Cerrar", "stop": "Detener", "setpoint": "Consigna de calefacción", "coolingsetpoint": "Consigna de refrigeración", "currenttemp": "Temperatura actual", "fanspeed": "Velocidad del ventilador", "temperature": "Temperatura", "humidity": "Humedad", "illuminance": "Iluminancia", "occupancy": "Ocupación", "contact": "Contacto", "battery": "Batería", "activepower": "Potencia activa", "importedenergy": "Energía importada", "identify": "Identificar", "lock": "Bloquear", "unlock": "Desbloquear"
35
+ "onoff": "Encender / Apagar", "on": "Encender", "off": "Apagar", "level": "Nivel", "brightness": "Brillo", "color_temperature": "Temperatura de color", "xy_color": "Color XY", "position": "Posición de persiana", "tiltposition": "Inclinación de persiana", "open": "Abrir", "close": "Cerrar", "stop": "Detener", "setpoint": "Consigna de calefacción", "coolingsetpoint": "Consigna de refrigeración", "currenttemp": "Temperatura actual", "fanspeed": "Velocidad del ventilador", "temperature": "Temperatura", "humidity": "Humedad", "illuminance": "Iluminancia", "occupancy": "Ocupación", "contact": "Contacto", "battery": "Batería", "activepower": "Potencia activa", "importedenergy": "Energía importada", "identify": "Identificar", "lock": "Bloquear", "unlock": "Desbloquear"
35
36
  },
36
37
  "tabs": {
37
38
  "switch": "Cambiar",
@@ -1,18 +1,48 @@
1
1
  <script type="text/markdown" data-help-name="knxUltimateAI">
2
2
  Ce nœud écoute **tous les télégrammes KNX** du gateway KNX Ultimate sélectionné, produit des statistiques de trafic, détecte des anomalies et peut interroger un LLM de façon optionnelle.
3
3
 
4
+ Les sections de l'éditeur utilisent les mêmes onglets verticaux à gauche que les nœuds Matter. **Configuration rapide** ne contient que les choix AI courants (activation, fournisseur, identifiants, modèle, lecture des états/commande des actionneurs KNX et confirmation) ; les paramètres techniques sont regroupés par thème dans les autres onglets.
5
+
4
6
  ## Sorties
5
7
  1. **Résumé/Stats** (`msg.payload` JSON)
6
8
  2. **Anomalies** (`msg.payload` JSON)
7
9
  3. **Assistant IA** (`msg.payload` texte, avec `msg.summary`)
10
+ 4. **Opérations KNX** (un message Universal Mode par lecture ou écriture validée)
11
+
12
+ Chaque message émis par les sorties 3 et 4 contient également une copie du message d'entrée original dans `msg.inputMessage`. Le payload, le topic, les métadonnées du chat et toutes les autres propriétés d'entrée restent ainsi disponibles pour les nœuds suivants. Les erreurs de clonage ou d'envoi sont interceptées et signalées sans se propager au runtime Node-RED.
8
13
 
9
14
  ## Commandes (entrée)
10
15
  Envoyez `msg.topic` :
11
16
  - `summary` (ou vide) : envoie le résumé immédiatement
12
17
  - `reset` : vide l'historique/compteurs internes
13
18
  - `ask` : envoie une question au LLM configuré
19
+ - `confirm` / `cancel` : confirme ou annule les commandes KNX en attente sans rappeler le LLM
20
+ - `clear_chat` : efface la mémoire de conversation de la session courante
21
+
22
+ Pour `ask`, mettez la question dans `msg.prompt` (recommandé), `msg.payload` (chaîne), ou les champs Telegram courants `msg.payload.content` / `msg.payload.text`.
23
+
24
+ Lorsque le contrôle KNX est activé, les échanges récents sont conservés en RAM par `msg.knxAi.sessionId`, `msg.sessionId` ou ID de chat Telegram détecté. Reliez la sortie 3 au nœud d'envoi du chat et la sortie 4 à un nœud KNX Ultimate en **mode universel**. Avec la confirmation active, la première réponse affiche GA, DPT et payload sans émettre d’écriture ; la même session doit répondre `CONFIRMER` ou `ANNULER` dans les 5 minutes. Une nouvelle demande remplace tout plan précédent. Chaque commande confirmée contient `msg.destination`, `msg.dpt`, `msg.payload` et `msg.event = "GroupValue_Write"`.
25
+ Pour les écritures DPT 1.xxx, les équivalents sûrs produits par l’IA `true`/`false`, `1`/`0` et `on`/`off` sont normalisés en véritables booléens avant la validation locale et la sortie.
26
+
27
+ ### Lectures KNX actualisées
28
+ Lorsque l’utilisateur demande explicitement un état actuel ou actualisé, l’IA peut interroger les objets exacts du catalogue ETS importé, y compris les objets d’état et autres objets en lecture seule. La sortie 4 émet `msg.destination`, `msg.dpt`, `msg.event = "GroupValue_Read"` et `msg.readstatus = true`. Le nœud attend jusqu’à 6 secondes chaque `GroupValue_Response` ou écriture récente, puis renvoie les valeurs décodées sur la sortie 3 et les détails dans `msg.knxAi.readResults`. Les lectures ne nécessitent jamais de confirmation et ne sont jamais transformées en écritures.
29
+
30
+ ### Demande de confirmation pour les boutons du chat
31
+ Lorsqu'un plan est en attente, la sortie 3 contient `msg.knxAi.confirmationRequest`. L'objet comprend `required`, `status`, `sessionId`, `expiresAt`, `commandCount` et deux éléments dans `actions`. Utilisez `action.label` comme texte du bouton Telegram, `action.callbackData` comme callback et renvoyez `action.message` à KNX AI pour confirmer ou annuler sans saisir de texte.
32
+
33
+ ### Préréglages d’adaptateur de chat
34
+ L’onglet **Adaptateurs de chat** charge ses mappages sélectionnables depuis `resources/KNXAIChatAdapterMappings.js`. Le choix d’un préréglage insère deux mappages JavaScript synchrones et modifiables dans des zones de texte pleine largeur : un avant le traitement de l’entrée par KNX AI et un avant l’émission sur la sortie 3. Renvoyez `msg` pour continuer ou aucune valeur pour écarter le message. Les erreurs de syntaxe et d’exécution sont interceptées et signalées sans arrêter Node-RED.
35
+
36
+ Le préréglage inclus **windkh/node-red-contrib-telegrambot** suit le contrat receiver/sender du paquet. Connectez directement un `telegram receiver` à KNX AI et la sortie 3 à un `telegram sender`. Pour les boutons de confirmation inline, connectez aussi un `telegram event` configuré pour `callback_query` à la même entrée KNX AI. Le mappage d’entrée extrait `msg.payload.content`, `msg.payload.chatId` et la langue Telegram. Le mappage de sortie crée `msg.payload.chatId`, `type` et `content`, puis ajoute `options.reply_markup` depuis `msg.knxAi.confirmationRequest` lorsqu’une écriture attend confirmation. Le paquet Telegram reste une dépendance optionnelle distincte.
14
37
 
15
- Pour `ask`, mettez la question dans `msg.prompt` (recommandé) ou `msg.payload` (chaîne).
38
+ ## Workflow rapide : contrôle KNX
39
+ 1. Importez le CSV ETS dans la passerelle et configurez le fournisseur, le modèle et les identifiants LLM.
40
+ 2. Activez **Assistant LLM** et **lecture des états KNX et commande des actionneurs** ; laissez la confirmation activée.
41
+ 3. Connectez l'entrée du chat à KNX AI en conservant un identifiant de session/chat stable.
42
+ 4. Connectez la sortie 3 à la réponse du chat et la sortie 4 à KNX Ultimate en **mode universel**.
43
+ 5. L'utilisateur envoie une demande ; les états actuels sont lus immédiatement, tandis que les écritures affichent d'abord GA, DPT et valeur sans écrire sur le bus.
44
+ 6. Dans les 5 minutes, le même chat répond exactement `CONFIRMER` ou `ANNULER`.
45
+ 7. Seul `CONFIRMER` revalide et émet les commandes sur la sortie 4 ; vérifiez l'exécution avec une GA d'état KNX.
16
46
 
17
47
  ## Champs de configuration
18
48
  Voici tous les champs tels qu'affichés dans l'éditeur KNX AI.
@@ -53,7 +83,13 @@ Voici tous les champs tels qu'affichés dans l'éditeur KNX AI.
53
83
  - **Endpoint URL** : URL endpoint chat/completions.
54
84
  - **API key** : clé API (non requise avec Ollama local).
55
85
  - **Model** : ID/nom du modèle.
86
+ - **Compatibilité du modèle de chat** : le modèle sélectionné doit prendre en charge l'endpoint Chat Completions configuré. Les anciens modèles réservés aux completions, comme `gpt-3.5-turbo-instruct`, sont exclus lors de l'actualisation de la liste. Si le fournisseur refuse une valeur de température personnalisée ou le paramètre de limite de tokens, KNX AI réessaie en supprimant ou remplaçant uniquement le champ incompatible.
56
87
  - **System prompt** : instruction système globale pour l'analyse KNX (Advanced).
88
+ - **Autoriser l’IA à lire les états KNX et commander les actionneurs** : active la sortie 4 et reste désactivé par défaut. Les objets exacts du catalogue ETS peuvent être lus ; seules les écritures vers des objets classés `command` sont acceptées. Les opérations inconnues, avec DPT discordant, invalides ou trop nombreuses, ainsi que les écritures vers des objets d'état ou neutres, sont rejetées localement.
89
+ - **Demander confirmation avant d’envoyer les commandes KNX** : activé par défaut. Affiche d'abord les modifications validées et n'émet aucune commande tant que la même session de chat ne les confirme pas. Lorsque des commandes attendent une confirmation, la réponse ajoute toujours les instructions exactes de confirmation ou d'annulation dans la langue de la demande courante. Les commandes sont à nouveau validées juste avant la sortie.
90
+ - **Préréglage d’adaptateur** : charge une paire de mappages entrée/sortie depuis le fichier d’adaptateurs de chat fourni. La sélection remplace volontairement les deux zones de texte ; le code reste ensuite modifiable.
91
+ - **Mappage d’entrée (chat → KNX AI)** : JavaScript synchrone exécuté avant le traitement de la commande d’entrée.
92
+ - **Mappage de sortie (KNX AI → chat)** : JavaScript synchrone appliqué uniquement aux messages de la sortie 3.
57
93
  - Si l'archive disque est active, **Ask** l'utilise par défaut : les dates/plages explicites sont respectées, sinon l'assistant cherche sur les dernières 24 heures plus les événements RAM courants.
58
94
  - **Include raw payload hex** : inclut le payload hex brut dans le prompt.
59
95
  - **Inclure l'inventaire du projet Node-RED** : inclut dans le prompt l'inventaire de tout le projet Node-RED, avec les nœuds KNX et d'autres nœuds utiles comme function/change/inject/template lorsqu'ils contiennent de la logique KNX ou des adresses de groupe.
@@ -84,5 +120,5 @@ Voici tous les champs tels qu'affichés dans l'éditeur KNX AI.
84
120
  - Si Node-RED tourne dans Docker, utiliser `host.docker.internal` au lieu de `localhost` dans l'endpoint.
85
121
 
86
122
  ## Note sécurité
87
- Si le LLM est activé, le contexte trafic KNX peut être envoyé à l'endpoint configuré. Pour un usage strictement on-premise, utilisez un provider local.
123
+ Si le LLM est activé, le contexte trafic KNX peut être envoyé à l'endpoint configuré. Pour un usage strictement on-premise, utilisez un provider local. Une commande émise en sortie 4 a passé la validation locale et a été transmise au flow, sans prouver son exécution par l'actionneur. Utilisez une GA d'état KNX pour la confirmation.
88
124
  </script>
@@ -2,12 +2,14 @@
2
2
  "knxUltimateAI": {
3
3
  "title": "KNX AI (Traffic Analyzer)",
4
4
  "sections": {
5
+ "quickSetup": "Configuration rapide",
5
6
  "capture": "Capture",
6
7
  "storage": "Historique et Resume",
7
8
  "detection": "Detection et Alertes",
8
9
  "llmConnection": "Connexion Assistant IA",
9
10
  "llmContext": "Contexte Assistant IA",
10
- "advanced": "Reglages Avances"
11
+ "chatAdapter": "Adaptateurs de chat",
12
+ "advanced": "IA avancee"
11
13
  },
12
14
  "properties": {
13
15
  "server": "Gateway",
@@ -39,19 +41,28 @@
39
41
  "llmSystemPrompt": "System prompt",
40
42
  "llmIncludeRaw": "Include raw payload hex",
41
43
  "llmIncludeFlowContext": "Inclure l'inventaire du projet Node-RED",
44
+ "llmAllowKnxCommands": "Autoriser l’IA à lire les états KNX et commander les actionneurs",
45
+ "llmRequireCommandConfirmation": "Demander confirmation avant d’envoyer les commandes KNX",
46
+ "chatAdapterPreset": "Préréglage d’adaptateur",
47
+ "chatInputCode": "Mappage d’entrée (chat → KNX AI)",
48
+ "chatOutputCode": "Mappage de sortie (KNX AI → chat)",
42
49
  "llmIncludeDocsSnippets": "Include documentation snippets (help/README/examples)",
43
50
  "llmDocsLanguage": "Docs language"
44
51
  },
45
52
  "outputs": {
46
53
  "summary": "Résumé/Stats",
47
54
  "anomalies": "Anomalies",
48
- "assistant": "Assistant IA"
55
+ "assistant": "Assistant IA",
56
+ "knxCommands": "Opérations KNX"
49
57
  },
50
58
  "selectlists": {
51
59
  "llmProvider": {
52
60
  "openai_compat": "OpenAI-compatible (chat/completions)",
53
61
  "anthropic": "Anthropic (Claude)",
54
62
  "ollama": "Ollama (local, beta)"
63
+ },
64
+ "chatAdapter": {
65
+ "none": "Aucun adaptateur"
55
66
  }
56
67
  },
57
68
  "messages": {
@@ -61,7 +72,9 @@
61
72
  "installedOllamaModel": "Ollama model installed",
62
73
  "installOllamaModelFailed": "Failed to install Ollama model",
63
74
  "ollamaInstallSteps": "1) Open the model library and copy the model name (for example llama3.1). 2) Put the name in the Model field and click Install it.",
64
- "ollamaStartedAuto": "Ollama server started automatically."
75
+ "ollamaStartedAuto": "Ollama server started automatically.",
76
+ "chatAdapterIntro": "Choisissez un préréglage pour insérer son code de mappage d’entrée et de sortie. La liste est chargée depuis le fichier d’adaptateurs de chat fourni ; le code généré reste modifiable.",
77
+ "chatAdapterCodeHelp": "Les mappages s’exécutent de façon synchrone. Renvoyez msg pour continuer ou aucune valeur pour l’écarter. Les erreurs sont interceptées et signalées sans arrêter Node-RED."
65
78
  },
66
79
  "placeholder": {
67
80
  "llmBaseUrl": "https://api.openai.com/v1/chat/completions (or your compatible endpoint)",
@@ -45,7 +45,7 @@ Ces options ne s'affichent que lorsqu'elles s'appliquent au type sélectionné.
45
45
 
46
46
  ## PIN du nœud
47
47
 
48
- Si vous activez les PIN entrée/sortie du nœud :
48
+ Le sélecteur de PIN se trouve hors des onglets de l'éditeur. Son activation affiche juste dessous une section contextuelle **Entrée/sortie du flow**, avec des exemples copiables filtrés selon le type d'appareil :
49
49
 
50
50
  - **Entrée** : mettez à jour l'état Matter depuis le flux, sans passer par le bus KNX : `msg.payload = { function: "onoff", value: true }` (`function` est l'une de `onoff`, `level`, `rgb`, `colortemp`, `position`, `temperature`, `humidity`, `illuminance`, `occupancy`, `contact`, `currenttemp`, `setpoint`, `fanspeed`, `smoke`, `co`, `leak`, `co2`, `rvcstate`, `rvcmode`). Utile pour exposer à Alexa & Co. des valeurs calculées dans le flux (ex. un capteur virtuel).
51
51
  - **Sortie** : chaque commande reçue d'un contrôleur Matter est transmise au flux : `msg.topic` = nom de l'appareil, `msg.payload` = valeur, `msg.matter` = la commande brute. Un appareil sans GA de commande devient un **appareil flow uniquement**.
@@ -36,6 +36,20 @@
36
36
  "mappings": "Mappages KNX",
37
37
  "advanced": "Options avancées"
38
38
  },
39
+ "flow_help": {
40
+ "title": "Entrée/sortie du flow",
41
+ "intro": "Ces exemples correspondent au type d'appareil sélectionné et sont disponibles lorsque les broches d'entrée/sortie du nœud sont activées.",
42
+ "input_title": "Flow → Matter (entrée du nœud)",
43
+ "input_hint": "Envoyez l'un de ces messages pour mettre à jour l'état Matter exposé sans écrire sur KNX.",
44
+ "output_title": "Matter → Flow (sortie du nœud)",
45
+ "output_hint": "Les commandes reçues d'un contrôleur Matter sont émises avec la valeur dans msg.payload et les détails bruts dans msg.matter.",
46
+ "function": "Fonction",
47
+ "message": "Message d'exemple",
48
+ "copy": "Copier",
49
+ "copied": "Message copié",
50
+ "no_input": "Ce type d'appareil ne possède aucun exemple de mise à jour d'état depuis le flow.",
51
+ "no_output": "Ce type d'appareil n'émet aucune commande de contrôleur ; sa sortie reste inactive."
52
+ },
39
53
  "functions": {
40
54
  "fn_onoff_cmd": "GA commande On/Off",
41
55
  "fn_onoff_status": "GA état On/Off",