# VersaPad Viewer Ein eigenständiges Tool für das [VersaPad](https://git.jappel.io/jappel/VersaMCU)-Makropad (4×5-Button-Grid + 4 Encoder, SAMD21-Firmware von jappel). Zeigt die aktuelle Belegung an, kann sie live mit dem Board synchronisieren und komplett neu programmieren — als Ergänzung zur offiziellen [VersaGUI](https://git.jappel.io/jappel/VersaGUI) (C#/.NET), nicht als Ersatz. Aktive Weiterentwicklung. Lesemodus, Live-Sync, Programmiermodus (inkl. Board-Schreibzugriff) und der MCP-Server sind funktionsfähig und gegen ein echtes Board getestet (Read-Modify-Write ist byte-identisch zum Original, inklusive CRC). Nicht vorhanden: automatisierte Tests (Verifikation läuft manuell gegen ein angeschlossenes Board), eine vorgefertigte `.exe` zum Download (siehe unten, warum), und Mehrbenutzer-/Netzwerkbetrieb. Die eigene Config-Datei (`versapad_config_all.json`) liegt automatisch neben der Installation (siehe „Aufbau" unten) und wird bei Bedarf automatisch neu angelegt — kein manuelles Pfad-Anpassen mehr nötig. Nur die *optionale* Lese-Interop mit den JSON-Exports der offiziellen VersaGUI (`versapad_data.CONFIG_PATHS`) ist noch für eine bestimmte Windows-Maschine hartkodiert (OneDrive-Desktop) — für einen anderen Rechner dort anpassen, falls gewünscht. ## Features - **Steuermatrix-Anzeige** — 4×5-Button-Grid + 4 Encoder, farbige LED-Vorschau, lesbare Beschriftung (z.B. "Strg+S" statt Rohwerten) - **Zwei Anzeige-Wege:** Browser (`server.py`, `localhost:8765`) oder natives Desktop-Fenster (`desktop_viewer.py`, Tkinter) - **Live-Sync** — pollt per Serial, welches Profil gerade am Board aktiv ist, und schaltet die Ansicht automatisch mit - **Programmiermodus** — Zellen anklicken und bearbeiten (Taste, Medientaste, Makro, Profilwechsel, LED-Farbe/Animation), direkt aufs Board schreiben oder als Datei speichern - **Makro-Editor** — bis zu 8 Schritte pro Slot, liest/schreibt die echte Makro-Tabelle vom Board - **MCP-Server** — lässt eine KI (Claude o.ä.) die Belegung direkt per Tool-Aufruf ändern, ohne Klicks in der GUI (siehe unten) - **Tray-Icon** — minimiert/schließt ins Tray statt in die Taskleiste, wie die offizielle VersaGUI ## Voraussetzungen - Python 3.11 oder neuer - Pakete: `pyserial` (Board-Kommunikation), `pystray` + `pillow` (Tray-Icon/Desktop-App), optional `mcp` (nur für den MCP-Server) ```bash pip install pyserial pystray pillow mcp ``` Für den Browser-Modus (`server.py`) reicht die Python-Standardbibliothek — keine zusätzlichen Pakete nötig. ## Starten **Aus dem Quellcode:** ```bash py server.py # Browser-Ansicht: http://127.0.0.1:8765 py desktop_viewer.py # natives Fenster (Konsole sichtbar, zum Debuggen) pyw desktop_viewer.py # natives Fenster ohne Konsolenfenster ``` **Als eigenständige `.exe` (Windows):** Es liegt keine fertige `.exe` im Repo (Build-Artefakte sind bewusst nicht eingecheckt — sie sind groß und pro Maschine/Python-Version unterschiedlich). Selbst bauen: ```powershell .\build_and_deploy.ps1 ``` Das Skript baut mit PyInstaller (`--onedir --windowed`, eigenes Icon) und kopiert das Ergebnis nach `%LOCALAPPDATA%\VersaPadViewer\VersaPadViewer.exe`. **Wichtig:** Sowohl Bauen als auch Ausführen müssen auf einem lokalen Laufwerk passieren — von einem Netzlaufwerk (SMB-Share) aus scheitert PyInstaller beim Bauen (Pfadlängen-Problem mit Tcl/Tk-Zeitzonendaten) und die fertige `.exe` startet zur Laufzeit gar nicht erst (Windows blockiert das Nachladen der Bundle-DLLs von einem Netzwerkpfad, ohne jede Fehlermeldung). `build_and_deploy.ps1` kopiert den Quellcode deshalb automatisch zuerst nach `%TEMP%` und baut nur dort. Voraussetzung: `pip install pyinstaller` zusätzlich zu den obigen Paketen. ## Aufbau | Datei | Zweck | |---|---| | `versapad_data.py` | Decoding für die Anzeige: JSON laden, HID-Keycodes/Consumer-IDs/Modifier → lesbarer Text | | `versapad_protocol.py` | Binäres NVM-Layout des Boards (740B Config + 512B Makros), CRC16 — pack/unpack | | `versapad_serial.py` | Serial-Client: liest/schreibt Config + Makros per 8-Byte-Paket-Protokoll | | `versapad_combined.py` | Ein-Datei-Format für alle 3 Profile + Makros + lokale Profilnamen | | `server.py` | Browser-Frontend (nur lesend) | | `desktop_viewer.py` | Tkinter-Frontend (lesend, Live-Sync, Programmiermodus, Tray) | | `action_dialog.py` | Bearbeiten-Dialoge für den Programmiermodus | | `versapad_mcp_server.py` | MCP-Server für KI-Tool-Aufrufe | Das Binärformat (`versapad_protocol.py`) ist 1:1 aus den VersaMCU-Firmware-Quellen übernommen und gegen ein echtes Board validiert (Read → unpack → pack ist bytegenau identisch zum Original, inklusive CRC). Die eigene Config-Datei (`versapad_config_all.json` — alle 3 Profile + Makros + lokale Profilnamen, siehe `versapad_combined.py`) liegt neben der Installation: bei der gebauten `.exe` im selben Ordner, beim Start aus dem Quellcode im Projektordner (`versapad_data.app_dir()`). Fehlt sie (z.B. frische Installation), wird sie automatisch angelegt — per Serial vom Board, falls eins angeschlossen ist, sonst als leere Default-Config. Profilnamen (`profile_names`) stehen direkt in dieser Datei und lassen sich per Doppelklick auf einen Tab (in jedem Modus — Nur-Lesen, Live-Sync oder Programmiermodus) oder `rename_profile()` (MCP) ändern. Die klassischen `versapad_config1/2/3.json` sind kein von diesem Tool geschriebenes Format, sondern optionale Lese-Interop mit einem JSON-Export der offiziellen VersaGUI (C#/.NET) — Pfad aktuell hartkodiert auf den OneDrive-Desktop einer bestimmten Windows-Maschine, siehe `CONFIG_PATHS` in `versapad_data.py`. ## MCP-Server `versapad_mcp_server.py` macht die Config per Tool-Aufruf statt Hand-JSON programmierbar — nutzbar von jeder MCP-fähigen KI-Anwendung (Claude Code, Claude Desktop, andere). In der MCP-Server-Liste der jeweiligen Anwendung eintragen: Kommando `python`/`py`, Argument der Pfad zu `versapad_mcp_server.py`. Werkzeuge (Auszug): `list_profiles`, `get_profile`, `get_macro`, `get_board_status` (lesen) · `set_button_key`/`_consumer`/`_macro`/ `_profile_switch`/`_none`/`_led`, dieselben `set_encoder_*`, `set_macro`, `rename_profile` (bearbeiten) · `save_local`/`load_local` (Datei), `load_from_board`/`write_to_board` (Board). `set_*`-Aufrufe ändern nur einen In-Memory-Zustand — erst `save_local()` oder `write_to_board()` macht die Änderung dauerhaft. Volle Liste mit Details: Info-Button (ⓘ) oben rechts im Fenster, oder direkt in `versapad_mcp_server.py`. ## Bekannte Einschränkungen - Der COM-Port ist exklusiv — Live-Sync/Programmiermodus können nicht gleichzeitig mit der offiziellen VersaGUI laufen (die läuft dauerhaft als Tray-App weiter, auch wenn nur ihr Konfigurationsfenster geschlossen wird — für Parallelbetrieb muss sie über ihr Tray-Menü beendet werden) - HID-Tasten-Auswahl im Programmiermodus ist ein Dropdown, kein Tastendruck-Capture (bewusst, um keinen WinAPI-Hook zu brauchen) - Zeichentasten-Labels zeigen eine US-Layout-Näherung, nicht das tatsächlich aktive Tastatur-Layout - Unsignierte `.exe` — kann von Antivirus/Smart App Control blockiert werden; `--onedir` (statt `--onefile`) verringert das Risiko, verhindert es aber nicht ## Weiterentwicklung Tiefere technische Notizen (Protokoll-Details, bekannte Stolpersteine beim Bauen, Design-Entscheidungen) stehen in [`AGENTS.md`](AGENTS.md). ## Lizenz / Herkunft Eigenständiges Begleit-Tool, kein Teil der offiziellen VersaGUI/VersaMCU-Repos.