Files
sps_skel/doc/Python_Scripts.md
T
s.ayadi 64c180d84b Document the new TRO_INSERT BricsCAD command
dxfmakros' TRO menu can now insert new TRO markers by hand (TRO_INSERT),
not just edit ones tro_annotate.py placed; note it here since this is
where the workflow and --emit-lisp switch are documented.
2026-08-03 15:56:16 +02:00

13 KiB
Raw Blame History

Python Scripts — CLI Tooling Overview

As of: 2026-08-03

lib/ currently holds five Python modules (three of them runnable CLI tools, two supporting libraries), plus one documentation-generator script that lives under doc/TRO_Katalog/tro_graphs/. Together the CLI tools turn a CSV export of the mechanical layout (ILS 2.0) into a material-flow graph, a derived TRO list/diagram, and an annotated copy of the BricsCAD drawing.

This document is the practical "what does each script do and which switches does it take" reference. For the underlying domain model (TRO types, JSON layout concept, I/O-list analysis) see TRO_Typen.md, Json_Layout-Konzept.md, EA-Listen-Analyse.md, BricsCAD_TRO_Symbol.md and doc/TRO_Katalog/TRO_Katalog.md.

1. How the pieces fit together

CSV export (in %SKEL_DATA%)
   │
   ▼
material_flow.py  ──►  <name>_material_flow.dot / .svg / .md
   │   (read_elements, build_graph — reused by tro_flow.py)
   ▼
tro_flow.py       ──►  <name>_tro_flow.dot / .svg, _tro_doc.md, _tro_errors.md
   │   (derives TROs, using the type catalog in tro_catalog.py)
   ▼
tro_annotate.py   ──►  <name>_annotated.dxf, <name>_registration.json
   (also needs the BricsCAD DXF; uses dxf_registration.py for the CSV↔DXF
    coordinate offset and tro_catalog.py for marker shape/color per TRO type)
  • material_flow.py models the material flow of the mechanical objects only (Gefällestrecke, Strecke, Kreisel).
  • tro_flow.py is its sister program: it derives the control objects (TROs) from the same graph and draws their flow instead.
  • tro_annotate.py takes the TROs from tro_flow.py and burns them into a copy of the BricsCAD drawing as attributed blocks (never touches the original).

Supporting libraries (no CLI of their own, imported by the tools above):

  • lib/tro_catalog.py — the single source of truth for TRO types: short name, Siemens FB block, sub-components and counts, color group, CAD marker shape.
  • lib/dxf_registration.py — derives, verifies and persists the rigid (rotation + offset) transform between the CSV export's coordinate system and the DXF drawing's.

Separate, documentation-only tool (not part of the generator pipeline):

  • doc/TRO_Katalog/tro_graphs/gen_tro_graphs.py — regenerates the schematic per-type SVGs, the edge-type legend and the per-controller (UH01UH05) topology graphs embedded in TRO_Katalog.md, built from doc/TRO_Katalog/connect.ini.

2. Running the scripts

Each CLI tool is invoked through its bin/<name>.bat (Windows) / bin/<name>.sh (Linux/macOS) wrapper, which:

  1. calls setenv to set SPS_SKEL, SKEL_DATA, SKEL_RESULTS, SKEL_CFG, SKEL_LIB and prepend SKEL_LIB to PYTHONPATH;
  2. activates .venv if it exists (bin/install_py creates it);
  3. runs the module with py (falling back to python).
bin\material_flow.bat --file mubea.csv --tosvg
bin\tro_flow.bat --file mubea.csv --tosvg --doc
bin\tro_annotate.bat --file mubea.csv --dxf 500573_60_1.dxf --flow --fb --legend

Conventions shared by all three tools:

  • --file / --dxf accept either a bare filename — resolved against %SKEL_DATA% — or a full path.
  • All generated output is written to %SKEL_RESULTS%.
  • tro_annotate.py additionally persists the verified CSV↔DXF coordinate offset to %SKEL_CFG%\dxf_registration.json.
  • Every run prints a ==== bordered report to stdout (counts, warnings, output file paths); non-fatal findings are printed as ?/! lines and also do not stop the run.
  • Requires the packages pinned in requirements.txt (pydantic>=2.0.0; ezdxf>=1.4.0 for tro_annotate.py only) — run bin\install_py.bat once.
  • --tosvg needs Graphviz's dot (or neato, for tro_flow.py --use-cords) on PATH, or the GRAPHVIZ_DOT environment variable pointing at the dot executable.

