Works out which TROs the control system will need for drawing 500573_60_1,
derived from the mechanical DXF and matched against the TRO catalog, plus the
annotated figures it refers to.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sister program to material_flow.py with the same switches, but --tosvg draws the
flow diagram of the TROs instead of the individual objects. It reuses
read_elements and build_graph, so CSV parsing and direction logic exist once.
A TRO is the control logic of one hand-over point, derived from the separator and
what is attached to it, following doc/500573_Mubea/TRO_Identifikation_500573.md:
Gefaellestrecke, >= 2 lines sharing feed/discharge -> PinStore_Auto per group
Gefaellestrecke, single line -> 1Sep
Strecke (driven) -> Vario per segment
Kreisel lane -> 1Sep
A scanner at the separator deliberately does not change the type: in connect.ini
separators with a scanner are predominantly 1Sep, and 1Sep_SSCC is reserved for
the SSCC/end-measurement/WCS case, which a mechanical layout cannot reveal.
Affected points are reported as hints instead. A host with 2 or 3 outgoing flow
edges upgrades 1Sep to 1Sep1Swi/1Sep2Swi.
Connectivity contracts passive nodes: material runs separator to separator, so a
carousel lane carrying no TRO is traversed rather than treated as a dead end.
Without that, a lone separator on a spur loop would be reported as an orphan
purely as an artifact of the model. Each TRO must connect to at least one other;
otherwise an error file is written and the exit code is 3.
Each TRO also carries a plant coordinate - the centroid of the components it was
built from, so a 1Sep1Swi sits between its separator and its switch. Written into
the DOT as a pos attribute (1:100), which dot ignores and "neato -n" can use to
draw the diagram to scale.
Types, function blocks, components and colours come exclusively from
lib/tro_catalog.py.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lib/tro_catalog.py is the single source for everything needed to create a TRO.
It reads no files at runtime; the origin of the data is recorded in comments
only, with CATALOG_AS_OF naming the revision it was taken from.
A TRO type is described by four things:
name short type as used in FB_Main and connect.ini ("1Sep")
fb_block the Siemens function block ("FB_ILS_MTRO_1Sep")
items which components sit inside it and how many
style colour group for drawings
TroDefinition is a pydantic v2 model with validate_assignment, so the get_*/set_*
methods cannot leave an object in an invalid state, and model_dump()/
model_validate() come for free for the planned JSON layout model.
Component lists for the four locally vendored FBs are verified against their VAR
declarations; the rest are .liblink references and follow the composition table
in TRO_Typen.md. Two findings from that comparison, recorded in the comments:
FB_ILS_MTRO_2Sep1Swi also declares two barcode readers, which the doc table
omits, and FB_EmptyCarrBuffer has no separator of its own - its base is a
separate 1Sep TRO (TRO101_IN next to TRO101 in the reference plant).
Colours follow the "Color legend" of the catalog: green means storage, the Vario
is purple. TroStyle renders both Graphviz attributes and Mermaid classDefs, so
the palette exists once and is ready for the BricsCAD symbol.
Enables pydantic in requirements.txt accordingly.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reads the CSV export of the plant objects (ILS 2.0) from SKEL_DATA and builds a
directed graph of the material flow, written as Graphviz DOT and optionally SVG
into SKEL_RESULTS.
Node model: one node per Gefaellestrecke and Strecke; a Kreisel becomes two
nodes (-L / -R) wired into a circle, since it is a carousel with one lane per
travel direction. Separators and scanners are no nodes of their own; they are
shown on the label of the object they are assigned to.
Edge direction is not in the CSV - the Nachbarn column is symmetric. It is
derived from geometry instead: a Gefaellestrecke runs downhill away from its
highest neighbour, a driven Strecke follows Antriebfahrtrichtung ("Auf" uphill,
"Ab" downhill). Connections that stay ambiguous, e.g. between two Kreisel at the
same height, are drawn as bidirectional edges and reported.
The lane suffix of a Kreisel is always stated in the *partner's* row, so both
viewpoints of a link are merged before orienting it.
Switches:
--file name of the CSV in SKEL_DATA, or a full path
--tosvg render the DOT via Graphviz
--doc write a Markdown documentation of the plant objects
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The doc folder is now addressed via an environment variable like every other
project folder, so tools can resolve doc paths without hardcoding them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>