Source code for cantools.database.diagnostics.data

# DID data.
from typing import Optional, Union

from ...typechecking import ByteOrder, Choices, SignalValueType
from ..can.signal import NamedSignalValue
from ..conversion import BaseConversion, IdentityConversion


[docs]class Data: """A data data with position, size, unit and other information. A data is part of a DID. """ def __init__(self, name: str, start: int, length: int, byte_order: ByteOrder = 'little_endian', conversion: Optional[BaseConversion] = None, minimum: Optional[float] = None, maximum: Optional[float] = None, unit: Optional[str] = None, ) -> None: #: The data name as a string. self.name: str = name #: The conversion instance, which is used to convert #: between raw and scaled/physical values. self.conversion = conversion or IdentityConversion(is_float=False) #: The start bit position of the data within its DID. self.start: int = start #: The length of the data in bits. self.length = length #: Data byte order as ``'little_endian'`` or ``'big_endian'``. self.byte_order: ByteOrder = byte_order #: The minimum value of the data, or ``None`` if unavailable. self.minimum: Optional[float] = minimum #: The maximum value of the data, or ``None`` if unavailable. self.maximum: Optional[float] = maximum #: The unit of the data as a string, or ``None`` if unavailable. self.unit = unit # ToDo: Remove once types are handled properly. self.is_signed: bool = False
[docs] def raw_to_scaled( self, raw_value: Union[int, float], decode_choices: bool = True ) -> SignalValueType: """Convert an internal raw value according to the defined scaling or value table. :param raw_value: The raw value :param decode_choices: If `decode_choices` is ``False`` scaled values are not converted to choice strings (if available). :return: The calculated scaled value """ return self.conversion.raw_to_scaled(raw_value, decode_choices)
[docs] def scaled_to_raw(self, scaled_value: SignalValueType) -> Union[int, float]: """Convert a scaled value to the internal raw value. :param scaled_value: The scaled value. :return: The internal raw value. """ return self.conversion.scaled_to_raw(scaled_value)
def choice_to_number(self, string: Union[str, NamedSignalValue]) -> int: try: return self.conversion.choice_to_number(string) except KeyError as exc: err_msg = f"Choice {string} not found in Data {self.name}." raise KeyError(err_msg) from exc @property def scale(self) -> Union[int, float]: """The scale factor of the signal value.""" return self.conversion.scale @scale.setter def scale(self, value: Union[int, float]) -> None: self.conversion = self.conversion.factory( scale=value, offset=self.conversion.offset, choices=self.conversion.choices, is_float=self.conversion.is_float, ) @property def offset(self) -> Union[int, float]: """The offset of the signal value.""" return self.conversion.offset @offset.setter def offset(self, value: Union[int, float]) -> None: self.conversion = self.conversion.factory( scale=self.conversion.scale, offset=value, choices=self.conversion.choices, is_float=self.conversion.is_float, ) @property def choices(self) -> Optional[Choices]: """A dictionary mapping signal values to enumerated choices, or ``None`` if unavailable.""" return self.conversion.choices @choices.setter def choices(self, choices: Optional[Choices]) -> None: self.conversion = self.conversion.factory( scale=self.conversion.scale, offset=self.conversion.offset, choices=choices, is_float=self.conversion.is_float, ) @property def is_float(self) -> bool: """``True`` if the raw signal value is a float, ``False`` otherwise.""" return self.conversion.is_float @is_float.setter def is_float(self, is_float: bool) -> None: self.conversion = self.conversion.factory( scale=self.conversion.scale, offset=self.conversion.offset, choices=self.conversion.choices, is_float=is_float, ) def __repr__(self) -> str: if self.choices is None: choices = None else: choices = '{{{}}}'.format(', '.join( [f"{value}: '{text}'" for value, text in self.choices.items()])) return "data('{}', {}, {}, '{}', {}, {}, {}, {}, '{}', {})".format( self.name, self.start, self.length, self.byte_order, self.conversion.scale, self.conversion.offset, self.minimum, self.maximum, self.unit, choices)