3. material_flow.py — material-flow graph of the mechanical layout

Reads the CSV export and builds a directed graph of the mechanical objects:

  • Gefällestrecke / Strecke (conveyor segments) → one node each.
  • Kreisel (rotary/turntable) → two nodes (-L / -R), linked by the Drehrichtung feature (UZS = clockwise = right→left, GUZ = counter-clockwise = left→right).
  • Separator / Scanner → no node of their own; shown via Zuordnung (assignment) on the label of their owning node.

Flow direction between conveyor segments is derived from height change (Hoehe_Von_mm/Hoehe_Bis_mm) or, failing that, from Antriebfahrtrichtung ("Auf"/"Ab"); connections whose direction can't be determined are drawn bidirectional and reported as a warning. --doc additionally cross-checks stated Anzahl_Separator/Anzahl_Scanner counts against what was actually attached.

Switch Argument Default Meaning
--file NAME export.csv CSV input file, resolved against %SKEL_DATA%, or a full path.
--tosvg off Also render the .dot file to .svg via Graphviz dot.
--doc off Also write a Markdown report (<name>_material_flow.md) with object list, connections and plausibility findings.

Output (in %SKEL_RESULTS%): <name>_material_flow.dot (always), <name>_material_flow.svg (with --tosvg), <name>_material_flow.md (with --doc).

Exit codes: 0 ok · 1 input/CLI error · 2 SVG rendering failed (Graphviz).

4. tro_flow.py — derive and draw the TROs

Sister program to material_flow.py — same --file/--tosvg/--doc switches, but instead of the mechanical objects it derives the TROs (Transfer Route Objects, i.e. control-logic units) from the same graph and draws their flow. Derivation rules (see doc/500573_Mubea/TRO_Identifikation_500573.md for the source analysis):

Host of the separator TRO type
Gefällestrecke, ≥ 2 lines sharing an in-/outfeed PinStore_Auto (one block per line group)
Gefällestrecke, single line 1Sep
Strecke (driven) Vario (one per segment)
Kreisel lane 1Sep
— additionally: 2 or 3 outgoing paths upgraded to 1Sep1Swi / 1Sep2Swi

A scanner mounted on a separator does not change the type (stays 1Sep); the 1Sep_SSCC special case can't be recognized from the mechanical layout alone and is only raised as a finding. TRO types, FB blocks, sub-components and colors all come from lib/tro_catalog.py — nothing is hard-coded here.

Switch Argument Default Meaning
--file NAME export.csv CSV input file, resolved against %SKEL_DATA%, or a full path.
--tosvg off Also render the TRO flow diagram to .svg.
--use-cords (alias --use-coords) off Place every TRO at the centroid of the components it was built from and render with neato -n (fixed positions) instead of dot's computed layout, so the diagram matches the plant layout. Only has an effect together with --tosvg; fails if any TRO has no coordinate.
--doc off Also write a Markdown report (<name>_tro_doc.md) with the TRO list, connections, findings and the full type catalog.

Output (in %SKEL_RESULTS%): <name>_tro_flow.dot (always, with pos attributes when --use-cords was used), <name>_tro_flow.svg (with --tosvg), <name>_tro_doc.md (with --doc), <name>_tro_errors.md (only if TROs are unconnected or of an unknown type).

Exit codes: 0 ok · 1 input/CLI error · 2 SVG rendering failed (Graphviz) · 3 TRO validation errors found (error file written).

5. tro_annotate.py — burn the TROs into a copy of the CAD drawing

Takes the CSV export, the original BricsCAD drawing (DXF) and the TROs derived the same way as tro_flow.py, and writes a copy of the drawing with:

  • one colored marker block per TRO, each type with its own shape (circle, triangle, square, diamond, …; see TroSymbol in tro_catalog.py) so types are distinguishable even without color;
  • visible attributes ID, TYPE (and FB_BLOCK with --fb); hidden attributes ITEMS, CONFIDENCE, SEPARATORS for downstream tooling;
  • optional directional flow arrows between TROs (--flow) and a legend (--legend).

The original drawing is never modified. Everything this tool adds lives on its own TRO_-prefixed layers and carries XDATA under the app id SPS_SKEL_TRO; a re-run removes exactly those tagged objects (not by layer name) and rebuilds them, so hand-drawn content on the same layers survives.

