Automatisierte Screenshot Aufnahme per [SCREENSHOT] datei implementiert

This commit is contained in:
2026-08-26 01:22:13 +02:00
parent 36923e1646
commit ef335f2d9e
16 changed files with 365 additions and 52 deletions

144
README.md
View File

@@ -8,21 +8,25 @@ Ein moderner UART-Monitor für Linux mit Qt6-Oberfläche. Gebaut als vollwertige
| Feature | Beschreibung |
|---|---|
| **Unbegrenzter Verlauf** | Kein Zeilenlimit keine Daten gehen verloren, egal wie viel der Pi sendet |
| **Serieller UND Netzwerk-Input** | Verbindung wahlweise über einen echten/virtuellen seriellen Port **oder** eine reine TCP-Verbindung praktisch für Emulatoren wie FS-UAE, deren Debug-UART per `socat` auf einen TCP-Port gelegt wird |
| **PTY-Erkennung** | Pseudo-Terminals unter `/dev/pts/` (z.B. von `qemu -serial pty`) werden im Port-Dropdown automatisch mitgelistet |
| **Unbegrenzter Verlauf** | Kein Zeilenlimit keine Daten gehen verloren, egal wie viel gesendet wird |
| **Timestamps** | Jede Zeile im Raw-View bekommt automatisch einen `hh:mm:ss.zzz`-Timestamp |
| **Auto-Scroll** | Standardmäßig aktiv springt automatisch ans Ende neuer Ausgaben |
| **H + V Scrolling** | Kein Zeilenumbruch, voller horizontaler Scrollbalken |
| **Live-Logging** | Alle empfangenen Zeilen werden mit Timestamp in eine Datei geschrieben |
| **Tag-Monitor** | Zeilen mit `[TAG]` werden in eigenen Panels angezeigt und aktualisiert |
| **Tag-Monitor mit Verlauf** | Zeilen mit `[TAG]` werden in eigenen Panels angezeigt; jedes Panel hat einen „Aktuell"-Tab (Live-Stand) und einen „Verlauf"-Tab (alle je empfangenen Werte, timestamped) |
| **Listen-Werte** | `;`-getrennte Werte in einem Tag werden als mehrzeilige Liste dargestellt |
| **Tag-Filter** | Tags können aus dem Raw-View ausgeblendet werden wird dauerhaft gespeichert |
| **Tag-Filter** | Tags können aus dem Raw-View ausgeblendet werden wird dauerhaft gespeichert; auch Tag-Namen mit Bindestrich (z.B. `I2C-BUS`) werden korrekt erkannt |
| **Tabellenansicht** | CSV-formatierte UART-Zeilen werden in einer Tabelle dargestellt |
| **Suche** | Inkrementelle Volltextsuche im Raw-View |
| **Auto-Reconnect** | Bei Verbindungsabbruch wird automatisch neu verbunden (Intervall einstellbar) |
| **Suche mit Navigation** | Inkrementelle Volltextsuche im Raw-View mit Weiter/Zurück (Buttons, Enter, F3/Shift+F3) und Wrap-Around |
| **Auto-Reconnect** | Bei Verbindungsabbruch wird automatisch neu verbunden (Intervall einstellbar) funktioniert für seriell und TCP gleichermaßen |
| **ANSI Clear-Screen** | `\033[2J\033[H` aus der Firmware leert Raw-View, Tabelle, Tag-Monitor und Video-Vorschau gleichzeitig |
| **Copy-Buttons** | Raw-View und jedes Tag-Panel haben einen „📋 Copy"-Button |
| **Copy-Buttons** | Raw-View und jedes Tag-Panel (Aktuell- oder Verlauf-Tab) haben einen „📋 Copy"-Button |
| **V4L2 Live Video** | HDMI-Grabber direkt eingebunden Live-Vorschau unter dem Tag-Monitor |
| **Video-Aufzeichnung (MP4)** | Live-Vorschau per Knopfdruck als MP4 aufzeichnen (H.264, via `ffmpeg`) |
| **Screenshot** | Aktuellen Frame des HDMI-Grabbers als PNG/JPG speichern |
| **Automatischer Screenshot-Trigger** | `[SCREENSHOT] dateiname` als Steuertag: der Frame wird exakt im Moment des Empfangs gespeichert ideal um z.B. einen kurz angezeigten Memory-Dump zuverlässig zu erwischen |
| **Format-Referenz** | Eingebauter Guide (mit Kopieren-Button) für KI-kompatible UART-Formatierung |
| **Fensterlayout** | Fenstergröße, Position, Splitter-Positionen und Tag-Filter werden beim Beenden gespeichert |
@@ -32,16 +36,18 @@ Ein moderner UART-Monitor für Linux mit Qt6-Oberfläche. Gebaut als vollwertige
```bash
# Arch (empfohlen)
sudo pacman -S cmake qt6-base qt6-serialport
sudo pacman -S cmake qt6-base qt6-serialport ffmpeg
# Ubuntu / Debian
sudo apt install cmake qt6-base-dev qt6-serialport-dev libqt6serialport6-dev
sudo apt install cmake qt6-base-dev qt6-serialport-dev libqt6serialport6-dev ffmpeg
# Fedora
sudo dnf install cmake qt6-qtbase-devel qt6-qtserialport-devel
sudo dnf install cmake qt6-qtbase-devel qt6-qtserialport-devel ffmpeg
```
V4L2 benötigt keine zusätzliche Library `linux/videodev2.h` ist Teil der Standard-Kernel-Header.
V4L2 benötigt keine zusätzliche Library `linux/videodev2.h` ist Teil der Standard-Kernel-Header. Das TCP-Netzwerk-Modul (`Qt6::Network`) ist üblicherweise Teil des `qt6-base`-Pakets und braucht keine separate Installation.
`ffmpeg` ist **nur** für die Video-Aufzeichnung (MP4) nötig ohne installiertes `ffmpeg` funktioniert der Rest von UARTScope normal, nur der „⏺ Record"-Button zeigt dann eine Fehlermeldung.
---
@@ -62,6 +68,69 @@ sudo cmake --install build
---
## Verbindung: Seriell oder Netzwerk (TCP)
Im Connect-Dialog gibt es zwei Tabs:
### Seriell
Wie gewohnt: Port aus der Liste wählen (echte Geräte **und** Pseudo-Terminals unter `/dev/pts/` werden angezeigt), Baudrate/Parität/Stopbits/Flow Control einstellen.
**Virtuelle serielle Geräte (z.B. QEMU):**
```bash
qemu-system-xxx -serial pty ...
# QEMU gibt im Log den zugewiesenen Pfad aus, z.B.:
# char device redirected to /dev/pts/4
```
Den ausgegebenen Pfad im Seriell-Tab auswählen (ggf. vorher ↻ zum Neuladen der Liste drücken). Baudrate & Co. werden von virtuellen PTYs ignoriert das ist unschädlich.
### Netzwerk (TCP)
Host/IP und Port angeben statt eines seriellen Ports. Gedacht für Firmware/Emulatoren, die ihre Debug-UART über TCP senden statt über ein echtes serielles Gerät zum Beispiel FS-UAE, dessen serielle Schnittstelle per `socat` auf einen TCP-Port gelegt wird:
```bash
# Beispiel: FS-UAEs serielle Ausgabe per socat auf TCP-Port 1234 legen
socat /tmp/fs-uae-serial TCP-LISTEN:1234,reuseaddr,fork
```
Danach im Netzwerk-Tab `localhost` und Port `1234` eintragen und verbinden. Auto-Reconnect funktioniert identisch zum seriellen Modus bricht die TCP-Verbindung ab, wird automatisch neu verbunden.
---
## Video-Aufzeichnung (MP4)
Die Live-Vorschau im Video-Widget lässt sich per „⏺ Record"-Button als MP4-Datei aufzeichnen. Dazu wird intern ein `ffmpeg`-Prozess gestartet, dem die rohen Frames als BGRA über eine Pipe zugeführt werden; `ffmpeg` encodiert sie zu H.264/MP4.
- **Voraussetzung:** `ffmpeg` muss installiert und im `PATH` sein (siehe [Voraussetzungen](#voraussetzungen))
- Die Aufzeichnung läuft unabhängig vom Freeze-Status weiter Freeze pausiert nur die Vorschau, nicht die Aufnahme
- Timestamps basieren auf der Systemuhr (`-use_wallclock_as_timestamps`), damit die Aufnahme auch bei schwankender Framerate des Grabbers die reale Dauer korrekt wiedergibt
- Ein Auflösungswechsel während der Aufnahme, ein Stopp der Capture oder ein Fehler beenden die Aufzeichnung automatisch sauber
---
## Automatischer Screenshot-Trigger
Manuelles Klicken auf den Screenshot-Button trifft bei schnellen Hardware-Ereignissen (z.B. einem kurz angezeigten Memory-Dump) selten genau den richtigen Moment menschliche Reaktionszeit liegt bei mehreren hundert Millisekunden, in der Hardware-Welt passieren in dieser Zeit unzählige Instruktionen. Dafür gibt es den Steuertag `[SCREENSHOT]`:
```c
uart_printf("[SCREENSHOT] memdump_%lu.png\n", HAL_GetTick());
```
Sobald diese Zeile empfangen wird, speichert UARTScope **sofort** den Frame, der zu diesem Zeitpunkt im V4L2-Vorschaupuffer liegt kein Dialog, keine Nutzerinteraktion nötig. Die Verzögerung besteht nur noch aus UART-Übertragungszeit und einem Event-Loop-Tick (typischerweise einstellige Millisekunden), statt aus menschlicher Reaktionszeit.
**Einrichtung:**
1. In der Toolbar auf „Screenshot folder…" klicken und den Zielordner wählen
2. Die Einstellung wird sofort gespeichert und bei jedem Programmstart wiederhergestellt
**Verhalten:**
- Ohne konfigurierten Ordner wird der Trigger zwar erkannt (erscheint im Tag-Monitor und Raw-View), aber es wird keine Datei geschrieben das Ergebnis jedes Trigger-Versuchs (Erfolg oder Fehler, z.B. „kein Ordner konfiguriert" oder „noch kein Frame verfügbar") erscheint kurz in der Statusleiste **und** dauerhaft als `[UARTSCOPE] ...`-Zeile im Raw-View, direkt neben der eigentlichen `[SCREENSHOT]`-Zeile so geht eine Fehlermeldung nie unbemerkt unter
- `<dateiname>` kann die Endung weglassen (Standard: `.png`); eventuelle Pfadanteile in der Firmware-Angabe werden ignoriert die Datei landet immer direkt im konfigurierten Ordner (kein Path-Traversal möglich)
- Wird derselbe Dateiname mehrfach gesendet (z.B. immer `dump.png`), wird nichts überschrieben UARTScope hängt automatisch `_1`, `_2`, … an
- Die Zeile erscheint zusätzlich ganz normal im Tag-Monitor unter `[SCREENSHOT]` inklusive „Verlauf"-Tab, der eine timestamped Liste aller Trigger-Ereignisse **und** deren Ergebnis zeigt: zuerst der angeforderte Dateiname, direkt danach das Resultat („Screenshot saved: /pfad/..." oder eine Fehlermeldung) beides chronologisch im selben Panel
- Funktioniert unabhängig vom Freeze-Status der Vorschau (wie der manuelle Screenshot-Button auch)
**Falls kein Bild erscheint:** die häufigsten zwei Ursachen sind (1) der Screenshot-Ordner wurde noch nicht gesetzt, oder (2) die V4L2-Vorschau läuft nicht (▶ Start im Video-Widget noch nicht geklickt, es gibt also noch keinen Frame zum Speichern). In beiden Fällen steht die genaue Ursache als `[UARTSCOPE] ...`-Zeile im Raw-View.
---
## Berechtigungen
```bash
@@ -84,9 +153,11 @@ v4l2-ctl -d /dev/video0 --list-formats-ext # unterstützte Formate & Auflösung
## UART-Ausgabe formatieren
Alles Folgende gilt unabhängig davon, ob die Verbindung über einen seriellen Port oder über TCP läuft (siehe Abschnitt „Verbindung: Seriell oder Netzwerk (TCP)" weiter oben) UARTScope interpretiert den empfangenen Text in beiden Fällen identisch.
### Raw-View (immer aktiv)
Jede UART-Zeile erscheint im Raw-View mit Timestamp. Keine besondere Formatierung nötig.
Jede Zeile erscheint im Raw-View mit Timestamp. Keine besondere Formatierung nötig.
**Screen leeren** von der Firmware aus Raw-View, Tabelle, Tag-Monitor und Video-Vorschau gleichzeitig leeren:
```c
@@ -99,10 +170,16 @@ Zeilen mit `[TAGNAME]` werden im Tag-Monitor-Panel angezeigt **und** im Raw-View
**Format:** `[TAGNAME] key1=value1 key2=value2 ...`
- Tag-Name: Buchstaben, Ziffern, Underscore z.B. `WDG`, `VIDEO`, `KICKSTART`
- Tag-Name: Buchstaben, Ziffern, Underscore **und Bindestrich** z.B. `WDG`, `VIDEO`, `KICKSTART`, `I2C-BUS`
- Key=Value-Paare: Leerzeichen-getrennt, Werte ohne Leerzeichen
- Ohne Key=Value-Paare wird der rohe String angezeigt
Jedes Tag-Panel hat zwei Tabs:
- **Aktuell** der letzte empfangene Stand, aktualisiert sich in-place (wie bisher)
- **Verlauf** jeder je empfangene Wert dieses Tags, chronologisch mit Timestamp, mit eigenem „Verlauf leeren"-Button (löscht nur die Historie, das Panel bleibt bestehen)
Der Copy-Button kopiert je nach aktivem Tab entweder den aktuellen Stand oder den kompletten Verlauf.
**Listen-Werte:** Ein Wert mit `;`-getrennten Einträgen wird als mehrzeilige Liste unter dem Key dargestellt:
```c
@@ -143,6 +220,14 @@ Optionale Header-Zeile mit `#`, dann CSV-Datenzeilen:
Delimiter per Dropdown umschaltbar: `,` `;` `\t` `|` `Space`
### Suche im Raw-View
Suchbegriff eingeben der erste Treffer wird automatisch markiert. Weitere Treffer:
- **▼** / `Enter` / `F3` → nächster Treffer
- **▲** / `Shift+F3` → vorheriger Treffer
- Ist kein weiterer Treffer in Suchrichtung vorhanden, springt die Suche automatisch an den Anfang (bzw. bei Rückwärtssuche ans Ende) und macht dort weiter (Wrap-Around)
---
## Tag-Filter
@@ -159,6 +244,7 @@ Beim Beenden werden folgende Einstellungen automatisch gespeichert und beim näc
- Splitter-Positionen (Haupt-Splitter und Tag/Video-Splitter)
- Auto-Reconnect ein/aus und Intervall
- Tag-Filter (ausgeblendete Tags)
- Screenshot-Ordner für den `[SCREENSHOT]`-Steuertag
Gespeichert unter `~/.config/ChicaDev/UARTScope.conf` (via `QSettings`).
@@ -174,15 +260,15 @@ uartscope/
├── UartscopeLogo.png
├── uartscope.desktop.in
├── include/
│ ├── mainwindow.h ← Hauptfenster, koordiniert alle Komponenten
│ ├── serialworker.h ← UART-Empfang im eigenen QThread, Auto-Reconnect, ANSI-Erkennung
│ ├── rawview.h ← Unbegrenzter Log mit Timestamps, Suche, Copy
│ ├── mainwindow.h ← Hauptfenster, koordiniert alle Komponenten, Screenshot-Ordner-Einstellung
│ ├── serialworker.h ← Empfang im eigenen QThread (seriell ODER TCP), Auto-Reconnect, ANSI-Erkennung, [SCREENSHOT]-Steuertag
│ ├── rawview.h ← Unbegrenzter Log mit Timestamps, Suche (Weiter/Zurück, Wrap-Around), Copy
│ ├── tableview.h ← CSV-Parser → QTableWidget
│ ├── tagwidget.h ← Container für Tag-Panels
│ ├── tagpanel.h ← Ein Panel pro [TAG], Key=Value-Tabelle mit Listen-Support, Copy
│ ├── connectdialog.h ← Port-Konfiguration (Port, Baud, Log-Datei)
│ ├── tagpanel.h ← Ein Panel pro [TAG]: Aktuell-Tab + Verlauf-Tab, Listen-Support, Copy
│ ├── connectdialog.h ← Seriell- und Netzwerk(TCP)-Konfiguration, PTY-Erkennung, Log-Datei
│ ├── v4l2worker.h ← V4L2-Capture in std::thread, MJPEG/YUYV/NV12
│ └── videowidget.h ← Live-Vorschau, Freeze, Screenshot
│ └── videowidget.h ← Live-Vorschau, Freeze, Screenshot (manuell + automatisch via Tag), MP4-Aufzeichnung (ffmpeg)
└── src/
├── main.cpp
├── mainwindow.cpp
@@ -205,3 +291,25 @@ uartscope/
- **Hex-View**: rohe Bytes als Hex-Dump anzeigen
- **Session-Replay**: gespeicherte Log-Dateien abspielen
- **Regex-Filter**: Zeilen im Raw-View per regulärem Ausdruck ein-/ausblenden
---
## Changelog
**1.2.0**
- Automatischer Screenshot-Trigger via `[SCREENSHOT] dateiname`-Steuertag speichert den Video-Frame exakt im Moment des Empfangs (z.B. für Memory-Dumps)
- Neue Toolbar-Option „Screenshot folder…" zur Konfiguration des Zielordners
- Format-Referenz-Dialog um Dokumentation des neuen Steuertags ergänzt
- Erfolg/Fehler eines Screenshot-Triggers wird zusätzlich zur Statusleiste dauerhaft als Zeile im Raw-View **und** direkt im `[SCREENSHOT]`-Tag-Panel selbst (Aktuell + Verlauf) protokolliert
**1.1.0**
- Netzwerk-Input (TCP) als Alternative zum seriellen Port, inkl. Auto-Reconnect
- PTY-Erkennung (`/dev/pts/`) im Seriell-Tab, z.B. für QEMU
- Video-Aufzeichnung als MP4 (via `ffmpeg`)
- Tag-Panels: zweiter „Verlauf"-Tab mit vollständiger, timestamped Historie
- Suche im Raw-View: Weiter/Zurück-Navigation mit Wrap-Around
- Tag-Namen mit Bindestrich werden jetzt korrekt erkannt und gefiltert
- Bugfix: letzte Zeile ging bei einem ausbleibenden Folge-Byte-Strom manchmal verloren (Idle-Flush-Timer)
**1.0.0**
- Erste Veröffentlichung