AGENTS.md: die WinAPI-Regel praeziser gefasst -- verboten bleiben Fenstermanipulation und globale Hooks, passive Layout-Abfragen sind es nicht (und die offizielle VersaGUI macht dasselbe). Dazu die neue Aufloesungsreihenfolge samt Warnung, nicht auf "Zeichen auswerten" zurueckzubauen, die Kollisionsregel bei Tastennamen, der Mehrmonitor-Fix und die Folgen der Titelleiste (welche Eigenbauten dadurch entfallen sind und warum randlos nicht ohne Ruecksprache zurueckkommt). README.md und docs/architecture.md entsprechend: Position statt Zeichen, layoutrichtige Beschriftungen inkl. der Anzeigeaenderung an bestehenden Belegungen, Taskleisten-Eintrag statt randlosem Fenster. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| docs | ||
| .gitignore | ||
| .mcp.json | ||
| action_dialog.py | ||
| AGENTS.md | ||
| build_and_deploy.ps1 | ||
| desktop_viewer.py | ||
| icon.ico | ||
| icon.png | ||
| README.md | ||
| requirements.txt | ||
| run_browser.bat | ||
| run_desktop.bat | ||
| server.py | ||
| versapad_combined.py | ||
| versapad_data.py | ||
| versapad_keylayout.py | ||
| versapad_mcp_server.py | ||
| versapad_protocol.py | ||
| versapad_serial.py | ||
| VersaPadViewer.spec | ||
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. Der Dialog öffnet über dem Hauptfenster, Enter bestätigt, Escape bricht ab
- Tastendruck-Erkennung — statt die Taste im Dropdown zu suchen,
„⌨ Taste drücken" klicken und die gewünschte Kombination einfach
drücken (Modifier inklusive). Erkannt wird die physische Taste, nicht
das Zeichen — Y/Z, ÄÖÜ,
#,+undßlanden also richtig auf dem Board, auch auf deutschem Layout. Läuft über das Dialogfenster, nicht über einen System-Hook: vom System abgefangene Kombinationen (Win+L, Strg+Alt+Entf) kommen nicht an - Layoutrichtige Tastennamen — Beschriftungen kommen vom aktiven
Windows-Layout (
Strg+Zheißt auf deutscher Tastatur auchStrg+Z, undä/ö/üheißen so). Bestehende Belegungen ändern dadurch ihre Anzeige, nicht ihre Funktion - Makro-Editor — bis zu 8 Schritte pro Slot, liest/schreibt die echte Makro-Tabelle vom Board. Schritte einzeln erfassen oder die ganze Folge am Stück aufnehmen („⏺ Folge aufnehmen"). Die Slot-Auswahl listet alle 32 Slots samt Inhalt, statt sie einzeln durchklicken zu müssen
- Makros im Grid lesbar — eine Makro-Belegung zeigt die tatsächliche
Tastenfolge (
Makro 3: Strg+C → Strg+V) statt nur der Slot-Nummer; das gilt auch in der Browser-Ansicht und in den MCP-Antworten - Farb-Schnellwahl — zwölf Grundfarben direkt in der LED-Zeile des Dialogs, der System-Farbdialog nur noch für den Rest („mehr…")
- Kopieren/Einfügen zwischen Tasten — Rechtsklick auf eine Karte im Programmiermodus: Belegung und/oder Farbe kopieren und auf andere Tasten anwenden, oder die Belegung leeren. Strg+C/Strg+V wirken auf die Karte unter dem Mauszeiger
- 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
- Normales Fenster mit Taskleisten-Eintrag — Titelleiste, Alt+Tab,
Aero-Snap und Größe ändern am Rahmen funktionieren nativ.
✕beendet nicht, sondern legt ins Tray (wie die offizielle VersaGUI — das Programm läuft im Hintergrund weiter); Minimieren geht normal in die Taskleiste. - Tastenkürzel im Hauptfenster —
Strg+1/2/3Profil wechseln,F2Profil umbenennen,Strg+EProgrammiermodus an/aus,Strg+C/Strg+VTaste unter dem Mauszeiger kopieren/einfügen,Escminimieren.
Voraussetzungen
- Python 3.11 oder neuer
- Alle Pakete stehen in
requirements.txt(pyserialfürs Board,pystray+pillowfürs Tray-Icon/Desktop-Fenster,mcpfür den MCP-Server,pyinstallerfü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, Tastendruck → HID-Keycode |
versapad_keylayout.py |
Abfragen ans aktive Windows-Tastaturlayout: physische Tastenposition und Tastenname (optional, nur Windows) |
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)
- Die Tastendruck-Erkennung läuft bewusst über das Dialogfenster statt über einen globalen WinAPI-Hook — vom System abgefangene Kombinationen (Win+L, Strg+Alt+Entf) erreichen das Fenster nie und lassen sich so nicht erfassen
- Ein Wechsel des Tastaturlayouts im laufenden Programm wird nicht bemerkt (die Tastennamen werden einmal beim ersten Zugriff ermittelt) — Neustart hilft. Unter Nicht-Windows fällt die Beschriftung auf eine US-Layout-Näherung zurück
- 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äufigkeitdocs/data-model.md— JSON-Formate (kombiniert + Legacy), binäres NVM-Layout, Geometrie, Enumsdocs/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.