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

258 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`).
```bat
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`.