You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/02_developer_guide/architecture.adoc
+36-10Lines changed: 36 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -52,23 +52,49 @@ Zusätzlich gibt es spezielle Tasks für Initialisierung, Heartbeat und MQTT-Com
52
52
53
53
Alle Ressourcen (Transport, MQTT-Client) implementieren `__aenter__`/`__aexit__` und werden mittels `async with` verwaltet. Der `SignalduinoController` selbst ist ein Kontextmanager, der die Lebensdauer der Verbindung steuert.
54
54
55
-
== MQTT-Integration
55
+
== MQTT-Integration (v1 API)
56
56
57
-
Die MQTT-Integration erfolgt über die Klasse `MqttPublisher` (`signalduino/mqtt.py`), die auf `aiomqtt` basiert und asynchrone Veröffentlichung und Abonnement unterstützt.
57
+
Die MQTT-Integration wurde auf eine versionierte, konsistente Befehlsschnittstelle umgestellt, basierend auf dem Architecture Decision Record (ADR-001, ADR-002).
58
58
59
-
=== Verbindungsaufbau
59
+
=== Architektur der Befehlsverarbeitung
60
60
61
-
Der MQTT-Client wird automatisch gestartet, wenn die Umgebungsvariable `MQTT_HOST` gesetzt ist. Im `__aenter__` des Controllers wird der Publisher mit dem Broker verbunden und ein Command-Listener-Task gestartet.
61
+
Die Verarbeitung von eingehenden Befehlen erfolgt über ein dediziertes *Command Dispatcher Pattern* zur strikten Trennung von Netzwerk-Layer, Validierungslogik und Controller-Aktionen:
62
62
63
-
=== Topics und Nachrichtenformat
63
+
. *MqttPublisher* (`signalduino/mqtt.py`) empfängt eine Nachricht auf `signalduino/v1/commands/#`.
64
+
. Der *SignalduinoController* leitet die rohe Payload an den *MqttCommandDispatcher* weiter.
65
+
. Der *Dispatcher* (`signalduino/commands.py`) validiert die Payload gegen ein JSON-Schema (ADR-002).
66
+
. Bei Erfolg wird die entsprechende asynchrone Methode im *SignalduinoController* aufgerufen.
67
+
. Der *Controller* sendet serielle Kommandos (`W<reg><val>`, `V`, `CG`) und verpackt die Firmware-Antwort.
68
+
. Die finale Antwort (`status: OK` oder `error: 400/500/502`) wird an den Client zurückgesendet.
* **Kommandos:** `{MQTT_TOPIC}/commands/{command}` – Ermöglicht die Steuerung des Signalduino via MQTT (z.B. `version`, `freeram`, `rawmsg`).
67
-
* **Status:** `{MQTT_TOPIC}/status/{alive,data,version}` – Heartbeat- und Gerätestatus.
70
+
=== Topic-Struktur und Versionierung (ADR-001)
68
71
69
-
=== Command-Listener
72
+
Alle Topics sind versioniert und verwenden das Präfix `{MQTT_TOPIC}/v1`.
70
73
71
-
Ein separater asynchroner Loop (`_command_listener`) lauscht auf Kommando‑Topics, ruft den registrierten Callback (im Controller `_handle_mqtt_command`) auf und führt die entsprechende Aktion aus. Die Antwort wird unter `result/{command}` oder `error/{command}` zurückveröffentlicht.
74
+
|===
75
+
| Topic-Typ | Topic-Struktur | Zweck
76
+
| Command (Request) | `signalduino/v1/commands/<type>/<target>/<param>` | Steuerung und Abfrage von Parametern (z.B. `get/system/version`)
| Status | `signalduino/v1/status/{alive,data}` | Heartbeat- und Gerätestatus (z.B. `free_ram`, `uptime`)
81
+
|===
82
+
83
+
=== Payload-Format
84
+
85
+
Alle Requests (Commands) und Responses (Responses/Errors) verwenden eine standardisierte JSON-Struktur, die eine `req_id` zur Korrelation von Anfrage und Antwort erfordert.
86
+
87
+
[source,json]
88
+
----
89
+
{
90
+
"req_id": "uuid-12345",
91
+
"data": "V 3.5.7+20250219" // Nur in Responses
92
+
}
93
+
----
94
+
95
+
=== Wichtige Architekturentscheidungen
96
+
* link:../architecture/decisions/adr-001-mqtt-topic-structure.md[ADR-001: MQTT Topic Struktur und Versionierung]
97
+
* link:../architecture/decisions/adr-002-command-dispatcher.md[ADR-002: Command Dispatcher Pattern und JSON-Schema-Validierung]
0 commit comments