Once at least one marker of a given type has been annotated, the dxfmakros BricsCAD menu (SSG_LIB > TRO) can insert further markers of that type by hand — TRO_INSERT reuses the TRO_SYM_<Typ> block definition this tool created and only asks for a point, an id and (optionally) a different type; TRO_EDIT changes ID/TYPE on an existing marker. Neither command draws new shapes — a type with no prior annotated instance in the drawing must be run through this tool at least once first.

CSV and DXF live in different coordinate systems; the offset between them is handled by dxf_registration.py — derived once, verified on every run, and cached per CSV/DXF filename pair in %SKEL_CFG%\dxf_registration.json unless overridden.

Switch Argument Default Meaning
--file NAME export.csv CSV export, resolved against %SKEL_DATA%, or a full path.
--dxf NAME Original drawing as DXF (path, or name resolved against %SKEL_DATA%). Required unless --emit-lisp is used alone. DWG is not supported.
--out NAME <csv-stem>_annotated.dxf Output filename in %SKEL_RESULTS%.
--flow off Draw directional flow arrows between the TROs.
--fb off Show the Siemens FB block name as a visible attribute on the marker.
--legend off Draw a legend of the color groups.
--marker-size MM (float) 300.0 Marker radius in mm.
--text-height MM (float) 220.0 Text height in mm.
--layer-prefix P TRO_ Prefix for the layers this tool creates.
--offset DX,DY Set the CSV↔DXF offset by hand instead of deriving/loading it.
--re-register off Re-derive the coordinate offset even if a verified one is already cached in %SKEL_CFG%.
--max-residual MM (float) 600.0 Largest residual error of the coordinate registration that is still accepted; above it the run fails (exit 4).
--check off Dry run: only analyze and report, write no output file.
--emit-lisp off Regenerate cad/tro_types.lsp (the type list for the TRO_INSERT/TRO_EDIT dialogs) from tro_catalog.py and exit — no --dxf needed. Written under %DXFM_LISP% if set (next to the dxfmakros SSG_LIB modules that provide the dialogs), otherwise under <SPS_SKEL>/cad.

Output (in %SKEL_RESULTS%, unless --check): <name>_annotated.dxf, <name>_registration.json (the coordinate transform used, with its proof).

Exit codes: 0 ok · 1 input/CLI error · 4 coordinate registration could not be proven (or exceeds --max-residual) — resolve with --offset or by raising --max-residual.

6. tro_catalog.py — TRO type catalog (library, no CLI)

The single source of truth for everything needed to generate or draw a TRO type: short name (as used in FB_Main/connect.ini), Siemens FB block, sub-components and their counts, color group (for Graphviz/Mermaid/CAD) and CAD marker shape. Ten types are defined in TRO_CATALOG, verified against data/*.scl where the source is vendored locally and against TRO_Typen.md's mapping table otherwise (see the module docstring, CATALOG_AS_OF, for provenance per type). Everything is a Pydantic v2 model (TroDefinition/TroStyle), so it validates on every assignment and comes with model_dump()/model_validate() for the planned JSON layout model for free. Consumed by tro_flow.py and tro_annotate.py; not run directly.

7. dxf_registration.py — CSV↔DXF coordinate registration (library, no CLI)

Derives the rigid transform (rotation + offset, no scaling) between the CSV export's and the DXF drawing's coordinate systems, by voting on the offset between same-role anchor points (Separator and Scanner blocks, see ANCHOR_BLOCKS), refining the best candidates via a Procrustes fit, and picking the candidate with the most exact matches. Raises RegistrationError if fewer than MIN_INLIERS (5) exact matches are found for any candidate. Persists/loads the verified transform per CSV/DXF filename pair under %SKEL_CFG%\dxf_registration.json. Used exclusively by tro_annotate.py; not run directly.

8. gen_tro_graphs.py — documentation image generator (doc tooling, not part of the generator)

Lives under doc/TRO_Katalog/tro_graphs/, not lib/ — it produces the pictures embedded in TRO_Katalog.md, not generator output. Two families:

  1. one schematic SVG per TRO type showing the block with its possible connection edges (normal/dir2/dir3/bypass/finger/plc/extern, each with its own color and line style), plus a shared edge_legend.svg;
  2. one Graphviz topology graph per controller (uh01..uh05), built from doc/TRO_Katalog/connect.ini, rendered to SVG.

No command-line switches — run it directly and re-run after editing connect.ini:

py doc/TRO_Katalog/tro_graphs/gen_tro_graphs.py

Needs Graphviz dot on PATH (or at the default Windows install location); without it the .dot files are still written, just not rendered to .svg.