Virtual#

The virtual interface can be used as a way to write OS and driver independent tests. Any VirtualBus instances connecting to the same channel (from within the same Python process) will receive each others messages.

If messages shall be sent across process or host borders, consider using the Multicast IP Interface and refer to Virtual Interfaces for a comparison and general discussion of different virtual interfaces.

Example#

import can

bus1 = can.interface.Bus('test', interface='virtual')
bus2 = can.interface.Bus('test', interface='virtual')

msg1 = can.Message(arbitration_id=0xabcde, data=[1,2,3])
bus1.send(msg1)
msg2 = bus2.recv()

#assert msg1 == msg2
assert msg1.arbitration_id == msg2.arbitration_id
assert msg1.data == msg2.data
assert msg1.timestamp != msg2.timestamp
import can

bus1 = can.interface.Bus('test', interface='virtual', preserve_timestamps=True)
bus2 = can.interface.Bus('test', interface='virtual')

msg1 = can.Message(timestamp=1639740470.051948, arbitration_id=0xabcde, data=[1,2,3])

# Messages sent on bus1 will have their timestamps preserved when received
# on bus2
bus1.send(msg1)
msg2 = bus2.recv()

assert msg1.arbitration_id == msg2.arbitration_id
assert msg1.data == msg2.data
assert msg1.timestamp == msg2.timestamp

# Messages sent on bus2 will not have their timestamps preserved when
# received on bus1
bus2.send(msg1)
msg3 = bus1.recv()

assert msg1.arbitration_id == msg3.arbitration_id
assert msg1.data == msg3.data
assert msg1.timestamp != msg3.timestamp

Bus Class Documentation#

class can.interfaces.virtual.VirtualBus(channel=None, receive_own_messages=False, rx_queue_size=0, preserve_timestamps=False, protocol=CanProtocol.CAN_20, **kwargs)[source]#

A virtual CAN bus using an internal message queue. It can be used for example for testing.

In this interface, a channel is an arbitrary object used as an identifier for connected buses.

Implements can.BusABC._detect_available_configs(); see _detect_available_configs() for how it behaves here.

Note

The timeout when sending a message applies to each receiver individually. This means that sending can block up to 5 seconds if a message is sent to 5 receivers with the timeout set to 1.0.

Warning

This interface guarantees reliable delivery and message ordering, but does not implement rate limiting or ID arbitration/prioritization under high loads. Please refer to the section Virtual Interfaces for more information on this and a comparison to alternatives.

The constructed instance has access to the bus identified by the channel parameter. It is able to see all messages transmitted on the bus by virtual instances constructed with the same channel identifier.

Parameters:
  • channel (Any) – The channel identifier. This parameter can be an arbitrary value. The bus instance will be able to see messages from other virtual bus instances that were created with the same value.

  • receive_own_messages (bool) – If set to True, sent messages will be reflected back on the input queue.

  • rx_queue_size (int) – The size of the reception queue. The reception queue stores messages until they are read. If the queue reaches its capacity, it will start dropping the oldest messages to make room for new ones. If set to 0, the queue has an infinite capacity. Be aware that this can cause memory leaks if messages are read with a lower frequency than they arrive on the bus.

  • preserve_timestamps (bool) – If set to True, messages transmitted via send() will keep the timestamp set in the Message instance. Otherwise, the timestamp value will be replaced with the current system time.

  • protocol (CanProtocol) – The protocol implemented by this bus instance. The value does not affect the operation of the bus instance and can be set to an arbitrary value for testing purposes.

  • kwargs (Any) – Additional keyword arguments passed to the parent constructor.

static _detect_available_configs()[source]#

Returns all currently used channels as well as one other currently unused channel.

Note

This method will run into problems if thousands of autodetected buses are used at once.

Return type:

List[AutoDetectedConfig]

send(msg, timeout=None)[source]#

Transmit a message to the CAN bus.

Override this method to enable the transmit path.

Parameters:
  • msg (Message) – A message object.

  • timeout (float | None) – If > 0, wait up to this many seconds for message to be ACK’ed or for transmit queue to be ready depending on driver implementation. If timeout is exceeded, an exception will be raised. Might not be supported by all interfaces. None blocks indefinitely.

Raises:

CanOperationError – If an error occurred while sending

Return type:

None

shutdown()[source]#

Called to carry out any interface specific cleanup required in shutting down a bus.

This method can be safely called multiple times.

Return type:

None