Source code for cantools.database.diagnostics.did

# A DID.

import binascii

from ..utils import create_encode_decode_formats, decode_data, encode_data


[docs]class Did: """A DID with identifier and other information. """ def __init__(self, identifier, name, length, datas): self._identifier = identifier self._name = name self._length = length self._datas = datas self._codec = None self.refresh() @property def identifier(self): """The did identifier as an integer. """ return self._identifier @identifier.setter def identifier(self, value): self._identifier = value @property def name(self): """The did name as a string. """ return self._name @name.setter def name(self, value): self._name = value @property def length(self): """The did name as a string. """ return self._length @length.setter def length(self, value): self._length = value @property def datas(self): """The did datas as a string. """ return self._datas @datas.setter def datas(self, value): self._datas = value def get_data_by_name(self, name): for data in self._datas: if data.name == name: return data raise KeyError(name)
[docs] def encode(self, data, scaling=True): """Encode given data as a DID of this type. If `scaling` is ``False`` no scaling of datas is performed. >>> foo = db.get_did_by_name('Foo') >>> foo.encode({'Bar': 1, 'Fum': 5.0}) b'\\x01\\x45\\x23\\x00\\x11' """ encoded = encode_data(data, self._codec['datas'], self._codec['formats'], scaling) encoded |= (0x80 << (8 * self._length)) encoded = hex(encoded)[4:].rstrip('L') return binascii.unhexlify(encoded)[:self._length]
[docs] def decode(self, data, decode_choices=True, scaling=True, allow_truncated=False, allow_excess=True): """Decode given data as a DID of this type. If `decode_choices` is ``False`` scaled values are not converted to choice strings (if available). If `scaling` is ``False`` no scaling of datas is performed. >>> foo = db.get_did_by_name('Foo') >>> foo.decode(b'\\x01\\x45\\x23\\x00\\x11') {'Bar': 1, 'Fum': 5.0} """ return decode_data(data[:self._length], self.length, self._codec['datas'], self._codec['formats'], decode_choices, scaling, allow_truncated, allow_excess)
[docs] def refresh(self): """Refresh the internal DID state. """ self._codec = { 'datas': self._datas, 'formats': create_encode_decode_formats(self._datas, self._length) }
def __repr__(self): return f"did('{self._name}', 0x{self._identifier:04x})"