No description
Find a file
Julian Appel 189ec01e68 Merge branch 'main' into dev/jappel
Reconciles two independent lines of work: main cherry-picked and then
extended dev/jappel's build-script/config-portability/rename-tab/
COM-port fixes, additionally fixing a config-loss bug (rebuild wiped
the config when it lived in the install dir -- moved to roaming
%APPDATA% instead) and adding free-text notes per action plus a
frameless resizable window. dev/jappel keeps its .mcp.json registration
and docs/ reference tree, which main deliberately left out.

Conflict resolutions favored main's versions where the two sides solved
the same problem (config location, build deploy target, COM-port
release, tab rename) since main's fixes were validated against a real
rebuild-wipes-config incident. docs/architecture.md and
docs/data-model.md updated to describe the resulting %APPDATA% config
path and the note field.
2026-08-15 18:16:00 +02:00
docs Merge branch 'main' into dev/jappel 2026-08-15 18:16:00 +02:00
.gitignore Move config storage next to the install and auto-create it if missing 2026-08-14 23:17:11 +02:00
.mcp.json Register versapad MCP server via project-scoped .mcp.json 2026-08-14 23:18:08 +02:00
action_dialog.py Add free-text notes per button/encoder action 2026-08-15 11:15:36 +02:00
AGENTS.md Merge branch 'main' into dev/jappel 2026-08-15 18:16:00 +02:00
build_and_deploy.ps1 Keep user config out of the install dir; frameless window with working resize 2026-08-15 12:12:33 +02:00
desktop_viewer.py Keep user config out of the install dir; frameless window with working resize 2026-08-15 12:12:33 +02:00
icon.ico Add custom icon and tray-minimize behavior (like VersaGUI's TrayApp) 2026-08-05 08:30:50 +02:00
icon.png Add custom icon and tray-minimize behavior (like VersaGUI's TrayApp) 2026-08-05 08:30:50 +02:00
README.md Merge branch 'main' into dev/jappel 2026-08-15 18:16:00 +02:00
requirements.txt Make build_and_deploy.ps1 self-installing and fail loudly 2026-08-14 23:51:42 +02:00
run_browser.bat Initial commit: VersaPad viewer + programming mode 2026-08-04 20:03:49 +02:00
run_desktop.bat Initial commit: VersaPad viewer + programming mode 2026-08-04 20:03:49 +02:00
server.py Add free-text notes per button/encoder action 2026-08-15 11:15:36 +02:00
versapad_combined.py Keep user config out of the install dir; frameless window with working resize 2026-08-15 12:12:33 +02:00
versapad_data.py Merge branch 'main' into dev/jappel 2026-08-15 18:16:00 +02:00
versapad_mcp_server.py Add free-text notes per button/encoder action 2026-08-15 11:15:36 +02:00
versapad_protocol.py Initial commit: VersaPad viewer + programming mode 2026-08-04 20:03:49 +02:00
versapad_serial.py Use lightweight READ_STATUS instead of full CONFIG_READ for profile polling 2026-08-07 15:37:40 +02:00
VersaPadViewer.spec Add custom icon and tray-minimize behavior (like VersaGUI's TrayApp) 2026-08-05 08:30:50 +02:00

VersaPad Viewer

Ein eigenständiges Tool für das VersaPad-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 (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 unter %APPDATA%\VersaPadViewer\ (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
  • Notizen — freier Text pro Button/Encoder-Aktion, was sie tatsächlich tut (z.B. "Speichern in Fusion 360"), zusätzlich zur automatischen Beschriftung ("Strg+S"). Rein lokal wie Profilnamen, geht nie aufs Board, bleibt beim Tastenwechsel und beim "Vom Board laden" erhalten
  • 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
  • Randloses Fenster — ohne Windows-Titelleiste, dafür kompakter Kopf (Modus-Checkboxen direkt neben dem Titel). Verschieben durch Ziehen an der Kopfzeile, Größe ändern am Anfasser unten rechts, / legen ins Tray. Einen Taskleisten-Eintrag gibt es dadurch nicht — das Fenster kommt über das Tray-Icon zurück.

Voraussetzungen

  • Python 3.11 oder neuer
  • Alle Pakete stehen in requirements.txt (pyserial fürs Board, pystray + pillow fürs Tray-Icon/Desktop-Fenster, mcp für den MCP-Server, pyinstaller fürs .exe-Bauen):
pip install -r requirements.txt

Für den Browser-Modus (server.py) reicht die Python-Standardbibliothek — keine zusätzlichen Pakete nötig. build_and_deploy.ps1 installiert requirements.txt beim Bauen automatisch selbst — ein manuelles pip install vorher ist dafür nicht nötig.

Starten

Aus dem Quellcode:

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:

.\build_and_deploy.ps1

Das Skript installiert/aktualisiert selbst alle nötigen Pakete aus requirements.txt (kein manuelles pip install vorher nötig), baut dann mit PyInstaller (--onedir --windowed, eigenes Icon) und kopiert das Ergebnis nach %LOCALAPPDATA%\VersaPadViewer\VersaPadViewer.exe. Bricht ein Schritt ab (fehlendes Python, PyInstaller-Fehler, ...), zeigt das Skript eine klare Fehlermeldung und wartet auf einen Tastendruck, statt sich bei Doppelklick im Explorer kommentarlos zu schließen (-NoPause unterdrückt das für automatisierte Aufrufe/CI).

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.

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 + Notizen, siehe versapad_combined.py) liegt unter %APPDATA%\VersaPadViewer\ (versapad_data.app_dir()), also getrennt vom Installationsordner und unabhängig davon, ob die .exe oder der Quellcode gestartet wurde. Beides ist Absicht: das Build-Skript räumt sein Zielverzeichnis vor jedem Deploy komplett ab (läge die Config dort, würde jeder Rebuild sie löschen), und ein vom Startweg abhängiger Pfad hatte zu zwei auseinanderlaufenden Configs geführt. Fehlt die Datei (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. Notizen ebenso — im Bearbeiten-Dialog des Programmiermodus oder per set_button_note()/set_encoder_note() (MCP).

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). Für Claude Code liegt bereits eine projektgebundene .mcp.json im Repo (Server "versapad", Kommando py versapad_mcp_server.py) — beim Öffnen des Projekts wird sie automatisch zum Verbinden angeboten. Für andere Anwendungen oder user-scope-Registrierung in der jeweiligen MCP-Server-Liste 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

Dokumentation

Ausführlichere technische Doku im docs/-Ordner:

  • docs/architecture.md — Schichtenmodell, Prozessmodell, Modi, Config-Speicherort, Nebenläufigkeit
  • docs/data-model.md — JSON-Formate (kombiniert + Legacy), binäres NVM-Layout, Geometrie, Enums
  • docs/protocol.md — Serial-Wire-Protokoll (Befehle, Events, Paketformat, CRC16)

Weiterentwicklung

Agentenseitige Notizen (Domänenregeln, bekannte Bugs und ihre Fixes, Implementierungsdisziplin, Design-Entscheidungen) stehen in AGENTS.md.

Lizenz / Herkunft

Eigenständiges Begleit-Tool, kein Teil der offiziellen VersaGUI/VersaMCU-Repos.