"""Tkinter GUI monitor for PyBusMonitor1553. Minimal GUI with: - Treeview showing registered messages (label, CW.raw, size) - Text log for raw sent/received events - Buttons: `Inizializza`, `Start`, `Stop`, `Aggiorna` This scaffold calls `pybusmonitor1553.core.connection_manager` for init/start/stop. """ import tkinter as tk from tkinter import ttk, scrolledtext, messagebox from pybusmonitor1553.core.connection_manager import get_manager from Grifo_E_1553lib.messages.messages import MessageDB import threading import time class MonitorApp(tk.Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack(fill=tk.BOTH, expand=True) self.manager = get_manager() self.create_widgets() self.update_loop_running = False def create_widgets(self): toolbar = tk.Frame(self) toolbar.pack(side=tk.TOP, fill=tk.X) self.init_btn = tk.Button(toolbar, text="Inizializza", command=self.on_init) self.init_btn.pack(side=tk.LEFT, padx=4, pady=4) self.start_btn = tk.Button(toolbar, text="Start", command=self.on_start) self.start_btn.pack(side=tk.LEFT, padx=4, pady=4) self.stop_btn = tk.Button(toolbar, text="Stop", command=self.on_stop) self.stop_btn.pack(side=tk.LEFT, padx=4, pady=4) self.refresh_btn = tk.Button(toolbar, text="Aggiorna", command=self.refresh_messages) self.refresh_btn.pack(side=tk.LEFT, padx=4, pady=4) # Filters row filter_fr = tk.Frame(self) filter_fr.pack(side=tk.TOP, fill=tk.X, padx=6) tk.Label(filter_fr, text="Filtro label:").pack(side=tk.LEFT) self.filter_entry = tk.Entry(filter_fr, width=20) self.filter_entry.pack(side=tk.LEFT, padx=4) tk.Label(filter_fr, text="Periodo min(ms):").pack(side=tk.LEFT, padx=(8,0)) self.period_min = tk.Entry(filter_fr, width=8) self.period_min.pack(side=tk.LEFT, padx=4) tk.Label(filter_fr, text="max(ms):").pack(side=tk.LEFT) self.period_max = tk.Entry(filter_fr, width=8) self.period_max.pack(side=tk.LEFT, padx=4) tk.Button(filter_fr, text="Applica", command=self.refresh_messages).pack(side=tk.LEFT, padx=6) # Message table (columns per screenshot) columns = ("label", "cw", "sw", "num", "errs", "period", "wc", "mc") self.tree = ttk.Treeview(self, columns=columns, show="headings", height=14) self.tree.heading("label", text="Name") self.tree.heading("cw", text="CW") self.tree.heading("sw", text="SW") self.tree.heading("num", text="Num") self.tree.heading("errs", text="Errs") self.tree.heading("period", text="period") self.tree.heading("wc", text="wc") self.tree.heading("mc", text="MC") self.tree.column("label", width=100) self.tree.column("cw", width=80) self.tree.column("sw", width=60) self.tree.column("num", width=60) self.tree.column("errs", width=60) self.tree.column("period", width=80) self.tree.column("wc", width=40) self.tree.column("mc", width=60) self.tree.pack(fill=tk.BOTH, expand=True, padx=6, pady=6) # Log area self.log = scrolledtext.ScrolledText(self, height=10) self.log.pack(fill=tk.BOTH, expand=False, padx=6, pady=6) def on_init(self): try: self.manager.init_library() self.log.insert(tk.END, "Inizializzazione eseguita.\n") self.refresh_messages() except Exception as e: messagebox.showerror("Errore", str(e)) def on_start(self): try: self.manager.start() self.log.insert(tk.END, "Avvio invio/ricezione\n") if not self.update_loop_running: self.update_loop_running = True threading.Thread(target=self.periodic_update, daemon=True).start() except Exception as e: messagebox.showerror("Errore", str(e)) def on_stop(self): self.manager.stop() self.log.insert(tk.END, "Stop richiesto\n") def refresh_messages(self): self.tree.delete(*self.tree.get_children()) try: msgs = MessageDB.getAllMessages() lbl_filter = self.filter_entry.get().strip().lower() pmin = None pmax = None try: if self.period_min.get().strip() != "": pmin = float(self.period_min.get().strip()) if self.period_max.get().strip() != "": pmax = float(self.period_max.get().strip()) except Exception: pmin = pmax = None for k, v in msgs.items(): if lbl_filter and lbl_filter not in k.lower(): continue # cw raw cw_raw = None wc = '' try: cw_raw = getattr(v.head.cw, 'raw', None) wc = getattr(v.head.cw.str, 'wc', '') except Exception: cw_raw = None # sw sw_raw = '' try: sw_raw = getattr(v.head, 'sw', '') except Exception: sw_raw = '' # num -> size (bytes) as fallback num = getattr(v, 'size', '') # errs errs = '' try: errs = getattr(v.head, 'errcode', '') except Exception: errs = '' # period (ms) period = getattr(v, '_time_ms', None) if period is None: # try compute from freq freq = getattr(v, 'freq', None) if freq: period = 1000.0 / freq if period is not None and pmin is not None and period < pmin: continue if period is not None and pmax is not None and period > pmax: continue mc = '' try: mc = getattr(v, 'mcounter', '') except Exception: mc = '' self.tree.insert('', tk.END, values=(k, hex(cw_raw) if cw_raw is not None else '', sw_raw, num, errs, f"{period:.3f}" if period else '', wc, mc)) except Exception: pass def periodic_update(self): while self.manager.is_running(): try: self.refresh_messages() except Exception: pass time.sleep(0.5) self.update_loop_running = False def main(): root = tk.Tk() root.title("PyBusMonitor1553 - Monitor") root.geometry("800x600") app = MonitorApp(master=root) app.mainloop() if __name__ == '__main__': main()