From 44bf3de167d449a71af9d3e3f9e67d22a00051d6 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 12:12:05 +0100
Subject: [PATCH 01/12] Add format lookup map
---
can/io/trc.py | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/can/io/trc.py b/can/io/trc.py
index 2dbe3763c..cf1760fba 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -278,10 +278,12 @@ class TRCWriter(TextIOMessageWriter):
file: TextIO
first_timestamp: Optional[float]
- FORMAT_MESSAGE = (
- "{msgnr:>7} {time:13.3f} DT {channel:>2} {id:>8} {dir:>2} - {dlc:<4} {data}"
- )
- FORMAT_MESSAGE_V1_0 = "{msgnr:>6}) {time:7.0f} {id:>8} {dlc:<1} {data}"
+ MESSAGE_FORMAT_MAP: Mapping[TRCFileVersion, str] = {
+ TRCFileVersion.V1_0: "{msgnr:>6}) {time:7.0f} {id:>8} {dlc:<1} {data}",
+ TRCFileVersion.V2_1: (
+ "{msgnr:>7} {time:13.3f} DT {channel:>2} {id:>8} {dir:>2} - {dlc:<4} {data}"
+ ),
+ }
def __init__(
self,
@@ -309,7 +311,7 @@ def __init__(
self.msgnr = 0
self.first_timestamp = None
self.file_version = TRCFileVersion.V2_1
- self._msg_fmt_string = self.FORMAT_MESSAGE_V1_0
+ self._msg_fmt_string = self.MESSAGE_FORMAT_MAP[self.file_version]
self._format_message = self._format_message_init
def _write_header_v1_0(self, start_time: datetime) -> None:
@@ -381,13 +383,12 @@ def _format_message_by_format(self, msg, channel):
def _format_message_init(self, msg, channel):
if self.file_version == TRCFileVersion.V1_0:
self._format_message = self._format_message_by_format
- self._msg_fmt_string = self.FORMAT_MESSAGE_V1_0
elif self.file_version == TRCFileVersion.V2_1:
self._format_message = self._format_message_by_format
- self._msg_fmt_string = self.FORMAT_MESSAGE
else:
raise NotImplementedError("File format is not supported")
+ self._msg_fmt_string = self.MESSAGE_FORMAT_MAP[self.file_version]
return self._format_message_by_format(msg, channel)
def write_header(self, timestamp: float) -> None:
From e99bc00f4635cc324915ae88fe3029f696111d64 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 12:23:09 +0100
Subject: [PATCH 02/12] Remove format message init stuff
---
can/io/trc.py | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/can/io/trc.py b/can/io/trc.py
index cf1760fba..f1ac74052 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -312,7 +312,6 @@ def __init__(
self.first_timestamp = None
self.file_version = TRCFileVersion.V2_1
self._msg_fmt_string = self.MESSAGE_FORMAT_MAP[self.file_version]
- self._format_message = self._format_message_init
def _write_header_v1_0(self, start_time: datetime) -> None:
lines = [
@@ -361,7 +360,7 @@ def _write_header_v2_1(self, start_time: datetime) -> None:
]
self.file.writelines(line + "\n" for line in lines)
- def _format_message_by_format(self, msg, channel):
+ def _format_message(self, msg, channel):
if msg.is_extended_id:
arb_id = f"{msg.arbitration_id:07X}"
else:
@@ -380,17 +379,6 @@ def _format_message_by_format(self, msg, channel):
)
return serialized
- def _format_message_init(self, msg, channel):
- if self.file_version == TRCFileVersion.V1_0:
- self._format_message = self._format_message_by_format
- elif self.file_version == TRCFileVersion.V2_1:
- self._format_message = self._format_message_by_format
- else:
- raise NotImplementedError("File format is not supported")
-
- self._msg_fmt_string = self.MESSAGE_FORMAT_MAP[self.file_version]
- return self._format_message_by_format(msg, channel)
-
def write_header(self, timestamp: float) -> None:
# write start of file header
start_time = datetime.fromtimestamp(timestamp, timezone.utc)
From 132a93d4468578344f46d45f9cce1219e6a6f17d Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 12:28:05 +0100
Subject: [PATCH 03/12] Add function for setup of file version
---
can/io/trc.py | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/can/io/trc.py b/can/io/trc.py
index f1ac74052..01126bfd1 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -310,8 +310,15 @@ def __init__(
self.header_written = False
self.msgnr = 0
self.first_timestamp = None
- self.file_version = TRCFileVersion.V2_1
- self._msg_fmt_string = self.MESSAGE_FORMAT_MAP[self.file_version]
+ self._setup_file_version(TRCFileVersion.V2_1)
+
+ def _setup_file_version(self, file_version: Union[int, TRCFileVersion]):
+ try:
+ self.file_version = TRCFileVersion(file_version)
+ self._msg_fmt_string = self.MESSAGE_FORMAT_MAP[self.file_version]
+ except (KeyError, ValueError) as exc:
+ err_msg = f"File version is not supported: {file_version}"
+ raise NotImplementedError(err_msg) from exc
def _write_header_v1_0(self, start_time: datetime) -> None:
lines = [
From 406b278aedad48df7dcbc08ac0c8f600fd6d0c59 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 12:29:28 +0100
Subject: [PATCH 04/12] Add file version as init parameter
---
can/io/trc.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/can/io/trc.py b/can/io/trc.py
index 01126bfd1..7f9ff9db8 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -289,6 +289,7 @@ def __init__(
self,
file: Union[StringPathLike, TextIO],
channel: int = 1,
+ file_version: Union[int, TRCFileVersion] = TRCFileVersion.V2_1,
**kwargs: Any,
) -> None:
"""
@@ -310,7 +311,7 @@ def __init__(
self.header_written = False
self.msgnr = 0
self.first_timestamp = None
- self._setup_file_version(TRCFileVersion.V2_1)
+ self._setup_file_version(file_version)
def _setup_file_version(self, file_version: Union[int, TRCFileVersion]):
try:
From e736744285864578bbdd03a6763d21979fe95ed8 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 12:30:29 +0100
Subject: [PATCH 05/12] Add missing import
---
can/io/trc.py | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/can/io/trc.py b/can/io/trc.py
index 7f9ff9db8..c2a647521 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -11,7 +11,17 @@
import os
from datetime import datetime, timedelta, timezone
from enum import Enum
-from typing import Any, Callable, Dict, Generator, Optional, TextIO, Tuple, Union
+from typing import (
+ Any,
+ Callable,
+ Dict,
+ Generator,
+ Mapping,
+ Optional,
+ TextIO,
+ Tuple,
+ Union,
+)
from ..message import Message
from ..typechecking import StringPathLike
From 39f3c8f534b7b7387e8928ee55f6d2c648ebf829 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 12:35:07 +0100
Subject: [PATCH 06/12] Add type hints for format message
---
can/io/trc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/can/io/trc.py b/can/io/trc.py
index c2a647521..e11767cbc 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -378,7 +378,7 @@ def _write_header_v2_1(self, start_time: datetime) -> None:
]
self.file.writelines(line + "\n" for line in lines)
- def _format_message(self, msg, channel):
+ def _format_message(self, msg: Message, channel: int) -> str:
if msg.is_extended_id:
arb_id = f"{msg.arbitration_id:07X}"
else:
From 61923083439856d482b76c3490fd50e1b47274e8 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 12:38:00 +0100
Subject: [PATCH 07/12] Add docstring for new parameter
---
can/io/trc.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/can/io/trc.py b/can/io/trc.py
index e11767cbc..970292c11 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -308,6 +308,7 @@ def __init__(
write mode, not binary write mode.
:param channel: a default channel to use when the message does not
have a channel set
+ :param file_version: the trc file format version. Version 2.1 by default
"""
super().__init__(file, mode="w")
self.channel = channel
From 39e8a01c6c146acaa1265297c0d6765f7c8b4881 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 13:06:45 +0100
Subject: [PATCH 08/12] Fix test case for expicit file version
---
test/logformats_test.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/test/logformats_test.py b/test/logformats_test.py
index a2fd0fe09..e48cb6f83 100644
--- a/test/logformats_test.py
+++ b/test/logformats_test.py
@@ -1058,8 +1058,7 @@ class TestTrcFileFormatV1_0(TestTrcFileFormatBase):
@staticmethod
def Writer(filename):
- writer = can.TRCWriter(filename)
- writer.file_version = can.TRCFileVersion.V1_0
+ writer = can.TRCWriter(filename, file_version=can.TRCFileVersion.V1_0)
return writer
def _setup_instance(self):
From d69601849ac0852e522e62e041d141b592ca36b9 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 13:11:44 +0100
Subject: [PATCH 09/12] Add None handling for first_timestamp
---
can/io/trc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/can/io/trc.py b/can/io/trc.py
index 970292c11..0e5235598 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -389,7 +389,7 @@ def _format_message(self, msg: Message, channel: int) -> str:
serialized = self._msg_fmt_string.format(
msgnr=self.msgnr,
- time=(msg.timestamp - self.first_timestamp) * 1000,
+ time=(msg.timestamp - (self.first_timestamp or 0.0)) * 1000,
channel=channel,
id=arb_id,
dir="Rx" if msg.is_rx else "Tx",
From e4efeb2ebd008e58a152b4a83d45704666f2eee0 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 13:12:19 +0100
Subject: [PATCH 10/12] Add return type hint
---
can/io/trc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/can/io/trc.py b/can/io/trc.py
index 0e5235598..9671fa1f6 100644
--- a/can/io/trc.py
+++ b/can/io/trc.py
@@ -324,7 +324,7 @@ def __init__(
self.first_timestamp = None
self._setup_file_version(file_version)
- def _setup_file_version(self, file_version: Union[int, TRCFileVersion]):
+ def _setup_file_version(self, file_version: Union[int, TRCFileVersion]) -> None:
try:
self.file_version = TRCFileVersion(file_version)
self._msg_fmt_string = self.MESSAGE_FORMAT_MAP[self.file_version]
From 5a142c2f313dd159a625502df8dff0cbf1639bb9 Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 18:25:16 +0100
Subject: [PATCH 11/12] Add documentation for TRCFileVersion
---
doc/file_io.rst | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/doc/file_io.rst b/doc/file_io.rst
index ff9431695..7911a5785 100644
--- a/doc/file_io.rst
+++ b/doc/file_io.rst
@@ -184,6 +184,14 @@ The following class can be used to read messages from TRC file:
:members:
+The following enum can be used during creation of a TRC file with :ref:`TRCWriter` to select a specific file version:
+
+.. autoclass:: can.TRCFileVersion
+ :show-inheritance:
+ :members:
+ :undoc-members:
+
+
Rotating Loggers
----------------
From 2c9019eb74076991736a1d76e54348a870e46fee Mon Sep 17 00:00:00 2001
From: Peter Kessen
Date: Sun, 23 Feb 2025 18:27:35 +0100
Subject: [PATCH 12/12] Fix ref
---
doc/file_io.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/file_io.rst b/doc/file_io.rst
index 7911a5785..5189c6598 100644
--- a/doc/file_io.rst
+++ b/doc/file_io.rst
@@ -184,7 +184,7 @@ The following class can be used to read messages from TRC file:
:members:
-The following enum can be used during creation of a TRC file with :ref:`TRCWriter` to select a specific file version:
+The following enum can be used during creation of a TRC file with `TRCWriter` to select a specific file version:
.. autoclass:: can.TRCFileVersion
:show-inheritance: