Dieses Proposal beschreibt die Einführung von zwei neuen MQTT-Funktionalitäten: die Durchführung eines Factory Resets auf dem Signalduino-Gerät und das Abrufen der aktuellen CC1101-Hardware-Einstellungen (Frequenz, Bandbreite, Verstärkung, Empfindlichkeit, Datenrate) über MQTT. Die Implementierung basiert auf dem Refactoring des MQTT-Befehls-Handlings, indem der vorhandene MqttCommandDispatcher zentral in signalduino/mqtt.py verwendet wird.
Aktuell müssen Hardware-Einstellungen direkt über die serielle Konsole des Signalduino-Geräts abgefragt werden. Für einen Factory Reset (Serial Command e (EEPROM Defaults)) fehlt ein hochstufiger, zugänglicher Mechanismus. Die bestehende MQTT-Befehlslogik in signalduino/mqtt.py ist eine unstrukturierte if/elif-Kette, die eine Erweiterung erschwert. Die Motivation ist, eine vollständig über MQTT fernsteuerbare und auslesbare Schnittstelle für die Geräteeinstellungen zu schaffen.
-
Refactoring: Ersetze die
if/elif-Logik insignalduino/mqtt.pydurch den [MqttCommandDispatcher](signalduino/commands.py:193) (siehe ADR 002). -
Factory Reset: Definiere und implementiere den MQTT-Befehl für den Signalduino Factory Reset (
e). -
Hardware-Status-Abruf: Implementiere neue Controller-Methoden und MQTT-Befehle, um die aktuellen CC1101-Einstellungen (Freq, Bandwidth, rAmpl, sens, DataRate) auszulesen.
-
Tooling: Entwirf die Schnittstelle für ein CLI-Helfer-Tool zum Testen und Steuern dieser Befehle.
Die Architektur nutzt die bereits existierende Schichtenarchitektur von PySignalduino (MQTT Publisher → Controller → Serial Commands). Der Schlüssel liegt in der Zentralisierung des Befehls-Routings im MqttCommandDispatcher.
graph TD
A[MQTT Client] --> B(MqttPublisher / Listener);
B --> C{MqttCommandDispatcher};
C --> D[SignalduinoController];
D --> E[SignalduinoCommands (Serial API)];
E --> F[Signalduino Hardware];
subgraph Signal Path (Commands)
B -- Refactored Handler --> C
C -- Payload Validation / Routing --> D
D -- High-Level Call --> E
E -- Low-Level Serial --> F
end
Dieses Diagramm zeigt den Ablauf für den Factory Reset und das Abrufen der Bandbreite.
sequenceDiagram
participant Mq as MQTT Client (Tool)
participant Mqp as MqttPublisher (signalduino/mqtt.py)
participant Disp as MqttCommandDispatcher
participant Ctrl as SignalduinoController
participant Cmd as SignalduinoCommands
participant SDU as Signalduino Hardware
group Factory Reset (Command)
Mq->>Mqp: PUBLISH (Topic: .../commands/command/factory_reset, Payload: {"req_id": "123"})
Mqp->>Disp: dispatch("command/factory_reset", payload)
Disp->>Ctrl: command_factory_reset(payload)
Ctrl->>Cmd: send_command("e")
Cmd->>SDU: Serial: e
SDU-->>Cmd: Serial: OK / Timeout
Cmd-->>Ctrl: Result
Ctrl-->>Disp: Response Data
Disp-->>Mqp: Result Dict
Mqp->>Mq: PUBLISH (Topic: .../responses, Payload: success: true, req_id: "123")
end
group Hardware Status (GET)
Mq->>Mqp: PUBLISH (Topic: .../commands/get/cc1101/bandwidth, Payload: {"req_id": "456"})
Mqp->>Disp: dispatch("get/cc1101/bandwidth", payload)
Disp->>Ctrl: get_cc1101_bandwidth(payload)
Ctrl->>Cmd: read_cc1101_register(0x10)
Cmd->>SDU: Serial: C10
SDU-->>Cmd: Serial: C10 = 02 (Beispiel)
Cmd->>Cmd: Decode to Bandwidth (z.B. 102 kHz)
Cmd-->>Ctrl: 102 (kHz)
Ctrl-->>Disp: 102
Disp-->>Mqp: Response Data
Mqp->>Mq: PUBLISH (Topic: .../responses, Payload: data: 102, req_id: "456")
end
-
signalduino/v1/commands/command/factory_reset -
signalduino/v1/commands/get/cc1101/bandwidth -
signalduino/v1/commands/get/cc1101/rampl -
signalduino/v1/commands/get/cc1101/sensitivity -
signalduino/v1/commands/get/cc1101/datarate
Neue Methoden in [SignalduinoCommands](signalduino/commands.py:20), die das Lesen der CC1101-Register kapseln und die Rohwerte in nutzbare Einheiten (kHz, dB) umrechnen:
* factory_reset() (Serial Command e)
* get_bwidth() (liest Register 0x10 und berechnet die Bandbreite)
* get_rampl() (liest Register 0x1B und decodiert die Verstärkung)
* get_sens() (liest Register 0x1D und decodiert die Empfindlichkeit)
* get_datarate() (liest Register 0x10 und 0x11 und berechnet die Datenrate)
-
Kein Refactoring: Das Beibehalten der
if/elif-Kette insignalduino/mqtt.pywurde abgelehnt, da es die Wartbarkeit reduziert und dem Architekturprinzip der Trennung der Zuständigkeiten widerspricht (siehe ADR-002). -
Keine Abfrage einzelner Werte: Stattdessen nur einen Sammelbefehl (
get/cc1101/status) implementieren. Dies wurde abgelehnt, da es die Konsistenz mit dem bereits vorhandenenget/cc1101/frequencybricht und nicht die Flexibilität für clientspezifische Abfragen bietet.
-
Bestehender Code: Die Methode
MqttPublisher._handle_commandinsignalduino/mqtt.pymuss vollständig refaktorisiert werden, um den Dispatcher zu verwenden. Die bestehende Logik fürget/system/versionundget/cc1101/frequencywird entfernt und über den Dispatcher abgewickelt. -
Abhängigkeiten: Keine neuen externen Abhängigkeiten erforderlich.
Der detaillierte Implementierungsplan wird in Phase 2 erstellt, basiert aber auf den folgenden High-Level-Schritten:
-
Refactoring: Initialisiere den
MqttCommandDispatcherinMqttPublisher.initund aktualisiereMqttPublisher._handle_commandzur Verwendung des Dispatchers. -
Controller-Erweiterung: Füge die High-Level-Methoden
command_factory_reset,get_cc1101_bandwidth,get_cc1101_rampl,get_cc1101_sensitivity,get_cc1101_dataratezumSignalduinoControllerhinzu. -
Serial Commands: Implementiere die entsprechenden Low-Level-Methoden (
factory_reset,get_bwidth,get_rampl,get_sens,get_datarate) in [SignalduinoCommands](signalduino/commands.py:20) inklusive der Register-Decodierungslogik. -
Dispatcher-Aktualisierung: Erweitere
COMMAND_MAPinsignalduino/commands.pyum die neuen Befehle und deren Schemata.
Es wird ein kleines Python-Helfer-Tool (z.B. signalduino-mqtt-cli) entworfen, das über die Kommandozeile MQTT-Befehle senden kann. Dieses Tool wird die neuen Funktionen demonstrieren und zur Verifikation dienen.
-
sd-mqtt-cli reset --req-id <ID>(Sendetcommand/factory_reset) -
sd-mqtt-cli get hardware-status --req-id <ID> --parameter bandwidth(Sendetget/cc1101/bandwidth) -
sd-mqtt-cli get hardware-status --all --req-id <ID>(Optional: Implementiert einen Batch-Abruf oder ruft alle einzelnen GET-Befehle sequenziell ab und gibt das konsolidierte Ergebnis aus.)
Dieses Tool würde die MqttPublisher Logik des Hauptprogramms in einem CLI-Kontext nachbilden, um PUBLISH/SUBSCRIBE für Request/Response zu handhaben.