Listeners

Listener

The Listener class is an “abstract” base class for any objects which wish to register to receive notifications of new messages on the bus. A Listener can be used in two ways; the default is to call the Listener with a new message, or by calling the method on_message_received.

Listeners are registered with Notifier object(s) which ensure they are notified whenever a new message is received.

Subclasses of Listener that do not override on_message_received will cause NotImplementedError to be thrown when a message is received on the CAN bus.

class can.Listener[source]

Bases: object

The basic listener that can be called directly to handle some CAN message:

listener = SomeListener()
msg = my_bus.recv()

# now either call
listener(msg)
# or
listener.on_message_received(msg)

# Important to ensure all outputs are flushed
listener.stop()
on_error(exc)[source]

This method is called to handle any exception in the receive thread.

Parameters:exc (Exception) – The exception causing the thread to stop
on_message_received(msg)[source]

This method is called to handle the given message.

Parameters:msg (Message) – the delivered message
stop()[source]

Stop handling new messages, carry out any final tasks to ensure data is persisted and cleanup any open resources.

Concrete implementations override.

There are some listeners that already ship together with python-can and are listed below. Some of them allow messages to be written to files, and the corresponding file readers are also documented here.

Note

Please note that writing and the reading a message might not always yield a completely unchanged message again, since some properties are not (yet) supported by some file formats.

Note

Additional file formats for both reading/writing log files can be added via a plugin reader/writer. An external package can register a new reader by using the can.io.message_reader entry point. Similarly, a writer can be added using the can.io.message_writer entry point.

The format of the entry point is reader_name=module:classname where classname is a can.io.generic.BaseIOHandler concrete implementation.

entry_points={
    'can.io.message_reader': [
       '.asc = my_package.io.asc:ASCReader'
   ]
},

BufferedReader

class can.BufferedReader[source]

Bases: can.listener.Listener

A BufferedReader is a subclass of Listener which implements a message buffer: that is, when the can.BufferedReader instance is notified of a new message it pushes it into a queue of messages waiting to be serviced. The messages can then be fetched with get_message().

Putting in messages after stop() has been called will raise an exception, see on_message_received().

Attr bool is_stopped:
 True if the reader has been stopped
get_message(timeout=0.5)[source]

Attempts to retrieve the latest message received by the instance. If no message is available it blocks for given timeout or until a message is received, or else returns None (whichever is shorter). This method does not block after can.BufferedReader.stop() has been called.

Parameters:timeout (float) – The number of seconds to wait for a new message.
Return type:Optional[Message]
Returns:the Message if there is one, or None if there is not.
on_message_received(msg)[source]

Append a message to the buffer.

Raises:BufferError if the reader has already been stopped
stop()[source]

Prohibits any more additions to this reader.

class can.AsyncBufferedReader(loop=None)[source]

Bases: can.listener.Listener

A message buffer for use with asyncio.

See Asyncio support for how to use with can.Notifier.

Can also be used as an asynchronous iterator:

async for msg in reader:
    print(msg)
get_message()[source]

Retrieve the latest message when awaited for:

msg = await reader.get_message()
Return type:Message
Returns:The CAN message.
on_message_received(msg)[source]

Append a message to the buffer.

Must only be called inside an event loop!

RedirectReader

class can.RedirectReader(bus)[source]

Bases: can.listener.Listener

A RedirectReader sends all received messages to another Bus.

on_message_received(msg)[source]

This method is called to handle the given message.

Parameters:msg (Message) – the delivered message

Logger

The can.Logger uses the following can.Listener types to create log files with different file types of the messages received.

class can.Logger(file, mode='rt')[source]

Bases: can.io.generic.BaseIOHandler, can.listener.Listener

Logs CAN messages to a file.

The format is determined from the file format which can be one of:

The filename may also be None, to fall back to can.Printer.

The log files may be incomplete until stop() is called due to buffering.

Note

This class itself is just a dispatcher, and any positional and keyword arguments are passed on to the returned instance.

Parameters:
  • file (Union[Io[Any], str, Forwardref, None]) – a path-like object to open a file, a file-like object to be used as a file or None to not use a file at all
  • mode (str) – the mode that should be used to open the file, see open(), ignored if file is None

Printer

class can.Printer(file=None, append=False)[source]

Bases: can.io.generic.BaseIOHandler, can.listener.Listener

The Printer class is a subclass of Listener which simply prints any messages it receives to the terminal (stdout). A message is turned into a string using __str__().

Attr bool write_to_file:
 

True iff this instance prints to a file instead of standard out

Parameters:
  • file – an optional path-like object or as file-like object to “print” to instead of writing to standard out (stdout) If this is a file-like object, is has to opened in text write mode, not binary write mode.
  • append (bool) – if set to True messages are appended to the file, else the file is truncated
on_message_received(msg)[source]

This method is called to handle the given message.

Parameters:msg – the delivered message

CSVWriter

class can.CSVWriter(file, append=False)[source]

