SimCore
Shared transport-layer plumbing for the ADR-029 Train/IL/CTC RBC simulators
Toggle main menu visibility
Loading...
Searching...
No Matches
status_report.py
Go to the documentation of this file.
1
"""ADR-038 own-perspective status heartbeat for a sim.
2
3
Each sim instance reports its OWN view of the world - which RBC sites it
4
is currently connected to, plus a few caller-supplied extras - once at
5
startup and then every PERIOD_S seconds. Each report is BOTH logged
6
locally (so `each sim shows connection statuses from own perspective`,
7
ADR-038) AND pushed to both sites over the sim's existing dual-homed
8
link as an opaque RBC_MSG_SIM_STATUS envelope frame; the owning Role C
9
gateway (train/il/ctc handler) recognises that kind, does NOT forward it
10
to A/B, and republishes the ASCII payload to the C-side status broker.
11
12
Kind-blind by construction: the caller owns what the payload keys mean;
13
this module only handles the cadence, the log line and the send. Mirrors
14
rbc_wire.encode_opaque()'s own transport-vs-application split.
15
"""
16
17
import
time
18
19
from
simcore
import
rbc_wire
20
21
#: rbc_wire_types.h RBC_MSG_SIM_STATUS - kept in sync with BOTH C copies.
22
SIM_STATUS_KIND = 19
23
24
#: Startup + every PERIOD_S (ADR-038: "Startup + every 5s").
25
PERIOD_S = 5.0
26
27
28
class
StatusReporter
:
29
"""Cadence + encode + log + send for one sim's status heartbeat."""
30
31
def
__init__
(self, log, link, unit, log_source, kind=SIM_STATUS_KIND,
32
period_s=PERIOD_S, clock=time.monotonic, frame_size=rbc_wire.ENVELOPE_SIZE):
33
"""@param frame_size: passed straight through to rbc_wire.encode_opaque() -
34
override if @link's own channel uses a wider fixed slot than the
35
default ENVELOPE_SIZE (see that function's own doc)."""
36
self.
_log
= log
37
self.
_link
= link
38
self.
_unit
= unit
39
self.
_source
= log_source
40
self.
_kind
= kind
41
self.
_period
= period_s
42
self.
_clock
= clock
43
self.
_frame_size
= frame_size
44
self.
_next
= 0.0
45
46
def
_payload
(self, extra):
47
sites = set(self.
_link
.connected_sites())
48
west_up =
"WEST"
in
sites
49
east_up =
"EAST"
in
sites
50
if
west_up
and
east_up:
51
conn_desc =
"Both_Up"
52
elif
west_up:
53
conn_desc =
"West_Up"
54
elif
east_up:
55
conn_desc =
"East_Up"
56
else
:
57
conn_desc =
"Both_Down"
58
59
parts = [
60
f
"unit={self._unit}"
,
61
"up=1"
,
62
f
"west={1 if west_up else 0}"
,
63
f
"east={1 if east_up else 0}"
,
64
f
"conn_status={conn_desc}"
,
65
]
66
for
key, value
in
(extra
or
{}).items():
67
parts.append(f
"{key}={value}"
)
68
return
" "
.join(parts)
69
70
def
emit
(self, extra=None):
71
"""Report now, unconditionally - use once at startup."""
72
payload = self.
_payload
(extra)
73
self.
_log
.info(
"[GENERAL] [%s] [internal] [STATUS] [self] [%s]"
, self.
_source
, payload)
74
self.
_link
.send_all(rbc_wire.encode_opaque(self.
_kind
, payload, frame_size=self.
_frame_size
))
75
self.
_next
= self.
_clock
() + self.
_period
76
77
def
tick
(self, extra=None):
78
"""Report iff PERIOD_S has elapsed since the last report."""
79
if
self.
_clock
() >= self.
_next
:
80
self.
emit
(extra)
simcore.status_report.StatusReporter
Definition
status_report.py:28
simcore.status_report.StatusReporter.tick
tick(self, extra=None)
Definition
status_report.py:77
simcore.status_report.StatusReporter._payload
_payload(self, extra)
Definition
status_report.py:46
simcore.status_report.StatusReporter._next
float _next
Definition
status_report.py:44
simcore.status_report.StatusReporter.emit
emit(self, extra=None)
Definition
status_report.py:70
simcore.status_report.StatusReporter._log
_log
Definition
status_report.py:36
simcore.status_report.StatusReporter._frame_size
_frame_size
Definition
status_report.py:43
simcore.status_report.StatusReporter._clock
_clock
Definition
status_report.py:42
simcore.status_report.StatusReporter._kind
_kind
Definition
status_report.py:40
simcore.status_report.StatusReporter._period
_period
Definition
status_report.py:41
simcore.status_report.StatusReporter._link
_link
Definition
status_report.py:37
simcore.status_report.StatusReporter._source
_source
Definition
status_report.py:39
simcore.status_report.StatusReporter.__init__
__init__(self, log, link, unit, log_source, kind=SIM_STATUS_KIND, period_s=PERIOD_S, clock=time.monotonic, frame_size=rbc_wire.ENVELOPE_SIZE)
Definition
status_report.py:32
simcore.status_report.StatusReporter._unit
_unit
Definition
status_report.py:38
src
simcore
status_report.py
Generated by
1.18.0