100 lines
3.2 KiB
Python
100 lines
3.2 KiB
Python
import os
|
|
import csv
|
|
import tkinter as tk
|
|
from tkinter import ttk
|
|
from tkinter import messagebox
|
|
from datetime import datetime
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
|
|
|
LOGS_DIR = "logs"
|
|
|
|
class GraphViewer(tk.Toplevel):
|
|
def __init__(self, master=None):
|
|
super().__init__(master)
|
|
self.title("Valve Graph Viewer")
|
|
self.geometry("1000x600")
|
|
|
|
self._create_widgets()
|
|
self._populate_dates()
|
|
|
|
def _create_widgets(self):
|
|
self.date_label = ttk.Label(self, text="Select Date:")
|
|
self.date_label.pack()
|
|
|
|
self.date_cb = ttk.Combobox(self, state="readonly")
|
|
self.date_cb.pack()
|
|
|
|
self.node_label = ttk.Label(self, text="Select Node:")
|
|
self.node_label.pack()
|
|
|
|
self.node_cb = ttk.Combobox(self, state="readonly", values=[f"Node{nid:02}" for nid in range(5, 25)])
|
|
self.node_cb.pack()
|
|
|
|
self.plot_btn = ttk.Button(self, text="Plot Graph", command=self._plot_graph)
|
|
self.plot_btn.pack(pady=10)
|
|
|
|
self.canvas_frame = ttk.Frame(self)
|
|
self.canvas_frame.pack(fill="both", expand=True)
|
|
|
|
def _populate_dates(self):
|
|
if not os.path.exists(LOGS_DIR):
|
|
return
|
|
dates = [d for d in os.listdir(LOGS_DIR) if os.path.isdir(os.path.join(LOGS_DIR, d))]
|
|
self.date_cb['values'] = sorted(dates)
|
|
if dates:
|
|
self.date_cb.current(0)
|
|
self.node_cb.current(0)
|
|
|
|
def _plot_graph(self):
|
|
date = self.date_cb.get()
|
|
node = self.node_cb.get()
|
|
|
|
filepath = os.path.join(LOGS_DIR, date, f"{node}.csv")
|
|
if not os.path.exists(filepath):
|
|
messagebox.showerror("File Not Found", f"No data for {node} on {date}.")
|
|
return
|
|
|
|
timestamps = []
|
|
setpoints = []
|
|
feedbacks = []
|
|
flows = []
|
|
pressures = []
|
|
|
|
with open(filepath, newline='') as csvfile:
|
|
reader = csv.DictReader(csvfile)
|
|
for row in reader:
|
|
try:
|
|
timestamps.append(datetime.strptime(row["Timestamp"], "%Y-%m-%d %H:%M:%S"))
|
|
setpoints.append(float(row["Setpoint"]))
|
|
feedbacks.append(float(row["Feedback"]))
|
|
flows.append(float(row["Flow (L/h)"]))
|
|
pressures.append(float(row["Pressure (bar)"]))
|
|
except Exception as e:
|
|
print(f"[PARSE ERROR] {e}")
|
|
|
|
self._draw_plot(timestamps, setpoints, feedbacks, flows, pressures)
|
|
|
|
def _draw_plot(self, t, sp, fb, fl, pr):
|
|
for widget in self.canvas_frame.winfo_children():
|
|
widget.destroy()
|
|
|
|
fig, ax = plt.subplots(figsize=(10, 5))
|
|
ax.plot(t, sp, label="Setpoint")
|
|
ax.plot(t, fb, label="Feedback")
|
|
ax.plot(t, fl, label="Flow (L/h)")
|
|
ax.plot(t, pr, label="Pressure (bar)")
|
|
ax.set_title("Valve Performance")
|
|
ax.set_xlabel("Time")
|
|
ax.set_ylabel("Values")
|
|
ax.legend()
|
|
ax.grid(True)
|
|
|
|
canvas = FigureCanvasTkAgg(fig, master=self.canvas_frame)
|
|
canvas.draw()
|
|
canvas.get_tk_widget().pack(fill="both", expand=True)
|
|
|
|
# Usage:
|
|
# from graph_viewer import GraphViewer
|
|
# btn.config(command=lambda: GraphViewer(root))
|