Source code for canlib.frame

def dlc_to_bytes(dlc, canFd=False):
    """Convert DLC to number of bytes

    .. versionadded:: 1.7

    """
    if dlc < 9:
        bytes = dlc
    elif dlc == 9:
        bytes = 12
    elif dlc == 10:
        bytes = 16
    elif dlc == 11:
        bytes = 20
    elif dlc == 12:
        bytes = 24
    elif dlc == 13:
        bytes = 32
    elif dlc == 14:
        bytes = 48
    else:
        bytes = 64

    if canFd:
        return bytes
    else:
        return min(bytes, 8)


def bytes_to_dlc(num_bytes, canFD=True):
    """Calculate minimum DLC that can hold number of bytes

    .. versionadded:: 1.18

    """
    if not canFD:
        return num_bytes
    if num_bytes < 8:
        return num_bytes
    if num_bytes <= 12:
        return 9
    if num_bytes <= 16:
        return 10
    if num_bytes <= 20:
        return 11
    if num_bytes <= 24:
        return 12
    if num_bytes <= 32:
        return 13
    if num_bytes <= 48:
        return 14
    return 15


[docs]class Frame: """Represents a CAN message Args: id_: Message id data : Message data, will pad zero to match dlc (if dlc is given) dlc : Message dlc, default is calculated from number of data flags (`canlib.MessageFlag`): Message flags, default is 0 timestamp : Optional timestamp """ # noqa: RST306 __slots__ = ('id', 'data', 'dlc', 'flags', 'timestamp') _repr_slots = __slots__ _eq_slots = __slots__[:-1] def __init__(self, id_, data, dlc=None, flags=0, timestamp=None): data = bytearray(data) if dlc is None: if len(data) <= 8: dlc = len(data) elif len(data) <= 12: dlc = 12 elif len(data) <= 16: dlc = 16 elif len(data) <= 20: dlc = 20 elif len(data) <= 24: dlc = 24 elif len(data) <= 32: dlc = 32 elif len(data) <= 48: dlc = 48 else: dlc = 64 if dlc > len(data): data.extend([0] * (dlc - len(data))) elif dlc <= 8: data.extend([0] * (dlc - len(data))) self.id = id_ self.data = data self.dlc = dlc self.flags = flags self.timestamp = timestamp # in Python 2 both __eq__ and __ne__ must be implemented def __ne__(self, other): return not self == other def __eq__(self, other): if isinstance(other, Frame): return all(getattr(self, slot) == getattr(other, slot) for slot in self._eq_slots) else: return NotImplemented def __getitem__(self, index): slot = self.__slots__[index] return getattr(self, slot) def __setitem__(self, index, val): slot = self.__slots__[index] return setattr(self, slot, val) def __iter__(self): for slot in self.__slots__: yield getattr(self, slot) def __repr__(self): return '{cls}({kwargs})'.format( cls=self.__class__.__name__, kwargs=', '.join(slot + '=' + repr(getattr(self, slot)) for slot in self._repr_slots), )
[docs]class LINFrame(Frame): """Represents a LIN message A `Frame` that also has an `info` attribute, which is a `linlib.MessageInfo` or `None`. This attribute is initialized via the `info` keyword-only argument to the constructor. """ __slots__ = Frame.__slots__ + ('info',) # In python 3 we could just use: # # def __init__(self, *args, info=None, **kwargs): def __init__(self, *args, **kwargs): info = kwargs.pop("info", None) if 'timestamp' not in kwargs and info is not None: kwargs['timestamp'] = info.timestamp super().__init__(*args, **kwargs) self.info = info