51 lines
2.2 KiB
Python
51 lines
2.2 KiB
Python
"""Explicit interpretation of ProtoCAN registers with the UMP 167/v1 map.
|
|
|
|
This is a manually selected dictionary, not detection of the legacy service
|
|
CAN packet format or a claim that a particular firmware implements ProtoCAN.
|
|
"""
|
|
from protocan import protocan as pc
|
|
from protocan.gas_167 import REGISTERS, describe_word
|
|
|
|
|
|
def decode_gas167(frame, node):
|
|
result = pc.decode(frame.can_id, frame.data, ide=frame.ide, rtr=frame.rtr)
|
|
result.device_label = "УМП %d (выбран вручную)" % node
|
|
result.protocol = "УМП %d / ProtoCAN GAS 167/v1" % node
|
|
if not frame.ide or frame.rtr or frame.is_error:
|
|
return result
|
|
if result.id.msg_type not in (pc.MsgType.GENERAL_ADDRESS_SPACE,
|
|
pc.MsgType.MODBUS_HOLDING):
|
|
return result
|
|
if result.id.msg_type == pc.MsgType.GENERAL_ADDRESS_SPACE:
|
|
start = result.id.body
|
|
else:
|
|
start, _count = pc.split_modbus(result.id.body)
|
|
words = result.registers
|
|
if words is None:
|
|
return result
|
|
labels = []
|
|
for address, value in words or [(start, None)]:
|
|
offset = address if 0 <= address < 128 else address - 0x5000
|
|
label = "0x%04X" % address
|
|
if 0 <= offset < len(REGISTERS):
|
|
entry = REGISTERS[offset]
|
|
label += " · " + entry['description']
|
|
result.fields += [
|
|
(" УМП 167/v1 0x%04X" % address, entry['description']),
|
|
(" Назначенные ID УМП 1/2", "%d / %d" % (entry['ump1_id'], entry['ump2_id'])),
|
|
(" Доступ", entry['access']),
|
|
]
|
|
else:
|
|
label += " · вне карты 167/v1"
|
|
if value is not None:
|
|
label += " = %d [0x%04X]" % (value, value)
|
|
description = describe_word(offset, value)
|
|
if description:
|
|
label += " — " + description
|
|
result.fields.append((" Биты 0x%04X" % address, description))
|
|
labels.append(label)
|
|
result.summary = "УМП %d · GAS 167/v1%s: %s" % (
|
|
node, " запрос" if not words else "", "; ".join(labels))
|
|
result.fields.append((" Карта", "167/v1 выбрана вручную"))
|
|
return result
|