SXXXXXXX_PyBusMonitor1553/pybusmonitor1553/gui/monitor.py
2025-12-17 07:59:30 +01:00

190 lines
6.8 KiB
Python

"""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()