Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:2-3-bookworm",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true,
"installYarnUsingApt": true,
"version": "lts",
"pnpmVersion": "latest",
"nvmVersion": "latest"
},
"ghcr.io/devcontainer-community/devcontainer-features/astral.sh-uv:1": {
"shellautocompletion": true,
"version": "latest"
}
//"ghcr.io/hspaans/devcontainer-features/pytest:2": {}
},

Expand All @@ -23,7 +34,12 @@
]
}
},
"runArgs": ["--env-file", ".devcontainer/devcontainer.env"]
"runArgs": [
"--env-file",
".devcontainer/devcontainer.env",
"--network=bridge",
"--memory=4gb"
],

// Configure tool-specific properties.
// "customizations": {},
Expand Down
20 changes: 20 additions & 0 deletions .roo/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/workspaces/PySignalduino"
]
},
"git": {
"command": "uvx",
"args": [
"mcp-server-git",
"--repository",
"/workspaces/PySignalduino"
]
}
}
}
20 changes: 20 additions & 0 deletions .roomodes
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
customModes:
- slug: perlmigrator
name: PerlMigrator
roleDefinition: |-
You are a Software Architect. Your a specalized on Perl and Python.
First you plan your work and then you create the code.
The main goal is to transform the functionality from the perl project into the python project.
customInstructions: |
We have a perl project which is working as expected. Every time, when migrating code to python, the perl code and also the test results act as a master.

If converting tests you will convert the testcases on an 1:1 basis in respect to the testdata and results.
After creating a pythontest you will run it to be sure, that it passes.
groups:
- read
- edit
- browser
- command
- mcp
source: project
description: perl-2-python-architect
43 changes: 41 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ This file provides guidance to agents when working with code in this repository.
oder um eine längere Laufzeit zu analysieren:
`python3 main.py --timeout 30`

## Test Timeout Configuration
- Für pytest wurde ein globaler Timeout von 30 Sekunden in der `pyproject.toml` konfiguriert:
```toml
[tool.pytest.ini_options]
timeout = 30
```
- Die erforderliche Abhängigkeit `pytest-timeout` wurde zur `requirements-dev.txt` hinzugefügt.

## Mandatory Documentation and Test Maintenance

Diese Richtlinie gilt für alle AI-Agenten, die Code oder Systemkonfigurationen in diesem Repository ändern. Jede Änderung **muss** eine vollständige Analyse der Auswirkungen auf die zugehörige Dokumentation und die Testsuite umfassen.
Expand Down Expand Up @@ -83,7 +91,7 @@ Dieser Abschnitt definiert den verbindlichen Arbeitsablauf für die Entwicklung
- Aufteilung in konkrete Arbeitspakete (Tasks)
- Definition von Akzeptanzkriterien für jede Komponente
- Planung von Teststrategien (Unit, Integration, System)
- Ressourcen- und Zeitplanung
- Ressourcen- und Zeitplaning
- Erstellung von Mockups/Prototypen für kritische Pfade
- **Deliverables:**
- Implementierungsplan mit Task-Breakdown
Expand Down Expand Up @@ -243,4 +251,35 @@ flowchart TD

Dieser Architecture-First Development Process ist für **alle** neuen Funktionen und wesentlichen Änderungen verbindlich. Ausnahmen sind nur bei kritischen Bugfixes erlaubt und müssen durch einen Emergency-ADR dokumentiert werden. Jede Abweichung vom Prozess muss vom Architecture Owner genehmigt werden.

Die Einhaltung dieses Prozesses gewährleistet, dass Design-Entscheidungen bewusst getroffen, dokumentiert und nachvollziehbar sind, was die langfristige Wartbarkeit, Skalierbarkeit und Qualität des PySignalduino-Projekts sicherstellt.
Die Einhaltung dieses Prozesses gewährleistet, dass Design-Entscheidungen bewusst getroffen, dokumentiert und nachvollziehbar sind, was die langfristige Wartbarkeit, Skalierbarkeit und Qualität des PySignalduino-Projekts sicherstellt.

## Fehlerbehebungsprozess für fehlende Abhängigkeiten

### Problemidentifikation
1. **Symptom:** ImportError oder ModuleNotFoundError während der Testausführung
2. **Ursachenanalyse:**
- Überprüfen der Traceback-Meldung auf fehlende Module
- Vergleich mit requirements.txt und requirements-dev.txt
- Prüfen der Dokumentation auf Installationsanweisungen

### Lösungsimplementierung
1. **requirements-dev.txt aktualisieren:**
- Modulname zur Datei hinzufügen
- Commit mit Conventional Commits Syntax erstellen (z.B. "fix: add <module> to requirements-dev.txt")
2. **Dokumentation prüfen:**
- Sicherstellen, dass Installationsanweisungen in README.md und docs/ aktuell sind

