TrainRBCSim
ADR-029 Train (EVC) simulator — dual-homed TCP client speaking the RBC wire protocol
Toggle main menu visibility
Loading...
Searching...
No Matches
site_data.py
Go to the documentation of this file.
1
"""site_data.py - Train sim's own tiny RailML reader.
2
3
Independently re-parses safeAPIRBC2oo2SA/etc/site/ab_site.railml.xml -
4
the same single source of truth safeAPIRBC2oo2GP/etc/scripts/
5
generate_ab_site_gp.py and safeAPIRBC2oo2GA/etc/scripts/generate_ab_site_ga.py
6
already generate GP's/GA's own C site-data tables from, and
7
safeAPIRBC2oo2TestEnv/src/web_runner/site_data.py already reads for the
8
live schematic - deliberately a FOURTH independent reader, not a call
9
into any of those three, matching the "each generator re-parses the file
10
itself, no pipeline coupling" convention those two C-side generators'
11
own header comments already establish (see either one's own doc for the
12
full rationale: no build-order coupling, and a real cross-check
13
opportunity instead of one silently trusting another's derived output).
14
15
Train only ever needs ONE thing from the file: the `nid_lrbg -> name`
16
mapping this sim uses purely for its own log-line decoration (see
17
train_sim.py's own get_balise_name()) - replaces what used to be a
18
hardcoded BALISE_NAMES dict that was, by actual comparison, a byte-for-
19
byte duplicate of this file's own <baliseGroup> data.
20
"""
21
22
import
logging
23
import
os
24
import
xml.etree.ElementTree
as
ET
25
26
_RAILML_NS =
"https://www.railml.org/schemas/3.3"
27
_SAPI_NS =
"https://safeapirbc2oo2.example/schemas/sapi-ext/1"
28
_NS = {
"r"
: _RAILML_NS,
"sapi"
: _SAPI_NS}
29
30
# TrainRBCSim/src/train/ -> up 3 (train, src, TrainRBCSim) -> the SAPI
31
# workspace root -> safeAPIRBC2oo2SA's own sibling checkout. Same
32
# sibling-directory convention web_runner/server.py's own
33
# DEFAULT_RAILML_PATH already uses - see that file's own doc.
34
_WORKSPACE_ROOT = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
".."
,
".."
,
".."
))
35
DEFAULT_RAILML_PATH = os.path.join(_WORKSPACE_ROOT,
"safeAPIRBC2oo2SA"
,
"etc"
,
"site"
,
"ab_site.railml.xml"
)
36
37
# Byte-for-byte what BALISE_NAMES (train_sim.py, before this module
38
# existed) hardcoded - kept ONLY as a fallback for a deployment that
39
# genuinely has no sibling safeAPIRBC2oo2SA checkout available (e.g. a
40
# Docker image built from just this project's own source tree, which
41
# does not copy that sibling project's own etc/site/ in today - a real,
42
# separate packaging gap, not something this module can fix from here).
43
# balise_names() logs a clear warning whenever this fallback is actually
44
# used, so the gap stays visible rather than silently masking itself.
45
_FALLBACK_BALISE_NAMES = {
46
1001:
"BG_W_TRK1"
, 1002:
"BG_W_TRK2"
, 1003:
"BG_W_TRK3"
, 1004:
"BG_W_TRK4"
,
47
1005:
"BG_UP_1"
, 1006:
"BG_UP_2"
, 1007:
"BG_DOWN_1"
, 1008:
"BG_DOWN_2"
,
48
1009:
"BG_E_TRK1"
, 1010:
"BG_E_TRK2"
, 1011:
"BG_E_TRK3"
, 1012:
"BG_E_TRK4"
,
49
}
50
51
52
def
balise_names
(railml_path=None):
53
"""@return {nid_lrbg: name} parsed fresh from the RailML file (no
54
caching - this sim's own catalog/config loading is likewise done
55
once at import/startup time, matching that same "read once, live
56
for the process's lifetime" posture). Falls back to a hardcoded copy
57
of today's known-good data (see _FALLBACK_BALISE_NAMES's own doc) and
58
logs a warning if the file can't be found/parsed, rather than raising
59
- a missing balise-name mapping is a log-decoration cosmetic, never
60
worth failing sim startup over."""
61
path = railml_path
or
os.environ.get(
"SAPI_RAILML_PATH"
)
or
DEFAULT_RAILML_PATH
62
try
:
63
tree = ET.parse(path)
64
root = tree.getroot()
65
infra = root.find(
"r:infrastructure"
, _NS)
66
fi = infra.find(
"r:functionalInfrastructure"
, _NS)
67
balise_groups = fi.find(
"r:baliseGroups"
, _NS)
68
names = {}
69
for
bg
in
balise_groups.findall(
"r:baliseGroup"
, _NS):
70
ext = bg.find(
"r:extensions/sapi:etcsBaliseGroup"
, _NS)
71
nid_lrbg = int(ext.get(
"nidLrbg"
))
72
names[nid_lrbg] = bg.get(
"name"
, f
"BG_{nid_lrbg}"
)
73
if
not
names:
74
raise
ValueError(
"RailML file parsed but yielded zero balise groups"
)
75
return
names
76
except
Exception
as
e:
77
logging.getLogger(
"train"
).warning(
78
"[GENERAL] [train] [internal] [CONFIG] [could not read balise names from RailML "
79
"(%s) - falling back to the hardcoded copy] [path=%s]"
, e, path)
80
return
dict(_FALLBACK_BALISE_NAMES)
train.site_data.balise_names
balise_names(railml_path=None)
Definition
site_data.py:52
src
train
site_data.py
Generated by
1.18.0