jmri_server.services.layout_block
LayoutBlockService — JSON topic layoutBlock.
Wire shape per jmri/server/json/layoutblock/layoutBlock-server.json.
Round-trip only in this pass — Panel Editor (Tier 1 #3) will layer
real occupancy logic on top of these beans.
1"""``LayoutBlockService`` — JSON topic ``layoutBlock``. 2 3Wire shape per ``jmri/server/json/layoutblock/layoutBlock-server.json``. 4Round-trip only in this pass — Panel Editor (Tier 1 #3) will layer 5real occupancy logic on top of these beans. 6""" 7from __future__ import annotations 8 9from typing import Any 10 11from jmri_core.beans.layout_block import LayoutBlock, LayoutBlockManager 12 13from jmri_server.services.beans import _BeanService, _common_named_bean 14 15 16class LayoutBlockService(_BeanService): 17 topic = "layoutBlock" 18 19 def manager(self) -> LayoutBlockManager: 20 return self.ctx.connection.layout_blocks 21 22 def project(self, bean: LayoutBlock) -> dict[str, Any]: 23 return _common_named_bean(bean) | { 24 "state": bean.state, 25 "block": bean.block, 26 "memory": bean.memory, 27 "occupancySensor": bean.occupancy_sensor, 28 "occupiedSense": bean.occupied_sense, 29 "blockColor": bean.block_color, 30 "trackColor": bean.track_color, 31 "occupiedColor": bean.occupied_color, 32 "extraColor": bean.extra_color, 33 "useExtraColor": bean.use_extra_color, 34 } 35 36 async def apply(self, bean: LayoutBlock, data: dict[str, Any]) -> None: 37 # Every field is a straight assignment — no signal fires here 38 # because Panel Editor isn't wired yet. When it lands, this 39 # method grows a "notify state_changed" branch for occupancy 40 # transitions. 41 for wire_field, attr in ( 42 ("block", "block"), 43 ("memory", "memory"), 44 ("occupancySensor", "occupancy_sensor"), 45 ("blockColor", "block_color"), 46 ("trackColor", "track_color"), 47 ("occupiedColor", "occupied_color"), 48 ("extraColor", "extra_color"), 49 ): 50 if wire_field in data: 51 val = data[wire_field] 52 setattr(bean, attr, str(val) if val is not None else None) 53 if "occupiedSense" in data: 54 bean.occupied_sense = int(data["occupiedSense"]) 55 if "useExtraColor" in data: 56 bean.use_extra_color = bool(data["useExtraColor"]) 57 if "state" in data: 58 bean.state = int(data["state"])
17class LayoutBlockService(_BeanService): 18 topic = "layoutBlock" 19 20 def manager(self) -> LayoutBlockManager: 21 return self.ctx.connection.layout_blocks 22 23 def project(self, bean: LayoutBlock) -> dict[str, Any]: 24 return _common_named_bean(bean) | { 25 "state": bean.state, 26 "block": bean.block, 27 "memory": bean.memory, 28 "occupancySensor": bean.occupancy_sensor, 29 "occupiedSense": bean.occupied_sense, 30 "blockColor": bean.block_color, 31 "trackColor": bean.track_color, 32 "occupiedColor": bean.occupied_color, 33 "extraColor": bean.extra_color, 34 "useExtraColor": bean.use_extra_color, 35 } 36 37 async def apply(self, bean: LayoutBlock, data: dict[str, Any]) -> None: 38 # Every field is a straight assignment — no signal fires here 39 # because Panel Editor isn't wired yet. When it lands, this 40 # method grows a "notify state_changed" branch for occupancy 41 # transitions. 42 for wire_field, attr in ( 43 ("block", "block"), 44 ("memory", "memory"), 45 ("occupancySensor", "occupancy_sensor"), 46 ("blockColor", "block_color"), 47 ("trackColor", "track_color"), 48 ("occupiedColor", "occupied_color"), 49 ("extraColor", "extra_color"), 50 ): 51 if wire_field in data: 52 val = data[wire_field] 53 setattr(bean, attr, str(val) if val is not None else None) 54 if "occupiedSense" in data: 55 bean.occupied_sense = int(data["occupiedSense"]) 56 if "useExtraColor" in data: 57 bean.use_extra_color = bool(data["useExtraColor"]) 58 if "state" in data: 59 bean.state = int(data["state"])
Base class encapsulating get/list/put/post/delete plumbing.
Concrete bean services set topic and override manager(),
project(), and (when mutations are supported) apply().
23 def project(self, bean: LayoutBlock) -> dict[str, Any]: 24 return _common_named_bean(bean) | { 25 "state": bean.state, 26 "block": bean.block, 27 "memory": bean.memory, 28 "occupancySensor": bean.occupancy_sensor, 29 "occupiedSense": bean.occupied_sense, 30 "blockColor": bean.block_color, 31 "trackColor": bean.track_color, 32 "occupiedColor": bean.occupied_color, 33 "extraColor": bean.extra_color, 34 "useExtraColor": bean.use_extra_color, 35 }
async def
apply( self, bean: jmri_core.beans.layout_block.LayoutBlock, data: dict[str, typing.Any]) -> None:
37 async def apply(self, bean: LayoutBlock, data: dict[str, Any]) -> None: 38 # Every field is a straight assignment — no signal fires here 39 # because Panel Editor isn't wired yet. When it lands, this 40 # method grows a "notify state_changed" branch for occupancy 41 # transitions. 42 for wire_field, attr in ( 43 ("block", "block"), 44 ("memory", "memory"), 45 ("occupancySensor", "occupancy_sensor"), 46 ("blockColor", "block_color"), 47 ("trackColor", "track_color"), 48 ("occupiedColor", "occupied_color"), 49 ("extraColor", "extra_color"), 50 ): 51 if wire_field in data: 52 val = data[wire_field] 53 setattr(bean, attr, str(val) if val is not None else None) 54 if "occupiedSense" in data: 55 bean.occupied_sense = int(data["occupiedSense"]) 56 if "useExtraColor" in data: 57 bean.use_extra_color = bool(data["useExtraColor"]) 58 if "state" in data: 59 bean.state = int(data["state"])
Apply mutations from a client request. Default: no-op.