From 6f22a9530cccae433a399fd7fcbe3f1e7a585987 Mon Sep 17 00:00:00 2001 From: Erick Ahmed Date: Mon, 6 Jul 2026 16:01:14 +0200 Subject: [PATCH] Add simple parser for bxcanlogger project - Takes text input and parses it to a csv --- parser.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 parser.py diff --git a/parser.py b/parser.py new file mode 100644 index 0000000..c68310a --- /dev/null +++ b/parser.py @@ -0,0 +1,67 @@ +import re +import csv +from pathlib import Path + +def parse_can_log(input_path: str | Path, out_bus1: str | Path, out_bus2: str | Path) -> None: + """ + Parses a CAN bus log file and saves valid frames to separate CSV files for Bus 1 and Bus 2. + Corrupted, incomplete, or debug frames are silently discarded. + """ + input_file = Path(input_path) + out1_file = Path(out_bus1) + out2_file = Path(out_bus2) + + # Group 1: Bus (C1 or C2) + # Group 2: ID (1 to 8 hex chars) + # Group 3: DLC (1 to 2 hex chars) + start_pattern = re.compile(r'(C[12]):([0-9A-Fa-f]{1,8})\s+([0-9A-Fa-f]{1,2})\s+') + + byte_pattern = re.compile(r'^[0-9A-Fa-f]{2}$') + + with input_file.open('r', encoding='utf-8') as f_in, \ + out1_file.open('w', newline='', encoding='utf-8') as f_out1, \ + out2_file.open('w', newline='', encoding='utf-8') as f_out2: + + writer1 = csv.writer(f_out1) + writer2 = csv.writer(f_out2) + + writer1.writerow(['ID', 'DLC', 'Data']) + writer2.writerow(['ID', 'DLC', 'Data']) + + for line in f_in: + for match in start_pattern.finditer(line): + bus = match.group(1) + can_id = match.group(2).upper() + dlc_str = match.group(3) + + try: + dlc = int(dlc_str, 16) + except ValueError: + continue + + if dlc > 8: + continue + + remaining = line[match.end():] + tokens = remaining.split() + + data_bytes = [] + for token in tokens: + if byte_pattern.match(token): + data_bytes.append(token.upper()) + else: + break + + if len(data_bytes) == dlc: + data_str = ' '.join(data_bytes) + row = [can_id, dlc, data_str] + + if bus == 'C1': + writer1.writerow(row) + elif bus == 'C2': + writer2.writerow(row) + +if __name__ == '__main__': + # Example usage: + # parse_can_log('can_traffic.txt', 'bus1_output.csv', 'bus2_output.csv') + pass