diff --git a/PTPLogger/PTPLogger_Graphing.py b/PTPLogger/PTPLogger_Graphing.py new file mode 100644 index 0000000..5d72f2c --- /dev/null +++ b/PTPLogger/PTPLogger_Graphing.py @@ -0,0 +1,85 @@ +import re +import datetime as dt +import matplotlib.pyplot as plt +import tkinter as tk +from tkinter import filedialog, messagebox + +def parse_log(file_path): + t = [] + rms = [] + freq = [] + + with open(file_path, encoding='utf-8', errors='ignore') as f: + for line in f: + # Match only valid ptp4l stat lines + match = re.search( + r'^(\w+ \d+ \d+:\d+:\d+).*rms (\d+).*freq ([+-]?\d+)', + line + ) + if match: + try: + # Add year (needed for parsing) + timestr = match.group(1) + " 2026" + timestamp = dt.datetime.strptime( + timestr, "%b %d %H:%M:%S %Y" + ) + + t.append(timestamp) + rms.append(int(match.group(2))) + freq.append(int(match.group(3))) + + except Exception: + # Skip malformed lines safely + pass + + return t, rms, freq + + +def plot_data(t, rms, freq): + if not t: + messagebox.showerror("Error", "No valid PTP lines found.") + return + + fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True) + + ax1.plot(t, rms) + ax1.set_ylabel("RMS (ns)") + ax1.set_title("PTP RMS Offset") + + ax2.plot(t, freq) + ax2.set_ylabel("Frequency deviation") + ax2.set_xlabel("Time") + ax2.set_title("PTP Frequency Deviation") + + plt.xticks(rotation=30) + plt.tight_layout() + plt.show() + + +def open_file(): + file_path = filedialog.askopenfilename( + title="Select PTP log file", + filetypes=[("Log files", "*.log *.txt"), ("All files", "*.*")] + ) + + if not file_path: + return + + t, rms, freq = parse_log(file_path) + + plot_data(t, rms, freq) + + +# --- GUI setup --- +root = tk.Tk() +root.title("PTP Log Viewer") + +root.geometry("300x150") + +label = tk.Label(root, text="PTP Log Plotter", font=("Arial", 14)) +label.pack(pady=10) + +btn = tk.Button(root, text="Open Log File", command=open_file) +btn.pack(pady=10) + +root.mainloop() \ No newline at end of file