Bases: can.io.generic.BaseIOHandler, can.listener.Listener

Writes a comma separated text file with a line for each message. Includes a header line.

The columns are as follows:

name of column format description example
timestamp decimal float 1483389946.197
arbitration_id hex 0x00dadada
extended 1 == True, 0 == False 1
remote 1 == True, 0 == False 0
error 1 == True, 0 == False 0
dlc int 6
data base64 encoded WzQyLCA5XQ==

Each line is terminated with a platform specific line separator.

Parameters:
  • file – a path-like object or a file-like object to write to. If this is a file-like object, is has to open in text write mode, not binary write mode.
  • append (bool) – if set to True messages are appended to the file and no header line is written, else the file is truncated and starts with a newly written header line
on_message_received(msg)[source]

This method is called to handle the given message.

Parameters:msg – the delivered message
class can.CSVReader(file)[source]

Bases: can.io.generic.BaseIOHandler

Iterator over CAN messages from a .csv file that was generated by CSVWriter or that uses the same format as described there. Assumes that there is a header and thus skips the first line.

Any line separator is accepted.

Parameters:file – a path-like object or as file-like object to read from If this is a file-like object, is has to opened in text read mode, not binary read mode.

SqliteWriter

class can.SqliteWriter(file, table_name='messages')[source]

Bases: can.io.generic.BaseIOHandler, can.listener.BufferedReader

Logs received CAN data to a simple SQL database.

The sqlite database may already exist, otherwise it will be created when the first message arrives.

Messages are internally buffered and written to the SQL file in a background thread. Ensures that all messages that are added before calling stop() are actually written to the database after that call returns. Thus, calling stop() may take a while.

Attr str table_name:
 the name of the database table used for storing the messages
Attr int num_frames:
 the number of frames actually written to the database, this excludes messages that are still buffered
Attr float last_write:
 the last time a message war actually written to the database, as given by time.time()

Note

When the listener’s stop() method is called the thread writing to the database will continue to receive and internally buffer messages if they continue to arrive before the GET_MESSAGE_TIMEOUT.

If the GET_MESSAGE_TIMEOUT expires before a message is received, the internal buffer is written out to the database file.

However if the bus is still saturated with messages, the Listener will continue receiving until the MAX_TIME_BETWEEN_WRITES timeout is reached or more than MAX_BUFFER_SIZE_BEFORE_WRITES messages are buffered.

Note

The database schema is given in the documentation of the loggers.

Parameters:
  • file – a str or since Python 3.7 a path like object that points to the database file to use
  • table_name (str) – the name of the table to store messages in

Warning

In contrary to all other readers/writers the Sqlite handlers do not accept file-like objects as the file parameter.

GET_MESSAGE_TIMEOUT = 0.25

Number of seconds to wait for messages from internal queue

MAX_BUFFER_SIZE_BEFORE_WRITES = 500

Maximum number of messages to buffer before writing to the database

MAX_TIME_BETWEEN_WRITES = 5.0

Maximum number of seconds to wait between writes to the database

stop()[source]

Stops the reader an writes all remaining messages to the database. Thus, this might take a while and block.

class can.SqliteReader(file, table_name='messages')[source]

Bases: can.io.generic.BaseIOHandler

Reads recorded CAN messages from a simple SQL database.

This class can be iterated over or used to fetch all messages in the database with read_all().

Calling len() on this object might not run in constant time.

Attr str table_name:
 the name of the database table used for storing the messages

Note

The database schema is given in the documentation of the loggers.

Parameters:
  • file – a str or since Python 3.7 a path like object that points to the database file to use
  • table_name (str) – the name of the table to look for the messages

Warning

In contrary to all other readers/writers the Sqlite handlers do not accept file-like objects as the file parameter. It also runs in append=True mode all the time.

read_all()[source]

Fetches all messages in the database.

Return type:Generator[can.Message]
stop()[source]

Closes the connection to the database.

Database table format

The messages are written to the table messages in the sqlite database by default. The table is created if it does not already exist.

The entries are as follows:

Name Data type Note
ts REAL The timestamp of the message
arbitration_id INTEGER The arbitration id, might use the extended format
extended INTEGER 1 if the arbitration id uses the extended format, else 0
remote INTEGER 1 if the message is a remote frame, else 0
error INTEGER 1 if the message is an error frame, else 0
dlc INTEGER The data length code (DLC)
data BLOB The content of the message

ASC (.asc Logging format)

ASCWriter logs CAN data to an ASCII log file compatible with other CAN tools such as Vector CANalyzer/CANoe and other. Since no official specification exists for the format, it has been reverse- engineered from existing log files. One description of the format can be found here.

Note

Channels will be converted to integers.

class can.ASCWriter(file, channel=1)[source]

Bases: can.io.generic.BaseIOHandler, can.listener.Listener

Logs CAN data to an ASCII log file (.asc).

The measurement starts with the timestamp of the first registered message. If a message has a timestamp smaller than the previous one or None, it gets assigned the timestamp that was written for the last message. It the first message does not have a timestamp, it is set to zero.

Parameters:
  • file (Union[Io[Any], str, Forwardref]) – a path-like object or as file-like object to write to If this is a file-like object, is has to opened in text write mode, not binary write mode.
  • channel (int) – a default channel to use when the message does not have a channel set
log_event(message, timestamp=None)[source]

Add a message to the log file.

Parameters:
  • message (str) – an arbitrary message
  • timestamp (Optional[float]) – the absolute timestamp of the event
Return type:

None

on_message_received(msg)[source]

This method is called to handle the given message.

Parameters:msg (Message) – the delivered message
Return type:None
stop()[source]

Closes the undelying file-like object and flushes it, if it was opened in write mode.

Return type:None

ASCReader reads CAN data from ASCII log files .asc, as further references can-utils can be used: asc2log, log2asc.

class can.ASCReader(file, base='hex')[source]

Bases: can.io.generic.BaseIOHandler

Iterator of CAN messages from a ASC logging file. Meta data (comments, bus statistics, J1939 Transport Protocol messages) is ignored.

TODO: turn relative timestamps back to absolute form

Parameters:
  • file (Union[Io[Any], str, Forwardref]) – a path-like object or as file-like object to read from If this is a file-like object, is has to opened in text read mode, not binary read mode.
  • base (str) – Select the base(hex or dec) of id and data. If the header of the asc file contains base information, this value will be overwritten. Default “hex”.

Log (.log can-utils Logging format)

CanutilsLogWriter logs CAN data to an ASCII log file compatible with can-utils <https://github.com/linux-can/can-utils> As specification following references can-utils can be used: asc2log, log2asc.

class can.CanutilsLogWriter(file, channel='vcan0', append=False)[source]

Bases: can.io.generic.BaseIOHandler, can.listener.Listener

Logs CAN data to an ASCII log file (.log). This class is is compatible with “candump -L”.

If a message has a timestamp smaller than the previous one (or 0 or None), it gets assigned the timestamp that was written for the last message. It the first message does not have a timestamp, it is set to zero.

Parameters:
  • file – a path-like object or as file-like object to write to If this is a file-like object, is has to opened in text write mode, not binary write mode.
  • channel – a default channel to use when the message does not have a channel set
  • append (bool) – if set to True messages are appended to the file, else the file is truncated
on_message_received(msg)[source]

This method is called to handle the given message.

Parameters:msg – the delivered message

CanutilsLogReader reads CAN data from ASCII log files .log

class can.CanutilsLogReader(file)[source]

Bases: can.io.generic.BaseIOHandler

Iterator over CAN messages from a .log Logging File (candump -L).

Note

.log-format looks for example like this:

(0.0) vcan0 001#8d00100100820100

Parameters:file – a path-like object or as file-like object to read from If this is a file-like object, is has to opened in text read mode, not binary read mode.

BLF (Binary Logging Format)

Implements support for BLF (Binary Logging Format) which is a proprietary CAN log format from Vector Informatik GmbH.

The data is stored in a compressed format which makes it very compact.

Note

Channels will be converted to integers.

class can.BLFWriter(file, append=False, channel=1, compression_level=-1)[source]

Bases: can.io.generic.BaseIOHandler, can.listener.Listener

Logs CAN data to a Binary Logging File compatible with Vector’s tools.

Parameters:
  • file – a path-like object or as file-like object to write to If this is a file-like object, is has to opened in mode “wb+”.
  • channel (int) – Default channel to log as if not specified by the interface.
  • append (bool) – Append messages to an existing log file.
  • compression_level (int) – An integer from 0 to 9 or -1 controlling the level of compression. 1 (Z_BEST_SPEED) is fastest and produces the least compression. 9 (Z_BEST_COMPRESSION) is slowest and produces the most. 0 means that data will be stored without processing. The default value is -1 (Z_DEFAULT_COMPRESSION). Z_DEFAULT_COMPRESSION represents a default compromise between speed and compression (currently equivalent to level 6).
application_id = 5

Application identifier for the log writer

log_event(text, timestamp=None)[source]

Add an arbitrary message to the log file as a global marker.

Parameters:
  • text (str) – The group name of the marker.
  • timestamp (float) – Absolute timestamp in Unix timestamp format. If not given, the marker will be placed along the last message.
max_container_size = 131072

Max log container size of uncompressed data

on_message_received(msg)[source]

This method is called to handle the given message.

Parameters:msg – the delivered message
stop()[source]

Stops logging and closes the file.

The following class can be used to read messages from BLF file:

class can.BLFReader(file)[source]

Bases: can.io.generic.BaseIOHandler

Iterator of CAN messages from a Binary Logging File.

Only CAN messages and error frames are supported. Other object types are silently ignored.

Parameters:file – a path-like object or as file-like object to read from If this is a file-like object, is has to opened in binary read mode, not text read mode.