User Tools

Site Tools


projekte:ionpy:ideen

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
projekte:ionpy:ideen [2026/02/13 08:47] dominikprojekte:ionpy:ideen [2026/02/13 09:16] (current) – [Implementierung (Code-Skizze)] dominik
Line 1: Line 1:
-====== ionpy Framework: Erweiterte Architektur-Spezifikation ======+====== ionpy Framework: Erweiterte Architektur-Spezifikation (Vollständig) ======
  
-Dieses Dokument dient als detaillierte Implementierungsvorlage für die nächste Evolutionsstufe des ionpy-Frameworks. Ziel ist die Transformation von einer reinen Monitoring-Plattform zu einem interaktiven Automatisierungssystem.+Dieses Dokument beschreibt die integrale Architektur-Erweiterung des ionpy-Frameworks. Es dient als verbindliche Grundlage für die Implementierung neuer Entitätstypen, haptischer Steuerungen und geräteübergreifender Automatisierung.
  
-===== 1. Dynamische Eingabesynchronisation (The Mute-Pattern) ===== +===== 1. Dynamische Eingabesynchronisation (Race Condition Schutz) ===== 
-Problem: Race Conditions zwischen Hardware-Polling und User-Eingaben führen zu springenden Werten in der UI.+Um zu verhindern, dass Hintergrund-Polling Benutzereingaben im Frontend überschreibt, wird ein duales Sperrsystem implementiert.
  
