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.
This commit is contained in:
commit
189ec01e68
11 changed files with 470 additions and 125 deletions
|
|
@ -110,13 +110,18 @@ auf.
|
|||
|
||||
`versapad_data.app_dir()` bestimmt das Basisverzeichnis für die eigene
|
||||
Config-Datei (`versapad_combined.DEFAULT_PATH` =
|
||||
`app_dir()/versapad_config_all.json`):
|
||||
`app_dir()/versapad_config_all.json`): `%APPDATA%\VersaPadViewer`
|
||||
(Roaming-AppData), unabhängig davon, ob die gebaute `.exe` oder der
|
||||
Quellcode gestartet wurde (kein `sys.frozen`-Zweig).
|
||||
|
||||
- **Gebaute `.exe`** (PyInstaller `--onedir`): `sys.executable`s Ordner —
|
||||
die Config liegt also neben `VersaPadViewer.exe`, in welchem
|
||||
Installationsverzeichnis sie auch liegt.
|
||||
- **Start aus dem Quellcode** (`py desktop_viewer.py`, `py server.py`,
|
||||
`py versapad_mcp_server.py`): der Projektordner (`__file__`-Verzeichnis).
|
||||
Bewusst **nicht** das Installationsverzeichnis (`%LOCALAPPDATA%\
|
||||
VersaPadViewer`, wo die `.exe` liegt): `build_and_deploy.ps1` räumt das
|
||||
Zielverzeichnis vor jedem Deploy komplett ab, läge die Config dort, würde
|
||||
jeder Rebuild sie mitlöschen (genau das ist am 2026-08-15 passiert, siehe
|
||||
`AGENTS.md`). Ebenso bewusst **nicht** vom Startweg abhängig — sonst sähe
|
||||
die `.exe` eine andere Datei als ein aus dem Quellcode gestarteter
|
||||
`versapad_mcp_server.py`, und Änderungen aus dem einen Weg wären im
|
||||
anderen unsichtbar (ebenfalls am 2026-08-15 beobachtet).
|
||||
|
||||
Fehlt die Datei, legt `load_or_fetch()` sie automatisch an — zuerst per
|
||||
Serial-Versuch vom Board (das ist die eigentliche Quelle der Wahrheit, die
|
||||
|
|
@ -177,8 +182,11 @@ statt dem ACK allein zu vertrauen. Details siehe „Bug beobachtet
|
|||
`build_and_deploy.ps1` installiert `requirements.txt` selbst
|
||||
(`pip install -r`), baut mit PyInstaller (`--onedir --windowed`, nur
|
||||
`desktop_viewer.py` wird gebündelt) und kopiert das Ergebnis nach
|
||||
`dist\VersaPadViewer\` im Projektordner. `--onedir` statt `--onefile`, um
|
||||
AV-Fehlalarme zu verringern. Läuft komplett in try/catch mit
|
||||
`%LOCALAPPDATA%\VersaPadViewer\`. `--onedir` statt `--onefile`, um
|
||||
AV-Fehlalarme zu verringern. Räumt das Zielverzeichnis vor dem Kopieren
|
||||
komplett ab, rettet dabei aber zuvor gefundene `versapad_config*.json`
|
||||
(Altinstallationen, bei denen die Config noch im Installationsordner
|
||||
liegt) über den Deploy hinweg. Läuft komplett in try/catch mit
|
||||
Exit-Code-Prüfung und pausiert am Ende (Erfolg wie Fehler) auf
|
||||
Tastendruck, außer bei `-NoPause`. Muss lokal laufen, nicht auf einem
|
||||
Netzlaufwerk (Pfadlängen-/DLL-Ladeprobleme, siehe `AGENTS.md`). Details:
|
||||
|
|
|
|||
|
|
@ -50,6 +50,16 @@ siehe unten):
|
|||
| `0x04` | Alt |
|
||||
| `0x08` | Win |
|
||||
|
||||
Jede `Action` trägt zusätzlich ein optionales `note`-Feld (freier Text,
|
||||
z.B. `"Speichern in Fusion 360"`) — **rein lokal**, wie `profile_names`
|
||||
(siehe unten): kein Platz dafür in `SAction` (3 Byte, komplett verplant),
|
||||
`to_binary()`/`pack_config()` ignorieren das Feld beim Schreiben ans
|
||||
Board, `from_binary()` liefert frisch vom Board immer `note=""`.
|
||||
`versapad_combined.merge_notes(neu, alt)` kopiert bestehende Notizen nach
|
||||
jedem `load_from_board()`/`fetch_from_board()` zurück, sonst gingen sie
|
||||
bei jedem Board-Refresh verloren. Editierbar per Programmiermodus-Dialog
|
||||
oder MCP (`set_button_note()`/`set_encoder_note()`).
|
||||
|
||||
## LED
|
||||
|
||||
Pro MX-Button (nicht pro Encoder — Encoder haben keine eigene LED):
|
||||
|
|
@ -100,7 +110,7 @@ kompletten 740B-Block, nie nur ein Profil.
|
|||
"buttons": [
|
||||
{
|
||||
"index": 0,
|
||||
"action": { "type": "HidKey", "data": 30 },
|
||||
"action": { "type": "HidKey", "data": 30, "note": "Speichern in Fusion 360" },
|
||||
"led": { "r": 80, "g": 40, "b": 0, "brightness": 255,
|
||||
"anim": "Static", "period_ms": 4000 }
|
||||
}
|
||||
|
|
@ -128,7 +138,8 @@ kompletten 740B-Block, nie nur ein Profil.
|
|||
Profilnamen (`profile_names`) sind **rein lokal** — die Firmware-Structs
|
||||
haben keinen Platz für einen String (Header exakt 32B, jedes Profil exakt
|
||||
236B, alles verplant), sie landen nie aufs Board, egal welcher
|
||||
Schreibpfad benutzt wird.
|
||||
Schreibpfad benutzt wird. Dasselbe gilt für `note` in jeder `Action`
|
||||
(siehe oben).
|
||||
|
||||
## JSON: Legacy-Einzeldatei-Format (`versapad_config1/2/3.json`)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue