serialtools.database module

class serialtools.database.ByteSpec(name: str, *, length: int | str | None = None, allowed_values: Sequence[bytes] | bytes | int | None = None)

Bases: object

Paramref length:

Either the number of bytes or the name of a previous byte spec which specifies the length of this byte spec

format_allowed_values() str
get_length(values: Mapping[str, bytes]) int
class serialtools.database.Database(message_spec: MessageSpec, signals: Sequence[Signal], *, endianness: Endianness, word_length_in_bits: int = 8)

Bases: object

decode(address: int, data: bytes) dict[Signal, float]
encode(data: Mapping[Signal, int | float | str] | Mapping[str, int | float | str]) bytes
encode_range(address: int, length_in_bytes: int, value: Callable[[Signal], int | float | str]) bytes

Encode all signals which are completely within the given range

endianness: Endianness

The byte order

get_endianness_fmt() str
get_signal(name: str) Signal
get_start_bit(signal: Signal) int
message_spec: MessageSpec

The parts that a message consists of, e.g. an address to be read, the length of the data, the data itself

signals: Sequence[Signal]

The possible signals which can be encoded in the data

word_length_in_bits: int

The default length of a signal

class serialtools.database.Endianness(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

BIG = 1
LITTLE = 2
class serialtools.database.Message(db: Database, timestamp: datetime | None, values: Mapping[str, bytes])

Bases: object

decode() Mapping[Signal, int | float | bool | str]
format() str
format_raw() str
format_raw_data() str
format_timestamp() str
class serialtools.database.MessageSpec(params: Sequence[ByteSpec], *, implicit_address: int | None = None)

Bases: object

ADDRESS = 'address'
class serialtools.database.Reader(bus: serial.Serial | ReadFromFileBus | WriteToFileBus, db: Database, *, config_id: ConfigId | None = None)

Bases: object

ignore_bytes_between_messages

A setting which can have different values for different objects.

This class implements the descriptor protocol to return one of the values in values depending on a config_id attribute of the owning object if an instance of this class is accessed as an instance attribute. If there is no value for the config_id in values value is returned instead. If the owning instance does not have a config_id attribute an AttributeError is raised.

In the config file a group can be opened with [config-id]. Then all following set commands set the value for the specified config id.

log_raw_received_bytes(fn: str) None

write all received bytes to a log file

This log file can be read with an object created with:

from serialtools.bus import bus_creator
bus = bus_creator.create_bus(create_bus.create_args(port=fn, rx_only=True))
Parameters:

fn – file name, where to log the received bytes

read() Iterator[Message]
read_byte() int

Receive one byte

Returns:

The received byte

Raises:

TimeoutError – If nothing has been received within the time frame passed as timeout when creating the bus

read_in_other_thread(callback: Callable[[Message], None]) None
read_msg() Message | None
read_n_bytes(n: int) bytes

Receive exactly n bytes

Parameters:

n – Number of bytes to read

Returns:

The received bytes

Raises:
  • EOFError – If stop() has been called

  • TimeoutError – If less than n bytes have been received within the time frame passed as timeout when creating the bus

read_up_to_n_bytes(n: int) bytes

Receive up to n bytes

Parameters:

n – Number of bytes to read

Returns:

The received bytes, may be less than n

Raises:

EOFError – If stop() has been called

retry_byte(b: int) None
send_msg(msg: Message) None
stop() None
timeout

A setting which can have different values for different objects.

This class implements the descriptor protocol to return one of the values in values depending on a config_id attribute of the owning object if an instance of this class is accessed as an instance attribute. If there is no value for the config_id in values value is returned instead. If the owning instance does not have a config_id attribute an AttributeError is raised.

In the config file a group can be opened with [config-id]. Then all following set commands set the value for the specified config id.

class serialtools.database.Signal(name: str, type: Type, address: int, *, bits: int | None = None, startbit: int | None = None, lsb: int | None = None, scale: float = 1, offset: float = 0, unit: str = '')

Bases: object

Paramref name:

The name of the signal

Paramref type:

The data type, e.g. INT, UINT, FLOAT

Paramref address:

The address which is used to request this value from the battery

Paramref bits:

The size of this signal in bits, defaults to Database.word_length_in_bits

Paramref startbit:

If the word identified by address contains several smaller values the startbit specifies the first transmitted bit in the word belonging to the signal. Bit 0 is the first bit transmitted, not the least significant bit.

Paramref lsb:

If the word identified by address contains several smaller values the lsb specifies where the list significant bit of the signal is inside of the word. startbit and lsb are mutually exclusive, only one of them may be passed.

Paramref scale:

A factor which is multiplied to the raw value received on the bus in order to get a value of unit

Paramref offset:

A summand which is added to the raw value received on the bus in order to get a value of unit

Paramref unit:

The unit of the value

When decoding data from bytes received on the bus to human readable floats in the given unit the raw value is first multiplied with scale and then offset is added to it as in cantools.

get_bitstruct_fmt() str
init(db: Database) None
class serialtools.database.Type(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

BOOL = 'b'
FLOAT = 'f'
INT = 's'
TEXT = 't'
UINT = 'u'
serialtools.database.format_bytes(data: bytes) str