-==== 1.1 Backend: Implementierung in AbstractDevice ==== +==== 1.1 Backend: Mute-Timer (AbstractDevice==== 
-[cite_start]Die Basisklasse ''AbstractDevice'' [cite: 113wird um ein Muting-System erweitert+[cite_start]In der Klasse ''AbstractDevice'' (hardware/base.py) wird eine zeitbasierte Sperre pro Entität eingeführt[cite: 117, 120]. 
-  * **Datenstruktur**: Ein Dictionary ''self._mute_until: Dict[str, float]'' speichert pro Entity-ID den Ablaufzeitstempel der Sperre+  * [cite_start]**Mechanismus**: Ein Dictionary ''self._last_command_time: Dict[str, float]'' speichert den Zeitpunkt des letzten Schreibbefehls[cite: 11, 54]
-  * **Code-Integration (hardware/base.py)**: +  * **Logik**:  
-    * [cite_start]In ''execute_command(self, entity_id, value)''[cite: 137]: Vor dem Aufruf des Handlers wird ''self._mute_until[entity_id] = time.time() + 3.0'' gesetzt+    * [cite_start]Sobald ''execute_command()'' aufgerufen wird, erhält die ''entity_id'' einen Zeitstempel[cite: 13, 138]
-    * [cite_start]In ''update_entity(self, entity_id, raw_value, ...)''[cite: 128]: Bevor das Sample erstellt wirderfolgt die Prüfung: +    * [cite_start]Die Methode ''update_entity()'' prüft diesen Zeitstempel: Liegt er weniger als **3,0 Sekunden** in der Vergangenheit, wird das Sample verworfen und nicht auf den Bus publiziert[cite: 87, 136]
-      <code>if time.time() < self._mute_until.get(entity_id, 0): return # Update verwerfen</code>+  * **Ziel**Die Hardware hat Zeitden Wert intern zu setzen, und der Polling-Loop liest keine "alten" Werte mehr zurück, während der User noch interagiert.
  
-==== 1.2 Frontend: Universeller Focus-Lock ==== +==== 1.2 Frontend: Universeller Focus-Lock (JS) ==== 
-In der ''settings.html'' wird ein globaler Schutzmechanismus implementiert, der unabhängig vom Gerätetyp funktioniert+In der Web-UI (settings.htmlwird eine automatische Erkennung aktiver Eingabefelder implementiert. 
-  * **Logik**: Verwendung eines ''Set()'' in JavaScript, das IDs von Elementen speichert, die den Fokus haben+  * **Mechanismus**: Nutzung eines ''Set()'' namens ''activeInputs''
-  * **Code-Hint**: +  * **Event-Delegation**: 
-    <code> +    * ''focusin'': Fügt die Element-ID zum Set hinzu
-    const lockedFields = new Set(); +    * ''focusout'': Entfernt die ID nach einer kurzen Verzögerung (ca. 300-500ms). 
-    containerEl.addEventListener('focusin', (e) => lockedFields.add(e.target.id)); +  * **WebSocket-Logik**Die Funktion ''channel.onmessage'' prüft vor dem Update eines HTML-Elements, ob dessen ID im Set vorhanden ist. [cite_start]Falls ja, wird das Update verworfen[cite: 53, 54].
-    containerEl.addEventListener('focusout'(e=> setTimeout(() => lockedFields.delete(e.target.id), 500)); +
-     +
-    // Im WebSocket-Handler: +
-    if (lockedFields.has(`i-${sample.entity_id}`)) return; +
-    </code>+
  
-===== 2. Strukturierte Daten: TableEntity ===== +===== 2. Strukturierte Daten: TableEntity (Deep Dive) ===== 
-[cite_start]Ermöglicht die Verwaltung von Profilen, Sequenzen und Speicherplätzen (z.B. M1-M10 für DPS5005 oder Timer-Listen für UDP3305 [cite: 303]).+Die ''TableEntity'' ist das Herzstück für komplexe Geräteeigenschaften wie Speicherplätze (M1-M10), Profil-Listen (Sequenzeroder Zell-Übersichten.
  
-==== 2.1 Datenmodell (structures/entities.py) ==== +==== 2.1 Datenstruktur & Schema ==== 
-[cite_start]Erweiterung der Entitäten um einen tabellarischen Typ[cite: 413]: +Eine ''TableEntity'' kapselt nicht nur Daten, sondern auch deren Bedeutung. 
-  * **TableEntity**: +  * **Schema (columns)**: Definition der Spalten-Metadaten. 
-    * [cite_start]''columns'': Liste von Meta-Definitionen (z.B. ''{key: "v", type: "number", unit: "V"}'' [cite: 418]). +    * Jede Spalte definiert: ''key'', ''name'', ''type'' (number/text/toggle/action)''unit'', sowie Constraints (''min'', ''max'', ''step''). 
-    ''value'': Liste von Zeilen-Objekten (z.B. ''[{v: 12.0, i: 1.0}, {v: 5.0, i: 2.0}]'').+  **Daten (value)**Eine Liste von Dictionaries, wobei jedes Dictionary eine Zeile darstellt. 
 +  * **Typen**: Unterscheidung zwischen ''fixed_size'' (z.B. genau 10 Speicherplätze) und ''dynamic_size'' (Zeilen hinzufügbar/löschbar).
  
-==== 2.2 UI-Repräsentation ==== +==== 2.2 Erweiterte Interaktions-Logik ==== 
-  * Dynamische Generierung einer HTML-Tabelle. +  * **Row-Updates**: Das Frontend sendet Koordinaten-Pakete: ''{ "row": r, "col": "key", "val": value }''
-  Jede Zelle erhält eine koordinatenbasierte ID (z.B. ''table-ch1_list-row0-v''). +  * **Atomic Row Actions**: Unterstützung einer Spalte vom Typ ''button''. Dies ermöglicht "Apply"-Buttons pro Zeile, um einen kompletten Parametersatz (z.B. Volt und Ampere eines Presets) gleichzeitig an die Hardware zu senden, um instabile Zustände zu vermeiden. 
-  Änderungen senden ein spezielles Command-Objekt: ''{"row": index, "column": key, "value": new_val}''.+  * **Active Row Tracking**: Ein zusätzliches Attribut ''active_row_index'' markiert die Zeile, die das Gerät aktuell tatsächlich verwendet (z.B. welcher Speicherplatz gerade geladen ist). 
 +  * **Zell-basiertes Muting**: Die Mute-Logik aus Kapitel 1 wird auf Zellebene angewendet, sodass eine Bearbeitung in Zeile 1 nicht die Live-Updates von Zeile 2 blockiert.
  
-===== 3. Gamepad-Steuerung via Pygame ===== +===== 3. Gamepad-Integration (HID-Steuerung===== 
-Integration von Human Interface Devices zur haptischen Steuerung.+Haptische Steuerung via USB-Controller, realisiert durch das ''pygame''-Subsystem.
  
-==== 3.1 Gamepad-Treiber (hardware/system/gamepad.py) ==== +==== 3.1 GamepadManager (hardware/system/gamepad.py) ==== 
-Ein dedizierter Treiber nutzt ''pygame.joystick'' zur Abfrage+Ein neuer Treiber-Typ, der autonom nach Controllern sucht
-  * **Threading**: Da Pygame einen eigenen Event-Loop benötigt, wird dieser in einem Thread gestartet: +  * [cite_start]**Discovery**: Nutzt ''pygame.joystick.get_count()'' und ''get_id()''um Controller dynamisch zu finden, ohne Hardcoding in der Config[cite: 63, 64]
-    <code> +  * [cite_start]**GamepadEntity**: Eine neue Entitätsklasse, die den Zustand (Axes, Buttons, Hats, Triggers) als Snapshot-Objekt im ''value''-Feld hält[cite: 135].
-    def pygame_loop(self): +
-        while self.running: +
-            for event in pygame.event.get()+
-                if event.type == pygame.JOYAXISMOTION: +
-                    asyncio.run_coroutine_threadsafe(self.update_entity(...), self.loop) +
-    </code> +
-  * **Entity-Mapping**: Der Controller wird als ''GamepadEntity'' mit einem Dictionary-Value dargestellt, der alle Achsen und Buttons enthält.+
  
-==== 3.2 Discovery ==== +==== 3.2 Haptisches Feedback & Visualisierung ==== 
-[cite_start]Der Treiber scannt beim Start mittels ''pygame.joystick.get_count()'' alle verfügbaren Controller und legt pro Controller eine Instanz in der ''SystemEngine'' [cite: 81] an.+  [cite_start]**UI-Widgets**: Spezielle Web-Komponenten für Joysticks (Fadenkreuz) und Trigger (Druckempfindliche Balken via ''UIMode.LEVEL'')[cite: 422]
 +  * **Sicherheitskonzept**: Implementierung eines "Deadman-Switch" (Totmannknopf). Steuerbefehle werden nur an andere Geräte weitergeleitet, wenn eine definierte Taste am Gamepad gehalten wird.
  
-===== 4. LogicService: Die Automatisierungs-Brücke ===== +===== 4. LogicService: Die Automation Bridge ===== 
-[cite_start]Ein zentraler Dienst in der ''SystemEngine''[cite: 81], der Events zwischen Geräten vermittelt.+[cite_start]Zentraler asynchroner Dienst in der ''SystemEngine''[cite: 81], der als Vermittler zwischen dem Bus und den Geräte-Kommandos fungiert.
  
 ==== 4.1 Die Rule-Engine ==== ==== 4.1 Die Rule-Engine ====
-[cite_start]Der Dienst abonniert den ''EventBus'' [cite: 85] und vergleicht jedes Sample mit einer Liste von Regeln (''rules.json'')+[cite_start]Der Dienst abonniert den ''EventBus'' [cite: 85, 427] und prozessiert Regeln aus einer ''rules.json''
-  * **Beispiel-Regel (Mapping)**: +  * [cite_start]**Trigger**: Ein Sample von Gerät A (z.B. Gamepad-Achse oder BMS-Temperatur)[cite: 424]
-    * **Trigger**: ''gamepad_0.axis_1'' (Linker Stick Y). +  * **Transformation (Scaling)**: Mathematische Umwandlung von Eingangswerten (z.B. Gamepad-Stick -1.0...+1.0) in Zielwerte (z.B. Netzteil 0.0...32.0 V). 
-    * **Transformation**: Linear Scaling (Input -1.0 bis 1.0 -> Output 0.0 bis 32.0V). +  [cite_start]**Action**: Ausführung von ''engine.execute_command(target_devkeytransformed_val)''[cite: 84, 433].
-    * **Action**: ''engine.execute_command("udp3305_1""ch1_v_set"calculated_value)''.+
  
-==== 4.2 Web-Konfigurator ==== +==== 4.2 Cross-Device Szenarien (Beispiele) ==== 
-Ein universelles Frontend-Modul erlaubt das Erstellen dieser Regeln per Dropdown: +  * **Synchronisation**: Die elektronische Last (Senke) folgt automatisch der Spannung des Netzteils (Quelle), um eine konstante Leistung (CP-Mode) über das Framework zu simulieren. 
-  * WENN [Gerät wählen] [Entität wählen] ÄNDERUNG > X%  +  * **Master-Slave**: Zwei Netzteile werden so gekoppelt, dass Kanal 2 immer exakt dem Wert von Kanal 1 folgt.
-  DANN [Zielgerät wählen] [Zielentität wählen] SETZE WERT [Transformations-Formel].+
  
-===== 5. Erweiterter Entitäten-Katalog (Specs) =====+===== 5. Erweiterter Entitäten-Katalog ===== 
 +[cite_start]Zusätzliche spezialisierte Typen für professionelle Laboranforderungen[cite: 421, 422, 423]:
  
-==== 5.1 LogEntity (Geräte-spezifisch) ==== +^ Typ ^ UI-Repräsentation ^ Funktionalität ^ 
-  * **Zweck**: Ein lokaler Feed für geräteinterne Ereignisse (Fehlercodes, Statuswechsel). +| **LogEntity** | Scrollende Konsole | Lokaler Ereignis-Speicher für gerätespezifische Fehler (z.B. SCPI-Fehlermeldungen). | 
-  * **Visualisierung**: Terminal-Widget in der Geräte-Tab-Ansicht.+| **StatusIndicator** | Virtuelle LED | Farb-Mapping für Zustände (z.B. 0=Off, 1=OK/Grün, 2=Warnung/Gelb, 3=Alarm/Rot-Blinkend). | 
 +**XYGraphEntity** | Kennlinien-Plot | Darstellung von X-Y-Beziehungen (z.B. Batterie-EntladekurveSpannung über Kapazität). | 
 +| **FileEntity** | Upload/Download | Schnittstelle für Firmware-Dateien (z.B. ESPHome .binoder Konfigurations-Exports| 
 +**RangeEntity** | Multi-Slider/Input | Gruppiert logisch zusammengehörige Werte für Sweeps (Start, Stop, Step, Intervall). | 
 +**ScheduleEntity** | Zeitplan-Editor | Verwaltung von Zeitereignissen (z.B. "Schalte Ausgang an Wochentagen um 08:00 Uhr an")|
  
-==== 5.2 StatusIndicatorEntity ==== +===== 6Implementierungs-Leitfaden für KI-Entwicklung ===== 
-  * **Zweck**: Visuelles Feedback ohne Text (virtuelle LED). +  * [cite_start]**Concurrency**: Alle Logik-Operationen müssen asynchron (''async/await''ausgeführt werden, um den Hardware-Poll-Loop nicht zu blockieren[cite: 1, 9]
-  * **Mapping**: Wert 0 = Grau1 = Grün, 2 = Rot blinkend.+  * [cite_start]**Caching**: Die ''SystemEngine'' nutzt ihren ''state_cache'' als "Single Source of Truth" für die Logic-Regeln[cite: 8184]. 
 +  * **Modularität**: Neue Entitäten müssen in ''structures/entities.py'' definiert und in der ''settings.html'' mit einem entsprechenden UI-Generator verknüpft werden.
  
-==== 5.3 XYGraphEntity ==== +===== 7Erweiterte Web-Views (Advanced Visualization) =====
-  * **Zweck**: Darstellung von Kennlinien (z.B. Strom über Spannung beim Batterie-Test). +
-  * [cite_start]**Implementierung**: Nutzt das Waveform-Sample-Format[cite: 425], aber mappt Achse A gegen Achse B statt gegen die Zeit.+
  
-==== 5.4 FileEntity ==== +Um die wachsende Komplexität der Daten (Gamepad, BMS, IMU-Sensoren) beherrschbar zu machenwerden spezialisierte Views implementiert.
-  * **Zweck**: Übertragung von Firmware-Dateien oder Konfigurations-Backups. +
-  * **API**: Endpoint für Multipart-Uploadsder direkt an den Treiber durchreicht.+
  
-===== 6Implementierungshinweise für KI-Programmierung ===== +==== 7.1 XYZ / 3D-Visualisierung (Spatial View) ==== 
-  * [cite_start]**Stabilität**: Alle Treiber müssen ''AbstractDevice'' [cite: 116] [cite_start]korrekt implementiereninsbesondere die Fehlerbehandlung im ''loop()''[cite: 137]. +Diese View nutzt Bibliotheken wie **Three.js** oder **Plotly.js**, um Daten im dreidimensionalen Raum darzustellen. 
-  * [cite_start]**Performance**: Der ''EventBus'' [cite: 85] ist das Nadelöhr; Samples sollten nur bei signifikanten Änderungen gesendet werden+  * [cite_start]**Anwendungsfall A: IMU/Orientierung**: Visualisierung der Fluglage oder Position eines Sensors (basierend auf der ''VectorEntity'' [cite: 419]). [cite_start]Ein 3D-Modell (z.B. ein PCB oder eine Batteriebox) neigt sich in Echtzeit entsprechend der Daten aus dem ''VirtualLaboratory''[cite: 252, 263]. 
-  * [cite_start]**Sicherheit**: Automatisierungsregeln müssen "Safe-Guards" (z.B. maximale Spannungsgrenzenrespektieren, die in der ''TableEntity'' oder ''NumericEntity'' [cite: 418definiert sind.+  * **Anwendungsfall B: Multi-Parameter-Sweeps**: Darstellung von Abhängigkeiten wie "Effizienz über Eingangsspannung und Laststrom". Hierbei entsteht eine 3D-Oberfläche (Surface Plot). 
 +  * **Anwendungsfall C: Raum-Mapping**: Wenn Sensordaten mit Positionsdaten gekoppelt sind (z.B. Temperatur-Mapping einer Oberfläche). 
 + 
 +==== 7.2 Multi-Device Dashboard (Global View) ==== 
 +[cite_start]Die aktuelle UI ist stark auf einzelne Tabs pro Gerät fokussiert[cite: 16]. Die ''Global View'' bricht diese Struktur auf. 
 +  * **Konzept**: Eine frei konfigurierbare Kachel-Ansicht (Grid-Layout), in der Entitäten verschiedener Geräte gemischt werden können. 
 +  * [cite_start]**Beispiel**: Ein "Power-Dashboard", das die Eingangsleistung vom ''UDP3305'' [cite: 303][cite_start], den Zellstatus vom ''JbdBms'' [cite: 145] [cite_start]und die Lastdaten der ''AtorchDL24'' [cite: 211] auf einer einzigen Seite zusammenfasst. 
 + 
 +==== 7.3 Logic-Flow Visualizer (Automation View==== 
 +Da der geplante ''LogicService'' komplex werden kann, ist eine textuelle Regel-Liste oft unübersichtlich. 
 +  * **Konzept**: Eine Node-basierte Darstellung (ähnlich wie Node-RED). 
 +  * [cite_start]**Darstellung**: Blöcke repräsentieren Trigger (z.B. Gamepad [cite: 255][cite_start]), Logik-Gatter und Aktionen (z.B. Netzteil-Kommando [cite: 326])
 +  * [cite_start]**Live-Feedback**: Linien zwischen den Blöcken leuchten kurz auf, wenn ein Event über den ''EventBus'' fließt[cite: 85]
 + 
 +==== 7.4 Session Replay & Analyse (History View) ==== 
 +[cite_start]Basierend auf dem ''SessionManager''
 +  * **Konzept**: Eine Ansicht zum "Zurückspulen" vergangener Messungen
 +  * [cite_start]**Funktion**: Über eine Timeline kann eine aufgezeichnete Session (identifiziert durch die ''session_id'' ) ausgewählt werden. Die UI zeigt dann die historischen Daten so an, als würden sie gerade live passieren. 
 +  * **Vergleichs-Modus**: Zwei Sessions können übereinandergelegt werden (z.B. Entladekurve von Batterie A vs. Batterie B). 
 + 
 +==== 7.5 Synoptic View (Prozessgrafik) ==== 
 +  * **Konzept**: Ein statisches Hintergrundbild (z.B. ein Foto deines Versuchsaufbaus oder ein Schaltplan), auf dem die Live-Werte der Entitäten an den physikalisch korrekten Stellen eingeblendet werden. 
 +  * **Nutzen**: Extrem intuitive Überwachung von komplexen Verdrahtungen. 
 + 
 +==== Sonstiges ==== 
 +Was ich mir sonst noch vorstellen könnte: 
 +  * Virtuelle Instrumente (Skins): Dass du für das UDP3305 eine View baust, die exakt so aussieht wie die Frontplatte des echten Geräts. Das macht die Bedienung im Web viel natürlicher. 
 +  * Webcam-Integration mit Overlay: Wenn dein Pi eine Kamera hat, könntest du den Videostream anzeigen und die Messwerte (z.B. Temperatur) direkt über das Bild legen (ähnlich wie Augmented Reality). 
 +  * Alarm-Management: Eine View, die nur dann aufpoppt, wenn Grenzwerte überschritten werden (z.B. BMS-Alarm ). 
 + 
 +===== 7.6 Webcam & Augmented Reality (AR) Overlay ===== 
 + 
 +Diese View kombiniert visuelles Feedback der Hardware mit den Live-Daten des EventBus. 
 + 
 +==== Architektur des Datenflusses ==== 
 +  * **Video-Pfad**: Webcam -> OpenCV -> FastAPI StreamingResponse (MJPEG) -> Browser <img>
 +  * **Daten-Pfad**: Hardware -> EventBus -> WebSocket -> Browser Canvas. 
 +  * **Vorteil**: Die hohe Last des Videos beeinträchtigt nicht die Echtzeit-Messdaten auf dem Bus. 
 + 
 +==== Features ==== 
 +  * **AR-Overlay**: Positionierung von Messwerten direkt über dem Videobild (z.B. Temperaturanzeige direkt auf dem Kühlkörper im Bild). 
 +  * **Visual CV**: Optionale Bilderkennung im Backend, die Ergebnisse (z.B. "Gerät eingeschaltet") als reguläre Samples auf den Bus publiziert. 
 + 
 +==== Implementierung (Code-Skizze) ==== 
 +  * **Backend**: Neuer API-Endpunkt unter ''/api/video/stream''
 +  * **Frontend**: Dynamisches Canvas-Mapping. Koordinaten für Overlays werden in der ''config.yaml'' des Geräts gespeichert. 
 + 
 +==== 7.7 Visual Event Trigger (Virtual Sensor) ==== 
 +Zusätzlich zum Videostream kann das System Bildbereiche (ROI) analysieren, um "virtuelle Sensoren" zu generieren. 
 + 
 +  * **Funktion**: Überwachung von analogen Anzeigen oder LEDs, die keine Datenschnittstelle besitzen. 
 +  * **Verarbeitung**:  
 +    1. ROI Definition via Koordinaten. 
 +    2. HSV-Farbraumfilterung zur Detektion von Statusfarben. 
 +    3. State-Machine zur Vermeidung von Bus-Spam (nur Änderungen werden publiziert). 
 +  * **Anwendung**: "BMS Alarm LED" -> EventBus -> "PSU OFF"
 + 
 +==== 7.8 Optical Character Recognition (OCR) Sensor ==== 
 +Verwandelt visuelle Anzeigen in digitale Datenströme. 
 + 
 +  * **Technologie**: Integration von ''Tesseract'' oder ''SSOCR'' in den Webcam-Treiber. 
 +  * **Datenfluss**: 
 +    1. Extraktion der Anzeige via ROI. 
 +    2. Bildvorbehandlung (Grayscale, Thresholding, Morphologie). 
 +    3. Konvertierung String -> Float/Int. 
 +    4. Publikation als ''NumericSample'' oder ''TextSample'' auf dem EventBus. 
 +  * **Anwendung**: Digitalisierung von Legacy-Hardware ohne Schnittstellen (DMMs, Waagen, analoge Anzeigen). 
 +===== 8. Zusammenfassung der Datenfluss-Architektur ===== 
 + 
 +Der Datenfluss im erweiterten System folgt nun diesem Muster: 
 +  - [cite_start]**Hardware/Input** (z.B. Owon HDS [cite: 270[cite_start]oder Gamepad) -> **Bus**[cite: 85]. 
 +  - [cite_start]**LogicService** (Abonniert Bus) -> Berechnet Transformation -> **Engine.execute_command**[cite: 84]. 
 +  - [cite_start]**Web-Views** (Abonnieren Bus via WebSocket [cite: 427]) -> Filtern nach Focus-Lock -> **Visualisierung** (3D, Table, Graph).
projekte/ionpy/ideen.1770968825.txt.gz · Last modified: by dominik

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki