7 KiB
versapad-viewer
Eigenes kleines Tool (Grovy311-Kontext, nicht Teil der fremden jappel-Repos
VersaGUI/VersaMCU). Zeigt die Steuermatrix (4x5 Button-Grid + 4 Encoder) als
Browser-Live-Seite oder natives Tkinter-Fenster. Inzwischen mehr als ein
reiner Viewer: der Tkinter-Desktop-Viewer hat einen vollen Programmiermodus
(Action-Editor, Serial-Schreibzugriff aufs Board, Makro-Editor) bekommen —
faktisch ein schlankes Python-Pendant zu VersaGUI. Der Browser-Server
(server.py) blieb bewusst read-only/einfach.
Architektur
Read-only-Schicht (JSON, beide Frontends):
versapad_data.py— Decoding fuer Anzeige: JSON laden, HID-Keycode/ Consumer-Usage/Modifier → lesbarer Text, Grid-Geometrie (index = spalte*5+reihe),hid_key_choices()/consumer_choices()fuer Dropdowns.server.py— stdlibhttp.server, generiert HTML bei jedem Request neu, Profil-Wechsel über?profile=0|1|2, Auto-Reload alle 4s. Rein lesend, kein Programmiermodus (bewusst einfach gehalten).
Binaer-/Serial-Schicht (fuer den Programmiermodus):
versapad_protocol.py— pack/unpack fuerSDeviceConfig(740B, alle 3 Profile) undSMacroTable(512B, 32 Slots) + CRC16 (Poly 0x1021, Init 0xFFFF), 1:1 aus den Firmware-Structs (nvm_config.h,action.h,macro_config.h,CButton.h-LEDAnim-Enum,nvm_config.cpp-CRC). Gegen echtes Board validiert: read → unpack → pack → byte-identisch zum Original, inkl. CRC — siehe Git-Historie dieser Datei / Sessionlog.versapad_serial.py—VersaPadLink: liest/schreibt komplette Config + Makros per 8-Byte-Paket-Protokoll (CmdConfigRead/Begin/Data/Commit,CmdMacroRead/Begin/Data/Commit), Board-Identifikation per VID/PID239A:0042. Schreiben ist sicher im Sinne von "kann NVM nicht zerlegen" — Firmware prueft Magic/CRC/Keycode-Bereich vor jedem Save und antwortet sonst nur mit NACK (kein Datenmuell moeglich).versapad_combined.py— kombiniertes Ein-Datei-Format (alle 3 Profile + Makros + nur lokal gespeicherte Profilnamen) statt der 3 Einzel-JSONs. Passt besser zum Wire-Protokoll:CONFIG_BEGIN/COMMITueberträgt ohnehin immer den kompletten 740B-Block auf einmal, nie nur ein Profil. Default-Pfad:~\OneDrive\Desktop\versapad_config_all.json.
UI:
desktop_viewer.py— Tkinter, flaches Design (Label-Flächen, keine Canvas-Formen/Anti-Aliasing). Zellen nutzen.place()mit festen Pixel-Positionen statt.pack()(mit pack sah das Grid je nach leerer/ belegter Zelle ungleichmäßig aus). Drei unabhängige Modi:- Nur lesen (Default): pollt die 3 JSONs alle 1.5s.
- Live-Sync: pollt per Serial das aktive Profil vom Board, schaltet
Tabs automatisch mit. Laeuft in einem Hintergrundthread, der NUR ueber
eine
queue.Queuemit dem Main-Thread kommuniziert (self.after()direkt aus einem Fremdthread aufrufen ist in Tkinter nicht threadsicher und hat den Prozess in einer frueheren Version lautlos abstuerzen lassen —pywhat kein Konsolenfenster, der Crash war unsichtbar). - Programmiermodus: Zellen anklicken →
action_dialog.py(ActionEditDialog/MacroStepsDialog) bearbeitet Action-Typ, HID-Taste (Dropdown statt Tastendruck-Capture — kein WinAPI-Hook, um nicht wieder einen AV-Fehlalarm wie bei den Fensterverstecktricks zu riskieren), Consumer, Makro-Slot+Schritte, ProfileSwitch, LED-Farbe/Animation. "Vom Board laden"/"Zum Board übertragen" nutzen die Binaer-Schicht. Schaltet Live-Sync automatisch aus (einVersaPadLinkkann nicht von zwei Konsumenten gleichzeitig genutzt werden).
action_dialog.py— die beiden Bearbeiten-Dialoge, importiert nurversapad_data(fuer Dropdown-Inhalte).
Quelle der Wahrheit — nicht raten
Bei Aenderungen am Schema/Decoding/Binaerformat immer gegen die Firmware- und GUI-Quellen abgleichen, nie aus dem Gedaechtnis rekonstruieren:
VersaGUI/src/ActionDialog.cs(HidKeyName, s_consumer, Modifier-Bits)VersaGUI/src/Protocol.cs(Paket-IDs, Chunk-Groessen)VersaMCU/src/config/nvm_config.h+.cpp(SDeviceConfig-Layout, CRC)VersaMCU/src/config/action.h(SAction, ActionType-Enum-Werte)VersaMCU/src/config/macro_config.h+.cpp(SMacroTable-Layout)VersaMCU/src/CButton.h(LEDAnim-Enum-Werte)VersaMCU/src/CMainController.cpp(welche Commands die Firmware tatsaechlich behandelt — Protocol.cs definiert mehr Konstanten als die Firmware zwingend implementiert, immer hier gegenchecken)
Zeichentasten (A-Z, Ziffern, Satzzeichen) zeigen US-Layout-Näherung, da die
echte GUI das über GetKeyNameText() layoutabhängig auflöst — das bilden
wir ohne WinAPI-Call nicht nach.
Korrektur einer frueheren Annahme: Anders als zuerst notiert, kann die
Firmware Makros sehr wohl per normaler USB-Verbindung schreiben
(USB_CMD_MACRO_BEGIN/DATA/COMMIT in CMainController.cpp sind
implementiert) — kein SWD/JTAG noetig. Der VersaPad-Skill
(~/.claude/skills/versapad/SKILL.md) behauptet noch das Gegenteil und
sollte bei Gelegenheit korrigiert werden.
Start
py server.py # Browser, http://127.0.0.1:8765
pyw desktop_viewer.py # natives Fenster, kein Konsolenfenster
Oder run_browser.bat / run_desktop.bat per Doppelklick, oder die
Desktop-Verknuepfungen "VersaPad Viewer (Browser)" / "VersaPad Viewer
(Fenster)".
Wichtig: pyw/py benutzen, nicht bare pythonw/python — auf hal9001
liegt in PATH zuerst eine Hermes-Agent-venv (...\hermes\hermes-agent\venv\ Scripts\pythonw.exe) ohne pyserial. pyw/py (Python Launcher) lösen
zuverlässig zur echten Python313-Installation auf.
Dateien/Pfade (hardcoded, hal9001-spezifisch)
- Einzel-JSONs (Read-only-Modus):
~\OneDrive\Desktop\versapad_config{1,2,3}.json— Profil 0 Windows / 1 Fusion 360 / 2 BricsCAD, sieheversapad_data.CONFIG_PATHS. - Kombinierte Datei (Programmiermodus-Export):
~\OneDrive\Desktop\ versapad_config_all.json(Default, sieheversapad_combined.DEFAULT_PATH).
Offene Punkte
- Kein automatischer Windows-Start/Tray-Icon — bewusst einfach gehalten, bei Bedarf nachrüstbar.
- Live-Sync und VersaGUI (bzw. Programmiermodus) können den COM-Port nicht
gleichzeitig halten (exklusiver Zugriff) — zeigt dann "Port belegt", kein
Crash. VersaGUI läuft als Tray-App dauerhaft im Hintergrund weiter, auch
wenn nur das Konfigurationsfenster geschlossen wird — für Programmiermodus/
Live-Sync muss es über das Tray-Icon → "Beenden" wirklich beendet werden.
Live-Sync wird beim Aktivieren des Programmiermodus automatisch ausgeschaltet.
Innerhalb des Programmiermodus selbst laufen "Vom Board laden"/"Zum Board
übertragen" synchron im UI-Thread (kurzzeitiges Einfrieren möglich, v.a.
bei Timeout) — bislang nicht als Hintergrund-Thread ausgelagert.
Der Browser-Server (
server.py) hat keinen Programmiermodus. - HID-Tasten-Auswahl im Programmiermodus ist ein Dropdown, kein Tastendruck-Capture (bewusst, um WinAPI-Hooks/AV-Fehlalarme zu vermeiden).
- Macro-Editor erlaubt nur Strg/Shift/Alt pro Schritt (kein Win), passend
zum Original-
ActionDialog.cs-Verhalten fuer Makro-Steps.