Skip to content

Commit

Permalink
First Pilot Project of UI
Browse files Browse the repository at this point in the history
  • Loading branch information
Kiran Jojare committed Jul 9, 2024
1 parent 3594dd0 commit 787f9c7
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 22 deletions.
Binary file added assets/can_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 55 additions & 22 deletions src/canalyzer_mimic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
import matplotlib.pyplot as plt
from tkinter import *
from tkinter import filedialog, messagebox, colorchooser
from PIL import Image, ImageTk
import logging
import os

logging.basicConfig(level=logging.DEBUG)

class CANLogAnalyzer:
"""
Expand All @@ -32,7 +36,8 @@ def __init__(self, root):
"""
self.root = root
self.root.title("CANalyzer Mimic Pro")
self.root.geometry("500x300")
self.root.geometry("600x400")
self.root.configure(bg='#2C3E50')

self.log_file = ""
self.df = pd.DataFrame()
Expand All @@ -44,23 +49,30 @@ def create_welcome_window(self):
"""Create the welcome window with author information."""
self.clear_window()

welcome_label = Label(self.root, text="Welcome to CANalyzer Mimic Pro", font=("Arial", 16))
welcome_label = Label(self.root, text="Welcome to CANalyzer Mimic Pro", font=("Helvetica", 18, "bold"), bg='#2C3E50', fg='#ECF0F1')
welcome_label.pack(pady=20)

author_label = Label(self.root, text="Author: Kiran Jojare", font=("Arial", 12))
author_label = Label(self.root, text="Author: Kiran Jojare", font=("Helvetica", 12), bg='#2C3E50', fg='#ECF0F1')
author_label.pack(pady=10)

proceed_btn = Button(self.root, text="Proceed", command=self.create_file_selection_window)
can_image_path = os.path.join(os.path.dirname(__file__), '..', 'assets', 'can_image.png')
can_image = Image.open(can_image_path)
can_image = can_image.resize((300, 150), Image.LANCZOS)
self.can_photo = ImageTk.PhotoImage(can_image)
image_label = Label(self.root, image=self.can_photo, bg='#2C3E50')
image_label.pack(pady=10)

proceed_btn = Button(self.root, text="Proceed", command=self.create_file_selection_window, bg='#3498DB', fg='#ECF0F1', font=("Helvetica", 12, "bold"))
proceed_btn.pack(pady=20)

def create_file_selection_window(self):
"""Create the file selection window."""
self.clear_window()

self.select_file_btn = Button(self.root, text="Select CAN Log File", command=self.load_file)
self.select_file_btn = Button(self.root, text="Select CAN Log File", command=self.load_file, bg='#3498DB', fg='#ECF0F1', font=("Helvetica", 12, "bold"))
self.select_file_btn.pack(pady=10)

self.file_label = Label(self.root, text="No file selected")
self.file_label = Label(self.root, text="No file selected", bg='#2C3E50', fg='#ECF0F1')
self.file_label.pack()

def load_file(self):
Expand All @@ -75,36 +87,52 @@ def load_file(self):
self.log_file,
sep=r'\s+',
names=['Timestamp', 'Bus', 'ID', 'DLC', 'Data'],
dtype={'ID': str, 'Data': str} # Ensure ID and Data are read as strings
dtype={'ID': str, 'Data': str}, # Ensure ID and Data are read as strings
engine='python'
)
self.df['Timestamp'] = self.df['Timestamp'].astype(float)
self.split_data_column()
self.file_label.config(text=f"Loaded file: {self.log_file}")
self.create_signal_selection_window()
except Exception as e:
logging.error(f"Failed to load file: {e}")
messagebox.showerror("Error", f"Failed to load file: {e}")
else:
self.file_label.config(text="No file selected")

def split_data_column(self):
"""Split the 'Data' column into individual byte columns."""
try:
data_split = self.df['Data'].str.split(' ', expand=True)
# Ensure there are 8 bytes by padding with NaN if there are fewer than 8 columns
data_split = data_split.reindex(columns=range(8), fill_value=float('nan'))
for i in range(8):
self.df[f'Byte_{i}'] = pd.to_numeric(data_split[i], errors='coerce')
except Exception as e:
logging.error(f"Failed to split 'Data' column: {e}")
messagebox.showerror("Error", f"Failed to split 'Data' column: {e}")

def create_signal_selection_window(self):
"""Create the signal selection and plot customization window."""
self.clear_window()

self.id_label = Label(self.root, text="Select Signals to Plot:")
self.id_label = Label(self.root, text="Select Signals to Plot:", font=("Helvetica", 12, "bold"), bg='#2C3E50', fg='#ECF0F1')
self.id_label.pack()

self.signal_listbox = Listbox(self.root, selectmode=MULTIPLE)
self.signal_listbox = Listbox(self.root, selectmode=MULTIPLE, bg='#34495E', fg='#ECF0F1', font=("Helvetica", 10))
self.signal_listbox.pack(pady=5)

for can_id in self.df['ID'].unique():
# Populate the listbox with unique CAN IDs from the log file
for can_id in sorted(self.df['ID'].unique()):
self.signal_listbox.insert(END, can_id)

self.color_btn = Button(self.root, text="Choose Color", command=self.choose_color)
self.color_btn = Button(self.root, text="Choose Color", command=self.choose_color, bg='#3498DB', fg='#ECF0F1', font=("Helvetica", 10, "bold"))
self.color_btn.pack(pady=5)

self.plot_btn = Button(self.root, text="Plot Data", command=self.plot_data)
self.plot_btn = Button(self.root, text="Plot Data", command=self.plot_data, bg='#2ECC71', fg='#ECF0F1', font=("Helvetica", 10, "bold"))
self.plot_btn.pack(pady=10)

self.clear_btn = Button(self.root, text="Clear", command=self.clear_data)
self.clear_btn = Button(self.root, text="Clear", command=self.clear_data, bg='#E74C3C', fg='#ECF0F1', font=("Helvetica", 10, "bold"))
self.clear_btn.pack(pady=10)

def choose_color(self):
Expand All @@ -126,21 +154,26 @@ def plot_data(self):
messagebox.showwarning("File Error", "No file loaded")
return

plt.figure(figsize=(15, 8))
for signal in selected_signals:
df_filtered = self.df[self.df['ID'].str.strip().str.lower() == signal.lower()]
last_timestamp = self.df['Timestamp'].max()

fig, axs = plt.subplots(len(selected_signals), 1, figsize=(15, 8 * len(selected_signals)), sharex=True)
if len(selected_signals) == 1:
axs = [axs]

for ax, signal in zip(axs, selected_signals):
df_filtered = self.df[self.df['ID'].str.strip().str.upper() == signal.upper()]
if df_filtered.empty:
continue
color = self.colors.get(signal, None)
for i in range(8):
data_values = pd.to_numeric(df_filtered['Data'].str[i], errors='coerce').dropna()
plt.plot(df_filtered['Timestamp'].iloc[:len(data_values)], data_values, label=f'{signal} Byte {i}', color=color)
ax.plot(df_filtered['Timestamp'], df_filtered[f'Byte_{i}'], label=f'{signal} Byte {i}', color=color)
ax.set_ylabel('Data')
ax.set_title(f'CAN Data Plot for {signal}')
ax.set_xlim(0, last_timestamp)
ax.legend(loc='upper right')
ax.grid(True)

plt.xlabel('Timestamp')
plt.ylabel('Data')
plt.title('CAN Data Plot')
plt.legend(loc='upper right')
plt.grid(True)
plt.show()

def clear_data(self):
Expand Down

0 comments on commit 787f9c7

Please sign in to comment.