### Verifikation
1. **Installation testen:**
```bash
pip install -r requirements-dev.txt
pytest
```
2. **Tests erneut ausführen:**
```bash
timeout 60 pytest ./tests/
```

### Dokumentation
- **AGENTS.md aktualisieren:** Diese Prozessbeschreibung hinzufügen
- **Commit erstellen:** Änderungen mit aussagekräftiger Nachricht committen
46 changes: 36 additions & 10 deletions docs/02_developer_guide/architecture.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,49 @@ Zusätzlich gibt es spezielle Tasks für Initialisierung, Heartbeat und MQTT-Com

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.

== MQTT-Integration
== MQTT-Integration (v1 API)

Die MQTT-Integration erfolgt über die Klasse `MqttPublisher` (`signalduino/mqtt.py`), die auf `aiomqtt` basiert und asynchrone Veröffentlichung und Abonnement unterstützt.
Die MQTT-Integration wurde auf eine versionierte, konsistente Befehlsschnittstelle umgestellt, basierend auf dem Architecture Decision Record (ADR-001, ADR-002).

=== Verbindungsaufbau
=== Architektur der Befehlsverarbeitung

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.
Die Verarbeitung von eingehenden Befehlen erfolgt über ein dediziertes *Command Dispatcher Pattern* zur strikten Trennung von Netzwerk-Layer, Validierungslogik und Controller-Aktionen:

=== Topics und Nachrichtenformat
. *MqttPublisher* (`signalduino/mqtt.py`) empfängt eine Nachricht auf `signalduino/v1/commands/#`.
. Der *SignalduinoController* leitet die rohe Payload an den *MqttCommandDispatcher* weiter.
. Der *Dispatcher* (`signalduino/commands.py`) validiert die Payload gegen ein JSON-Schema (ADR-002).
. Bei Erfolg wird die entsprechende asynchrone Methode im *SignalduinoController* aufgerufen.
. Der *Controller* sendet serielle Kommandos (`W<reg><val>`, `V`, `CG`) und verpackt die Firmware-Antwort.
. Die finale Antwort (`status: OK` oder `error: 400/500/502`) wird an den Client zurückgesendet.

* **Sensordaten:** `{MQTT_TOPIC}/messages` – JSON‑Serialisierte `DecodedMessage`-Objekte.
* **Kommandos:** `{MQTT_TOPIC}/commands/{command}` – Ermöglicht die Steuerung des Signalduino via MQTT (z.B. `version`, `freeram`, `rawmsg`).
* **Status:** `{MQTT_TOPIC}/status/{alive,data,version}` – Heartbeat- und Gerätestatus.
=== Topic-Struktur und Versionierung (ADR-001)

=== Command-Listener
Alle Topics sind versioniert und verwenden das Präfix `{MQTT_TOPIC}/v1`.

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.
|===
| Topic-Typ | Topic-Struktur | Zweck
| Command (Request) | `signalduino/v1/commands/<type>/<target>/<param>` | Steuerung und Abfrage von Parametern (z.B. `get/system/version`)
| Response (Success) | `signalduino/v1/responses/<type>/<target>/<param>` | Strukturierte Antwort auf Befehle (`"status": "OK"`)
| Error (Failure) | `signalduino/v1/errors/<type>/<target>/<param>` | Strukturierte Fehlerinformationen (`"error_code": 400/500/502`)
| Telemetry | `signalduino/v1/state/messages` | JSON-serialisierte, dekodierte Sensordaten (`DecodedMessage`)
| Status | `signalduino/v1/status/{alive,data}` | Heartbeat- und Gerätestatus (z.B. `free_ram`, `uptime`)
|===

=== Payload-Format

Alle Requests (Commands) und Responses (Responses/Errors) verwenden eine standardisierte JSON-Struktur, die eine `req_id` zur Korrelation von Anfrage und Antwort erfordert.

[source,json]
----
{
"req_id": "uuid-12345",
"data": "V 3.5.7+20250219" // Nur in Responses
}
----

=== Wichtige Architekturentscheidungen
* link:../architecture/decisions/adr-001-mqtt-topic-structure.md[ADR-001: MQTT Topic Struktur und Versionierung]
* link:../architecture/decisions/adr-002-command-dispatcher.md[ADR-002: Command Dispatcher Pattern und JSON-Schema-Validierung]

== Komponentendiagramm (Übersicht)

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ include = ["signalduino", "sd_protocols"]

[tool.pytest.ini_options]
testpaths = ["tests"]
timeout = 30

[tool.pytest-asyncio]
mode = "auto"
2 changes: 2 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ pytest
pytest-mock
pytest-asyncio
pytest-cov
jsonschema
pytest-timeout
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ pyserial
requests
paho-mqtt
python-dotenv
asyncio-mqtt
jsonschema
pyserial-asyncio
aiomqtt
Loading
Loading