import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import can
import csv
import threading
import os
class BLFConverterApp:
def __init__(self, root):
self.root = root
self.root.title("BLF to CSV Converter")
# File selection
self.file_path_var = tk.StringVar()
self.file_path_entry = tk.Entry(root, textvariable=self.file_path_var, width=50)
self.file_path_entry.grid(row=0, column=0, padx=10, pady=10)
self.browse_button = tk.Button(root, text="Browse", command=self.browse_file)
self.browse_button.grid(row=0, column=1, padx=10, pady=10)
# Progress bar
self.progress_var = tk.DoubleVar()
self.progress_bar = ttk.Progressbar(root, variable=self.progress_var, maximum=100)
self.progress_bar.grid(row=1, column=0, columnspan=2, padx=10, pady=10)
# Start conversion button
self.start_button = tk.Button(root, text="Start Conversion", command=self.start_conversion)
self.start_button.grid(row=2, column=0, columnspan=2, padx=10, pady=10)
def browse_file(self):
file_path = filedialog.askopenfilename(filetypes=[("BLF files", "*.blf")])
if file_path:
self.file_path_var.set(file_path)
def start_conversion(self):
blf_file = self.file_path_var.get()
if not os.path.exists(blf_file):
messagebox.showerror("Error", "File not found!")
return
csv_file = filedialog.asksaveasfilename(defaultextension=".csv", filetypes=[("CSV files", "*.csv")])
if not csv_file:
return
self.progress_var.set(0)
threading.Thread(target=self.blf_to_csv, args=(blf_file, csv_file)).start()
def blf_to_csv(self, blf_file, csv_file):
try:
# First pass to count the total number of frames
total_frames = 0
with can.BLFReader(blf_file) as log:
for _ in log:
total_frames += 1
# Second pass to read and write frames
with can.BLFReader(blf_file) as log:
with open(csv_file, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow([
'Timestamp', 'CAN ID', 'DLC', 'Data', 'Channel', 'Direction',
'Frame Type', 'Error Frame', 'Remote Frame', 'Extended ID',
'Bitrate Switch', 'Error State Indicator'
])
for i, msg in enumerate(log):
timestamp = msg.timestamp
can_id = msg.arbitration_id
dlc = msg.dlc
data = ' '.join(format(byte, '02x') for byte in msg.data)
channel = msg.channel
direction = 'Rx' if msg.is_rx else 'Tx'
frame_type = 'CAN FD' if msg.is_fd else 'CAN'
error_frame = msg.is_error_frame
remote_frame = msg.is_remote_frame
extended_id = msg.is_extended_id
bitrate_switch = msg.bitrate_switch
error_state_indicator = msg.error_state_indicator
writer.writerow([
timestamp, can_id, dlc, data, channel, direction,
frame_type, error_frame, remote_frame, extended_id,
bitrate_switch, error_state_indicator
])
# Update progress
self.progress_var.set((i + 1) / total_frames * 100)
self.root.update_idletasks()
messagebox.showinfo("Success", "Conversion complete!")
except Exception as e:
messagebox.showerror("Error", f"An error occurred: {e}")
if __name__ == "__main__":
root = tk.Tk()
app = BLFConverterApp(root)
root.mainloop()
最后修改:2024 年 06 月 13 日
© 允许规范转载