jmri_core.beans.reporter

Reporter — a layout input that delivers identification data.

Where a Sensor reports a boolean, a Reporter reports a string (or other structured value) — typically a loco ID from a RailCom reader, RFID tag, or transponder. Reporters keep both a current report (the most recent value) and a last report (the value before that), per JMRI semantics.

 1"""``Reporter`` — a layout input that delivers identification data.
 2
 3Where a :class:`Sensor` reports a boolean, a Reporter reports a string (or
 4other structured value) — typically a loco ID from a RailCom reader, RFID
 5tag, or transponder. Reporters keep both a *current* report (the most recent
 6value) and a *last* report (the value before that), per JMRI semantics.
 7"""
 8from __future__ import annotations
 9
10from dataclasses import dataclass
11from typing import Any
12
13from jmri_core.bean import AbstractNamedBean
14from jmri_core.manager import Manager
15
16
17@dataclass(frozen=True, slots=True)
18class ReporterChange:
19    previous: Any
20    current: Any
21
22
23class Reporter(AbstractNamedBean):
24    """Identification-data input. ``current_report`` is None when no read yet."""
25
26    __slots__ = ("_current_report", "_last_report")
27
28    type_letter = "R"
29
30    def __init__(self, system_name: str, user_name: str | None = None) -> None:
31        super().__init__(system_name, user_name)
32        self._current_report: Any = None
33        self._last_report: Any = None
34
35    @property
36    def current_report(self) -> Any:
37        return self._current_report
38
39    @property
40    def last_report(self) -> Any:
41        return self._last_report
42
43    async def set_report(self, value: Any) -> None:
44        prev = self._current_report
45        self._last_report = prev
46        self._current_report = value
47        await self.state_changed.emit(ReporterChange(prev, value))
48
49
50class ReporterManager(Manager[Reporter]):
51    type_letter = "R"
52
53    def _create(self, system_name: str) -> Reporter:
54        return Reporter(system_name)
@dataclass(frozen=True, slots=True)
class ReporterChange:
18@dataclass(frozen=True, slots=True)
19class ReporterChange:
20    previous: Any
21    current: Any
ReporterChange(previous: Any, current: Any)
previous: Any
current: Any
class Reporter(jmri_core.bean.AbstractNamedBean):
24class Reporter(AbstractNamedBean):
25    """Identification-data input. ``current_report`` is None when no read yet."""
26
27    __slots__ = ("_current_report", "_last_report")
28
29    type_letter = "R"
30
31    def __init__(self, system_name: str, user_name: str | None = None) -> None:
32        super().__init__(system_name, user_name)
33        self._current_report: Any = None
34        self._last_report: Any = None
35
36    @property
37    def current_report(self) -> Any:
38        return self._current_report
39
40    @property
41    def last_report(self) -> Any:
42        return self._last_report
43
44    async def set_report(self, value: Any) -> None:
45        prev = self._current_report
46        self._last_report = prev
47        self._current_report = value
48        await self.state_changed.emit(ReporterChange(prev, value))

Identification-data input. current_report is None when no read yet.

Reporter(system_name: str, user_name: str | None = None)
31    def __init__(self, system_name: str, user_name: str | None = None) -> None:
32        super().__init__(system_name, user_name)
33        self._current_report: Any = None
34        self._last_report: Any = None
type_letter = 'R'
current_report: Any
36    @property
37    def current_report(self) -> Any:
38        return self._current_report
last_report: Any
40    @property
41    def last_report(self) -> Any:
42        return self._last_report
async def set_report(self, value: Any) -> None:
44    async def set_report(self, value: Any) -> None:
45        prev = self._current_report
46        self._last_report = prev
47        self._current_report = value
48        await self.state_changed.emit(ReporterChange(prev, value))
51class ReporterManager(Manager[Reporter]):
52    type_letter = "R"
53
54    def _create(self, system_name: str) -> Reporter:
55        return Reporter(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.
type_letter = 'R'