jmri_core.beans.layout_block
LayoutBlock — a track segment on the panel that a layout-editor
diagram references.
This is intentionally a round-trip bean for the current pass. A
real LayoutBlock in JMRI Java participates in occupancy propagation
across turnout paths, block-boss signalling, and layout-editor
rendering — none of which exist in the Python rewrite yet. What we
carry here is enough to survive PanelPro.xml load/save and to
answer the JSON schema so JMRI mobile clients don't get 404s when
they probe the layoutBlock topic.
When Panel Editor lands (Tier 1 #3 in ~/workitems.txt) this file
grows real logic; today it's honest scaffolding.
1"""``LayoutBlock`` — a track segment on the panel that a layout-editor 2diagram references. 3 4This is intentionally a **round-trip bean** for the current pass. A 5real LayoutBlock in JMRI Java participates in occupancy propagation 6across turnout paths, block-boss signalling, and layout-editor 7rendering — none of which exist in the Python rewrite yet. What we 8carry here is enough to survive `PanelPro.xml` load/save and to 9answer the JSON schema so JMRI mobile clients don't get 404s when 10they probe the ``layoutBlock`` topic. 11 12When Panel Editor lands (Tier 1 #3 in ``~/workitems.txt``) this file 13grows real logic; today it's honest scaffolding. 14""" 15from __future__ import annotations 16 17from jmri_core.bean import AbstractNamedBean 18from jmri_core.manager import Manager 19 20# Default panel colours JMRI uses when it renders a layout block. 21# Strings so the wire form pins the wire form; Layout Editor is what 22# consumes them later. 23_DEFAULT_BLOCK_COLOR = "black" 24_DEFAULT_TRACK_COLOR = "black" 25_DEFAULT_OCCUPIED_COLOR = "red" 26_DEFAULT_EXTRA_COLOR = "white" 27 28 29class LayoutBlock(AbstractNamedBean): 30 """One layout-editor block. Occupancy / adjacency logic is Panel-Editor 31 territory; here we're a data holder.""" 32 33 __slots__ = ( 34 "block", # underlying Block bean name (opaque string) 35 "block_color", 36 "extra_color", 37 "memory", # associated Memory bean name (opaque string) 38 "occupancy_sensor", # associated Sensor bean name (opaque string) 39 "occupied_color", 40 "occupied_sense", # sensor state that means "occupied" (usually 2) 41 "state", # opaque int the layout-editor uses 42 "track_color", 43 "use_extra_color", 44 ) 45 46 type_letter = "B" 47 48 def __init__( 49 self, system_name: str, user_name: str | None = None, 50 ) -> None: 51 super().__init__(system_name, user_name) 52 self.state: int = 0 53 self.block: str | None = None 54 self.memory: str | None = None 55 self.occupancy_sensor: str | None = None 56 # JMRI Java's default: ACTIVE == 2 == occupied. 57 self.occupied_sense: int = 2 58 self.block_color: str = _DEFAULT_BLOCK_COLOR 59 self.track_color: str = _DEFAULT_TRACK_COLOR 60 self.occupied_color: str = _DEFAULT_OCCUPIED_COLOR 61 self.extra_color: str = _DEFAULT_EXTRA_COLOR 62 self.use_extra_color: bool = False 63 64 65class LayoutBlockManager(Manager[LayoutBlock]): 66 # JMRI uses ``ILB``-prefixed system names for layout blocks; the 67 # type letter is ``B`` (same as Block) but the manager is distinct. 68 # Callers pass fully-qualified system names — ``normalize_name`` will 69 # accept ``"ILB1"`` unchanged when we're constructed with prefix 70 # ``"IL"``. 71 type_letter = "B" 72 73 def _create(self, system_name: str) -> LayoutBlock: 74 return LayoutBlock(system_name)
30class LayoutBlock(AbstractNamedBean): 31 """One layout-editor block. Occupancy / adjacency logic is Panel-Editor 32 territory; here we're a data holder.""" 33 34 __slots__ = ( 35 "block", # underlying Block bean name (opaque string) 36 "block_color", 37 "extra_color", 38 "memory", # associated Memory bean name (opaque string) 39 "occupancy_sensor", # associated Sensor bean name (opaque string) 40 "occupied_color", 41 "occupied_sense", # sensor state that means "occupied" (usually 2) 42 "state", # opaque int the layout-editor uses 43 "track_color", 44 "use_extra_color", 45 ) 46 47 type_letter = "B" 48 49 def __init__( 50 self, system_name: str, user_name: str | None = None, 51 ) -> None: 52 super().__init__(system_name, user_name) 53 self.state: int = 0 54 self.block: str | None = None 55 self.memory: str | None = None 56 self.occupancy_sensor: str | None = None 57 # JMRI Java's default: ACTIVE == 2 == occupied. 58 self.occupied_sense: int = 2 59 self.block_color: str = _DEFAULT_BLOCK_COLOR 60 self.track_color: str = _DEFAULT_TRACK_COLOR 61 self.occupied_color: str = _DEFAULT_OCCUPIED_COLOR 62 self.extra_color: str = _DEFAULT_EXTRA_COLOR 63 self.use_extra_color: bool = False
One layout-editor block. Occupancy / adjacency logic is Panel-Editor territory; here we're a data holder.
49 def __init__( 50 self, system_name: str, user_name: str | None = None, 51 ) -> None: 52 super().__init__(system_name, user_name) 53 self.state: int = 0 54 self.block: str | None = None 55 self.memory: str | None = None 56 self.occupancy_sensor: str | None = None 57 # JMRI Java's default: ACTIVE == 2 == occupied. 58 self.occupied_sense: int = 2 59 self.block_color: str = _DEFAULT_BLOCK_COLOR 60 self.track_color: str = _DEFAULT_TRACK_COLOR 61 self.occupied_color: str = _DEFAULT_OCCUPIED_COLOR 62 self.extra_color: str = _DEFAULT_EXTRA_COLOR 63 self.use_extra_color: bool = False
Inherited Members
66class LayoutBlockManager(Manager[LayoutBlock]): 67 # JMRI uses ``ILB``-prefixed system names for layout blocks; the 68 # type letter is ``B`` (same as Block) but the manager is distinct. 69 # Callers pass fully-qualified system names — ``normalize_name`` will 70 # accept ``"ILB1"`` unchanged when we're constructed with prefix 71 # ``"IL"``. 72 type_letter = "B" 73 74 def _create(self, system_name: str) -> LayoutBlock: 75 return LayoutBlock(system_name)
Per-type bean registry. Subclass and override _create().
Attributes set on the class describe the bean type:
type_letter— single uppercase letter the bean class owns (e.g."T"for Turnout). Must be set by subclass.system_prefix— connection prefix (e.g."L"). Set per-instance because one bean class can have many connection-specific managers.