8b4619cf9f
Add doc/Python_Scripts.md covering material_flow.py, tro_flow.py, tro_annotate.py, tro_catalog.py and dxf_registration.py: purpose, CLI switches, outputs and exit codes. Update CLAUDE.md, which still described lib/ and doc/ as empty design-phase scaffolding: reflect the working tooling, the doc/ reorganization (HundM/, 500573_Mubea/, TRO_Katalog/), the moved SCL templates, and the now-accepted bin/<tool>.bat+.sh wrapper convention. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
250 lines
13 KiB
Markdown
250 lines
13 KiB
Markdown
# 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
|
||
(UH01–UH05) 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.
|
||
|
||
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 `TROEDIT` dialog) 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 dialog), 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`.
|