Initial commit: VersaPad viewer + programming mode
This commit is contained in:
parent
ef0faec100
commit
6227903ebd
10 changed files with 1765 additions and 0 deletions
94
versapad_combined.py
Normal file
94
versapad_combined.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
"""
|
||||
Kombiniertes Ein-Datei-Format fuer den Programmiermodus: alle 3 Profile +
|
||||
Makro-Tabelle + (nur lokal gespeicherte) Profilnamen in einer JSON-Datei,
|
||||
plus Konvertierung zu/von den Binaerblobs aus versapad_protocol.py.
|
||||
|
||||
Passt besser zum echten Geraeteprotokoll als die 3 Einzeldateien von
|
||||
versapad_data.py: CONFIG_BEGIN/DATA/COMMIT ueberträgt ohnehin immer den
|
||||
kompletten 740B-Block (alle 3 Profile auf einmal), nie nur ein Profil.
|
||||
|
||||
Profilnamen: die Firmware-Structs (SDeviceConfig/SDeviceProfile) haben
|
||||
keinerlei Platz fuer einen String -- Header exakt 32B, jedes Profil exakt
|
||||
236B, alles verplant (siehe nvm_config.h). Namen bleiben deshalb rein
|
||||
lokal in dieser Datei, landen nie auf dem Board.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
|
||||
import versapad_data as vp
|
||||
import versapad_protocol as proto
|
||||
|
||||
DEFAULT_PATH = os.path.expanduser(r"~\OneDrive\Desktop\versapad_config_all.json")
|
||||
|
||||
DEFAULT_NAMES = ["Windows", "Fusion 360", "BricsCAD"]
|
||||
|
||||
|
||||
def _empty_profile():
|
||||
buttons = [{"index": i, "action": {"type": "None", "data": 0},
|
||||
"led": {"r": 80, "g": 40, "b": 0, "brightness": 255,
|
||||
"anim": "Static", "period_ms": 4000}} for i in range(20)]
|
||||
none = {"type": "None", "data": 0}
|
||||
encoders = [{"index": i, "sw": dict(none), "cw": dict(none), "ccw": dict(none)} for i in range(4)]
|
||||
return {"buttons": buttons, "encoders": encoders}
|
||||
|
||||
|
||||
def default_combined():
|
||||
"""Seed aus den 3 bestehenden Einzel-JSONs (versapad_data.CONFIG_PATHS),
|
||||
fehlende Dateien werden als leeres Profil aufgefuellt. Makros leer,
|
||||
da die Einzel-JSONs keine Makro-Schritte enthalten (kein Exportformat
|
||||
dafuer) -- fuer echte Makro-Inhalte "Vom Board laden" benutzen."""
|
||||
profiles = []
|
||||
for p in range(3):
|
||||
try:
|
||||
cfg = vp.load_profile(p)
|
||||
profiles.append({
|
||||
"buttons": [{"index": b["index"], "action": b["action"], "led": b["led"]} for b in cfg["buttons"]],
|
||||
"encoders": [{"index": e["index"], "sw": e["sw"], "cw": e["cw"], "ccw": e["ccw"]} for e in cfg["encoders"]],
|
||||
})
|
||||
except FileNotFoundError:
|
||||
profiles.append(_empty_profile())
|
||||
|
||||
return {
|
||||
"active_profile": 0,
|
||||
"global_brightness": 255,
|
||||
"enc_sensitivity": [1, 1, 1, 1],
|
||||
"profile_names": list(DEFAULT_NAMES),
|
||||
"profiles": profiles,
|
||||
"macros": [[] for _ in range(proto.MACRO_SLOTS)],
|
||||
}
|
||||
|
||||
|
||||
def from_binary(config_dict, macro_slots, profile_names=None):
|
||||
"""config_dict: Ergebnis von versapad_protocol.unpack_config().
|
||||
macro_slots: Ergebnis von versapad_protocol.unpack_macros()."""
|
||||
return {
|
||||
"active_profile": config_dict["active_profile"],
|
||||
"global_brightness": config_dict["global_brightness"],
|
||||
"enc_sensitivity": config_dict["enc_sensitivity"],
|
||||
"profile_names": profile_names or list(DEFAULT_NAMES),
|
||||
"profiles": config_dict["profiles"],
|
||||
"macros": macro_slots,
|
||||
}
|
||||
|
||||
|
||||
def to_binary(combined):
|
||||
"""-> (config_bytes[740], macro_bytes[512])"""
|
||||
config_bytes = proto.pack_config({
|
||||
"active_profile": combined["active_profile"],
|
||||
"global_brightness": combined["global_brightness"],
|
||||
"enc_sensitivity": combined["enc_sensitivity"],
|
||||
"profiles": combined["profiles"],
|
||||
})
|
||||
macro_bytes = proto.pack_macros(combined["macros"])
|
||||
return config_bytes, macro_bytes
|
||||
|
||||
|
||||
def save_file(combined, path=DEFAULT_PATH):
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
json.dump(combined, f, indent=2, ensure_ascii=False)
|
||||
return path
|
||||
|
||||
|
||||
def load_file(path=DEFAULT_PATH):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
Loading…
Add table
Add a link
Reference in a new issue