Skip to content

Commit bc66b57

Browse files
committed
Add preserve timestamps to virtual
Add an option to virtual interfaces to preserve message timestamps on transmissions. This is useful in test setups fed by log files.
1 parent 78f86f3 commit bc66b57

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

can/interfaces/virtual.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def __init__(
5959
channel: Any = None,
6060
receive_own_messages: bool = False,
6161
rx_queue_size: int = 0,
62+
preserve_timestamps: bool = False,
6263
**kwargs: Any,
6364
) -> None:
6465
super().__init__(
@@ -69,6 +70,7 @@ def __init__(
6970
self.channel_id = channel
7071
self.channel_info = f"Virtual bus channel {self.channel_id}"
7172
self.receive_own_messages = receive_own_messages
73+
self.preserve_timestamps = preserve_timestamps
7274
self._open = True
7375

7476
with channels_lock:
@@ -103,7 +105,7 @@ def _recv_internal(
103105
def send(self, msg: Message, timeout: Optional[float] = None) -> None:
104106
self._check_if_open()
105107

106-
timestamp = time.time()
108+
timestamp = msg.timestamp if self.preserve_timestamps else time.time()
107109
# Add message to all listening on this channel
108110
all_sent = True
109111
for bus_queue in self.channel:

doc/interfaces/virtual.rst

+28-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ Example
8585
-------
8686

8787
.. code-block:: python
88-
88+
8989
import can
9090
9191
bus1 = can.interface.Bus('test', bustype='virtual')
@@ -100,6 +100,33 @@ Example
100100
assert msg1.data == msg2.data
101101
assert msg1.timestamp != msg2.timestamp
102102
103+
.. code-block:: python
104+
105+
import can
106+
107+
bus1 = can.interface.Bus('test', bustype='virtual', preserve_timestamps=True)
108+
bus2 = can.interface.Bus('test', bustype='virtual')
109+
110+
msg1 = can.Message(timestamp=1639740470.051948, arbitration_id=0xabcde, data=[1,2,3])
111+
112+
# Messages sent on bus1 will have their timestamps preserved when received
113+
# on bus2
114+
bus1.send(msg1)
115+
msg2 = bus2.recv()
116+
117+
assert msg1.arbitration_id == msg2.arbitration_id
118+
assert msg1.data == msg2.data
119+
assert msg1.timestamp == msg2.timestamp
120+
121+
# Messages sent on bus2 will not have their timestamps preserved when
122+
# received on bus1
123+
bus2.send(msg1)
124+
msg3 = bus1.recv()
125+
126+
assert msg1.arbitration_id == msg3.arbitration_id
127+
assert msg1.data == msg3.data
128+
assert msg1.timestamp != msg3.timestamp
129+
103130
104131
Bus Class Documentation
105132
-----------------------

test/test_interface_virtual.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python
2+
# coding: utf-8
3+
4+
"""
5+
This module tests :meth:`can.interface.virtual`.
6+
"""
7+
8+
import unittest
9+
10+
from can import Bus, Message
11+
12+
EXAMPLE_MSG1 = Message(timestamp=1639739471.5565314, arbitration_id=0x481, data=b"\x01")
13+
14+
15+
class TestMessageFiltering(unittest.TestCase):
16+
def setUp(self):
17+
self.node1 = Bus("test", bustype="virtual", preserve_timestamps=True)
18+
self.node2 = Bus("test", bustype="virtual")
19+
20+
def tearDown(self):
21+
self.node1.shutdown()
22+
self.node2.shutdown()
23+
24+
def test_sendmsg(self):
25+
self.node2.send(EXAMPLE_MSG1)
26+
r = self.node1.recv(0.1)
27+
assert r.timestamp != EXAMPLE_MSG1.timestamp
28+
assert r.arbitration_id == EXAMPLE_MSG1.arbitration_id
29+
assert r.data == EXAMPLE_MSG1.data
30+
31+
def test_sendmsg_preserve_timestamp(self):
32+
self.node1.send(EXAMPLE_MSG1)
33+
r = self.node2.recv(0.1)
34+
assert r.timestamp == EXAMPLE_MSG1.timestamp
35+
assert r.arbitration_id == EXAMPLE_MSG1.arbitration_id
36+
assert r.data == EXAMPLE_MSG1.data
37+
38+
39+
if __name__ == "__main__":
40+
unittest.main()

0 commit comments

Comments
 (0)