Files
OBD2-Simulator/app/tabs/dashboard.py

78 lines
2.9 KiB
Python

# app/tabs/dashboard.py
from __future__ import annotations
import tkinter as tk
from tkinter import ttk
class DashboardTab:
"""Zeigt dynamisch alle im Vehicle registrierten Dashboard-Metriken."""
def __init__(self, parent, sim):
self.sim = sim
self.frame = ttk.Frame(parent, padding=8)
self.tree = ttk.Treeview(self.frame, columns=("label","value","unit","key","source"), show="headings", height=12)
self.tree.heading("label", text="Parameter")
self.tree.heading("value", text="Wert")
self.tree.heading("unit", text="Einheit")
self.tree.heading("key", text="Key")
self.tree.heading("source",text="Modul")
self.tree.column("label", width=180, anchor="w")
self.tree.column("value", width=120, anchor="e")
self.tree.column("unit", width=80, anchor="w")
self.tree.column("key", width=180, anchor="w")
self.tree.column("source",width=100, anchor="w")
self.tree.grid(row=0, column=0, sticky="nsew")
sb = ttk.Scrollbar(self.frame, orient="vertical", command=self.tree.yview)
self.tree.configure(yscrollcommand=sb.set)
sb.grid(row=0, column=1, sticky="ns")
self.frame.columnconfigure(0, weight=1)
self.frame.rowconfigure(0, weight=1)
self._last_keys = None
self._tick()
def _format_value(self, val, fmt):
if fmt:
try:
return f"{val:{fmt}}"
except Exception:
return str(val)
return str(val)
def _tick(self):
snap = self.sim.v.dashboard_snapshot()
specs = snap["specs"]
values = snap["values"]
keys = sorted(specs.keys(), key=lambda k: (specs[k].get("priority", 999), specs[k].get("label", k)))
if keys != self._last_keys:
# rebuild table
for item in self.tree.get_children():
self.tree.delete(item)
for k in keys:
spec = specs[k]
lbl = spec.get("label", k)
unit = spec.get("unit", "")
src = spec.get("source", "")
val = self._format_value(values.get(k, ""), spec.get("fmt"))
self.tree.insert("", "end", iid=k, values=(lbl, val, unit, k, src))
self._last_keys = keys
else:
# update values only
for k in keys:
spec = specs[k]
val = self._format_value(values.get(k, ""), spec.get("fmt"))
try:
self.tree.set(k, "value", val)
except tk.TclError:
pass
try:
self.frame.after(200, self._tick)
except tk.TclError:
pass
# Config-API no-ops (für Konsistenz mit anderen Tabs)
def save_into_config(self, out): # pragma: no cover
pass
def load_from_config(self, cfg): # pragma: no cover
pass