jmri_nce.detect
Auto-detect the NCE command-set variant via SW_REV_CMD (opcode 0xAA).
The query returns 3 bytes: major version, minor version, and a model byte. We use the model byte to choose between the three production variants; falls back to PH-Pro 2006+ if the model is unknown (the most permissive of the three).
1"""Auto-detect the NCE command-set variant via ``SW_REV_CMD`` (opcode 0xAA). 2 3The query returns 3 bytes: major version, minor version, and a model byte. 4We use the model byte to choose between the three production variants; 5falls back to PH-Pro 2006+ if the model is unknown (the most permissive 6of the three). 7""" 8from __future__ import annotations 9 10import logging 11 12from jmri_nce.command_set import ( 13 NCE_PH_PRO_2006, 14 NCE_POWERCAB, 15 NCE_SB5, 16 NceCommandSet, 17) 18from jmri_nce.messages import NceCommandError, query_command_version 19from jmri_nce.traffic import NceTrafficController 20 21_log = logging.getLogger(__name__) 22 23 24# Model byte values per the NCE binary command reference. 25MODEL_POWERPRO = 0x00 26MODEL_SB5 = 0x01 27MODEL_POWERCAB = 0x02 28MODEL_TWIN = 0x03 29 30 31def model_to_command_set(model: int) -> NceCommandSet: 32 """Choose the canonical command set for an NCE model byte.""" 33 if model == MODEL_POWERCAB: 34 return NCE_POWERCAB 35 if model == MODEL_SB5: 36 return NCE_SB5 37 # PowerPro, Twin, and unknowns all use the PH-Pro 2006+ map. 38 return NCE_PH_PRO_2006 39 40 41async def detect_command_set( 42 tc: NceTrafficController, *, fallback: NceCommandSet = NCE_PH_PRO_2006 43) -> NceCommandSet: 44 """Query the command station and pick the matching command set. 45 46 On any error (timeout, unsupported by old firmware, NACK) we log a 47 warning and return *fallback* so the connection still opens. 48 """ 49 try: 50 reply = await tc.send_command(query_command_version()) 51 except (TimeoutError, NceCommandError) as e: 52 _log.warning("NCE version query failed (%s); falling back to %s", e, fallback.name) 53 return fallback 54 if len(reply.data) < 3: 55 _log.warning("NCE version reply too short: %r", reply.data) 56 return fallback 57 major, minor, model = reply.data[0], reply.data[1], reply.data[2] 58 cs = model_to_command_set(model) 59 _log.info("NCE firmware v%d.%d, model=%#x → %s", major, minor, model, cs.name) 60 return cs
MODEL_POWERPRO =
0
MODEL_SB5 =
1
MODEL_POWERCAB =
2
MODEL_TWIN =
3
32def model_to_command_set(model: int) -> NceCommandSet: 33 """Choose the canonical command set for an NCE model byte.""" 34 if model == MODEL_POWERCAB: 35 return NCE_POWERCAB 36 if model == MODEL_SB5: 37 return NCE_SB5 38 # PowerPro, Twin, and unknowns all use the PH-Pro 2006+ map. 39 return NCE_PH_PRO_2006
Choose the canonical command set for an NCE model byte.
async def
detect_command_set( tc: jmri_nce.NceTrafficController, *, fallback: jmri_nce.NceCommandSet = NceCommandSet(name='PH-Pro 2006+', turnout_memory_base=60416, turnout_table_bytes=256, macro_memory_base=51200, consist_memory_base=62720, supports_ops_mode_prog=True, aiu_polling_supported=True)) -> jmri_nce.NceCommandSet:
42async def detect_command_set( 43 tc: NceTrafficController, *, fallback: NceCommandSet = NCE_PH_PRO_2006 44) -> NceCommandSet: 45 """Query the command station and pick the matching command set. 46 47 On any error (timeout, unsupported by old firmware, NACK) we log a 48 warning and return *fallback* so the connection still opens. 49 """ 50 try: 51 reply = await tc.send_command(query_command_version()) 52 except (TimeoutError, NceCommandError) as e: 53 _log.warning("NCE version query failed (%s); falling back to %s", e, fallback.name) 54 return fallback 55 if len(reply.data) < 3: 56 _log.warning("NCE version reply too short: %r", reply.data) 57 return fallback 58 major, minor, model = reply.data[0], reply.data[1], reply.data[2] 59 cs = model_to_command_set(model) 60 _log.info("NCE firmware v%d.%d, model=%#x → %s", major, minor, model, cs.name) 61 return cs
Query the command station and pick the matching command set.
On any error (timeout, unsupported by old firmware, NACK) we log a warning and return fallback so the connection still opens.