52 lines
2.7 KiB
Python
52 lines
2.7 KiB
Python
"""GAS 167/v1 dictionary and assigned UKSS IDs; values remain raw u16."""
|
||
import json
|
||
from pathlib import Path
|
||
|
||
REGISTERS = tuple(json.loads(Path(__file__).with_name('gas_167_registers.json').read_text(encoding='utf-8'))['registers'])
|
||
BY_ADDRESS = {entry['address']: entry for entry in REGISTERS}
|
||
BY_ASSIGNED_ID = {entry[key]: (node, entry) for node, key in ((5, 'ump1_id'), (6, 'ump2_id')) for entry in REGISTERS}
|
||
|
||
COMMAND_NAMES = (
|
||
'cTestLamp — проверка ламп', 'cDefParam — параметры по умолчанию',
|
||
'cSaveParam — сохранение параметров', 'cLoadParam — загрузка параметров',
|
||
'cTermoCal — термокалибровка', 'cKoefCalc — расчёт коэффициентов',
|
||
'cUMPreset — останов заряда', 'cUMPstart — пуск заряда',
|
||
'cInitDac — инициализация ЦАП', 'cCalibrDac — калибровка ЦАП',
|
||
'cSecretBt', 'cLiteFire', 'cRawMeat', 'бит 13 (не назначен)',
|
||
'бит 14 (не назначен)', 'cReset — сброс',
|
||
)
|
||
|
||
|
||
def describe_word(offset, value):
|
||
"""Describe active bits using the selected LOAD register map."""
|
||
if offset == 127:
|
||
return ', '.join(name for bit, name in enumerate(COMMAND_NAMES)
|
||
if value & (1 << bit)) or 'нет активных команд'
|
||
if offset == 124:
|
||
names = ('LOAD_FAULT — ошибка пуска', 'нет свежего напряжения ЗПТ',
|
||
'LOAD_RELOAD — сброс перед пуском', 'LOAD_RUN — работа рампы',
|
||
'имитация потери ЗПТ', 'имитация 0 В')
|
||
return ', '.join(names[bit] if bit < len(names) else 'бит %d' % bit
|
||
for bit in range(16) if value & (1 << bit)) or 'нет активных флагов LOAD'
|
||
return ''
|
||
|
||
|
||
def metadata(address):
|
||
"""Metadata for the explicitly selected legacy Modbus profile."""
|
||
index = address if 0 <= address < 128 else address - 0x5000
|
||
if not 0 <= index < 128:
|
||
return {}
|
||
entry = REGISTERS[index]
|
||
return {'name': entry['description'], 'gas_id': f"{entry['ump1_id']} / {entry['ump2_id']}"}
|
||
|
||
|
||
def assigned_metadata(address):
|
||
"""Only assigned global IDs; reserved offsets have no parameter name."""
|
||
match = BY_ASSIGNED_ID.get(address)
|
||
if match is None:
|
||
return {}
|
||
node, entry = match
|
||
return {'node': node, 'name': entry['description'], 'access': entry['access'],
|
||
'modbus': entry['modbus'], 'legacy_address': entry['address'],
|
||
'status': 'назначен; прошивка 167/v1 ещё не обслуживает'}
|