import tkinter as tk from tkinter import ttk import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import asyncio from .filter import * from .gui.device import Device from .gui.slider import Slider class FilterDevApp(tk.Tk): def __init__(self, loop: asyncio.EventLoop): super().__init__() self.loop = loop self.protocol("WM_DELETE_WINDOW", self.close) self.tasks = [] self.tasks.append(loop.create_task(self.updater(1./2))) self.tasks.append(loop.create_task(self.update_plot(1./20))) self.tasks.append(loop.create_task(self.read_values(1./100))) self.filter = None self.title("JannTers Filter Evaluation Tool") # Create a frame for the plot and sliders self.frame = tk.Frame(self) self.frame.pack(side=tk.LEFT, fill=tk.BOTH) # Create a figure for plotting self.fig, self.ax = plt.subplots() self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame) self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH) # Create a frame for sliders self.toolbar = tk.Frame(self, width=200, padx=10) self.toolbar.pack(side=tk.RIGHT, fill=tk.Y) # Device Settings self.connect_button = ttk.Button(self.toolbar, text="Connect", command=self.connect_disconnect) self.connect_button.pack(pady=10) self.device_label = ttk.Label(self.toolbar, text="Device Name:") self.device_label.pack(pady=10) self.device_name = ttk.Entry(self.toolbar) self.device_name.insert(0, "Smaage") # Set default value self.device_name.pack(pady=10) self.device = Device(self.device_name) # Filter Settings self.filter_type_label = ttk.Label(self.toolbar, text="Filter:") self.filter_type_label.pack(pady=10) self.filter_type_combobox = ttk.Combobox(self.toolbar, values=["MovAvg"]) self.filter_type_combobox.set("MovAvg") # Set default value self.filter_type_combobox.pack(pady=10) self.change_filter = ttk.Button(self.toolbar, text="Change Filter", command=self.update_filter) self.change_filter.pack(pady=10) # Objects self.filter = MovAvg(self.device, self.toolbar, lambda: None) self.filter.pack() async def update_plot(self, interval): while await asyncio.sleep(interval, True): if self.filter is None: continue # Clear the current plot self.ax.clear() # Get current values from sliders df = self.filter() # Generate data x = df['timestamps'] y1 = df['weights'] y2 = df['filtered'] # Plot the data self.ax.plot(x, y1) self.ax.plot(x, y2) self.ax.set_xlabel("Time in ms") self.ax.set_ylabel("Weight") self.ax.grid() # Draw the updated plot self.canvas.draw() def update_filter(self): option = self.filter_type_combobox.get() if option == 'MovAvg' and not isinstance(self.filter, MovAvg): self.filter = MovAvg(self.device, self.toolbar, self.update_plot) self.update_plot() def connect_disconnect(self): if self.device.is_connected: self.device_label.pack(pady=10) self.device_name.pack(pady=10) self.connect_button.config(text="Connect") self.connect_button.pack(pady=10) self.device.disconnect() else: task = self.loop.create_task(self.device.connect()) task.add_done_callback(self.connected) def connected(self, *args): if self.device.is_connected: self.device_label.pack_forget() self.device_name.pack_forget() self.connect_button.config(text="Disconnect") self.filter.pack() async def read_values(self, interval): await self.device.read_values(interval) async def updater(self, interval): while await asyncio.sleep(interval, True): self.update() def close(self): for task in self.tasks: task.cancel() self.loop.stop() self.destroy() if __name__ == "__main__": loop = asyncio.new_event_loop() app = FilterDevApp(loop) loop.run_forever() loop.close()