"""GUI-neutral adapter for the shared templates Balsam 167 CAN decoder.""" from __future__ import annotations from protocan import balsam from protocan import protocan as pc from .shared_protocol import get_shared_protocol def decode(raw_id: int, data: bytes, *, ide: bool = True, rtr: bool = False) -> pc.Decoded | None: if not ide or rtr or not balsam.is_balsam_id(raw_id): return None try: frame = balsam.decode(raw_id, data, native=get_shared_protocol()) except ValueError as error: result = pc.Decoded(pc.ProtoCanId.parse(raw_id), len(data), bytes(data), ide=ide, rtr=rtr, protocol="BALZAM 167") result.summary = "BALZAM: неверный кадр" result.fields = [("Протокол", "BALZAM 167"), ("Ошибка", str(error))] result.warnings.append(str(error)) return result if frame is None: return None pid = pc.ProtoCanId( raw=frame.can_id, body=frame.start_address, msg_type=0, device=frame.device, device_type=0, pm=1 if frame.from_device else 0, priority=0, ) result = pc.Decoded(pid, len(data), bytes(data), ide=ide, rtr=rtr, protocol="BALZAM 167", device_label=frame.device_name, message_label="BALZAM регистры") result.summary = frame.summary result.fields = [ ("Протокол", "BALZAM 167 legacy eCAN"), ("Узел", "%d — %s" % (frame.device, frame.device_name)), ("Направление", "от устройства" if frame.from_device else "к устройству"), ("Начальный адрес", "0x%04X" % frame.start_address), ("Маска трёх слов", "0b%s" % format(frame.present_mask, "03b")), ] result.registers = [(item.address, item.value) for item in frame.registers] for item in frame.registers: result.fields.append(( "0x%04X %s" % (item.address, item.name or "регистр"), "0x%04X (%d)" % (item.value, item.signed_value), )) if frame.present_mask == 0: result.warnings.append("В адресном слове не отмечен ни один регистр") return result