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"])
class LayoutBlockService(jmri_server.services.beans._BeanService):
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().

topic = 'layoutBlock'
def manager(self) -> jmri_core.beans.layout_block.LayoutBlockManager:
20    def manager(self) -> LayoutBlockManager:
21        return self.ctx.connection.layout_blocks
def project( self, bean: jmri_core.beans.layout_block.LayoutBlock) -> dict[str, typing.Any]:
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.