Document lib/ CLI tools and refresh CLAUDE.md to match
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>
This commit is contained in:
@@ -9,23 +9,33 @@ electrical layout (list of sensors, stoppers, switches, etc.) and generates a **
|
||||
of Siemens SCL code** ("TRO" — Transfer Route Object — blocks for a conveyor/material-flow
|
||||
control system) that can be imported directly into TIA Portal.
|
||||
|
||||
The repository is currently in the **design/analysis phase**: `lib/`, `tests/`, `examples/`,
|
||||
and `cfg/` are empty scaffolding directories (see "Standard Programm Template" structure
|
||||
below). No generator code has been written yet. What exists today is:
|
||||
The repository has moved past pure analysis: `lib/` now holds working Python tooling that
|
||||
derives a material-flow graph and a TRO list from a CSV export (ILS 2.0) and can annotate a
|
||||
copy of the BricsCAD drawing with the result. What does **not** exist yet is the actual
|
||||
SCL-skeleton generator — the step that would emit TIA-Portal-importable SCL from a JSON
|
||||
layout model. `tests/` and `examples/` are still empty scaffolding (see "Standard Programm
|
||||
Template" below). What exists today is:
|
||||
|
||||
- `bin/` — environment/venv management scripts (see "Environment scripts" below)
|
||||
- `data/*.scl` — real SCL code extracted from an existing plant ("HundM_Fortna", 5
|
||||
controllers UH01–UH05), used as reference templates for the planned generator
|
||||
- `bin/` — environment/venv management scripts, plus one `.bat`/`.sh` wrapper pair per CLI
|
||||
tool in `lib/` (see "Environment scripts" below)
|
||||
- `lib/*.py` — CLI tools and libraries that turn a CSV export + BricsCAD DXF into a
|
||||
material-flow graph, a derived TRO list/diagram, and an annotated copy of the drawing.
|
||||
See **`doc/Python_Scripts.md`** for what each script does and which switches it takes.
|
||||
- `data/` — input CSV exports (gitignored, not committed)
|
||||
- `cad/tro_types.lsp` — generated type list for the BricsCAD `TROEDIT` dialog (written by
|
||||
`tro_annotate.py --emit-lisp`)
|
||||
- `cfg/dxf_registration.json` — persisted, verified CSV↔DXF coordinate transform
|
||||
- `doc/*.md` — analysis documents that reverse-engineer the SCL patterns and propose the
|
||||
JSON schema / code-generation approach
|
||||
JSON schema / code-generation approach for the generator that's still to be written
|
||||
|
||||
Read `doc/` before writing any generator code — it contains the actual domain model this
|
||||
project is meant to implement.
|
||||
Read `doc/` before writing any generator code — start with `doc/Python_Scripts.md` for the
|
||||
existing tooling, then the domain-model documents below; together they contain the actual
|
||||
domain model this project is meant to implement.
|
||||
|
||||
## Environment scripts (bin/)
|
||||
|
||||
Every script has a `.bat` (Windows) and `.sh` (Linux/macOS) pair. **None of them invoke a
|
||||
concrete Python script** — they only manage the environment and virtualenv.
|
||||
Every script has a `.bat` (Windows) and `.sh` (Linux/macOS) pair. The four scripts below are
|
||||
environment/venv management only — they never invoke a concrete Python script:
|
||||
|
||||
| Script | Purpose |
|
||||
|---|---|
|
||||
@@ -34,6 +44,13 @@ concrete Python script** — they only manage the environment and virtualenv.
|
||||
| `activate_venv.bat` / `activate_venv.sh` | Calls `setenv`, activates `.venv` (errors if missing — run `install_py` first) |
|
||||
| `get_cmd.bat` / `get_cmd.sh` | Calls `setenv`, opens a new shell with the environment variables set |
|
||||
|
||||
**Convention:** every CLI tool added to `lib/` gets its own `.bat`/`.sh` wrapper pair in
|
||||
`bin/`, named after the module (e.g. `lib/tro_flow.py` → `bin/tro_flow.bat` /
|
||||
`bin/tro_flow.sh`). Each wrapper calls `setenv`, activates `.venv` if present, then runs the
|
||||
module with `py`/`python3 "%*"`/`"$@"`. This supersedes the old "env-only" rule — see
|
||||
`bin/material_flow.bat`, `bin/tro_flow.bat`, `bin/tro_annotate.bat` (+ `.sh`) for the current
|
||||
pattern, and `doc/Python_Scripts.md` for what each tool does and which switches it takes.
|
||||
|
||||
Typical workflow on Windows:
|
||||
|
||||
```
|
||||
@@ -48,13 +65,14 @@ bash bin/install_py.sh
|
||||
source bin/activate_venv.sh
|
||||
```
|
||||
|
||||
Requires Python 3.10+. `requirements.txt` currently has no real dependencies pinned yet
|
||||
(placeholders for `pydantic`, `pytest`).
|
||||
Requires Python 3.10+. `requirements.txt` pins `pydantic>=2.0.0` (used throughout `lib/`
|
||||
for validated models) and `ezdxf>=1.4.0` (DXF read/write, `tro_annotate.py` only); `pytest`
|
||||
is commented out as not yet needed.
|
||||
|
||||
There is no build/lint/test command configured yet — `tests/` is empty and no test
|
||||
runner or linter is set up. Once code exists in `lib/`, use `pytest` (already anticipated
|
||||
in `requirements.txt`) and set `PYTHONPATH` via `bin/setenv` first so imports resolve
|
||||
against `lib/`.
|
||||
runner or linter is set up. Once tests exist, use `pytest` (already anticipated in
|
||||
`requirements.txt`, just commented out) and set `PYTHONPATH` via `bin/setenv` first so
|
||||
imports resolve against `lib/`.
|
||||
|
||||
## Domain model (from doc/)
|
||||
|
||||
@@ -62,8 +80,12 @@ The target system is a Siemens TIA Portal / SCL project for automated conveyor/c
|
||||
routing, modeled around **TRO** (Transfer Route Object) blocks. Key documents, read in
|
||||
this order for onboarding:
|
||||
|
||||
1. **`doc/Json_Layout-Konzept.md`** — the core proposal: a JSON file as single source of
|
||||
truth (`plc`, `controlUnits`, `sensors[]`, `conveyors[]`, `tros[]`, `loadingBooms[]`,
|
||||
0. **`doc/Python_Scripts.md`** — the existing CLI tooling (`lib/material_flow.py`,
|
||||
`lib/tro_flow.py`, `lib/tro_annotate.py`, plus the `lib/tro_catalog.py` and
|
||||
`lib/dxf_registration.py` libraries they share): what each script does, its switches,
|
||||
inputs/outputs. This is working code, not a proposal — read it before touching `lib/`.
|
||||
1. **`doc/HundM/Json_Layout-Konzept.md`** — the core proposal: a JSON file as single source
|
||||
of truth (`plc`, `controlUnits`, `sensors[]`, `conveyors[]`, `tros[]`, `loadingBooms[]`,
|
||||
`emptyCarrBuffers[]`, `routing`, `jamAreas[]`, `scanners[]`, `connections[]`,
|
||||
`destinations[]`) from which the repetitive, per-topology SCL code in `FB_Main`,
|
||||
`FB_CallSensors`, `FC_Direction`, `FC_Call_Jams` would be generated.
|
||||
@@ -72,34 +94,48 @@ this order for onboarding:
|
||||
combinations of one base type (`1Sep` = one separator/stopper) plus reusable
|
||||
sub-blocks (`FB_ILS_STRO_Sep`, `FB_ILS_STRO_Switch`, `FB_ILS_STRO_Vario`,
|
||||
`FB_BarcodeReaderCognex`, `FB_CarrAccumulate1Sep`). Only `LoadingBoom` is structurally
|
||||
independent.
|
||||
3. **`doc/EA-Listen-Analyse.md`** — analyzes the raw I/O list Excel exports
|
||||
independent. `lib/tro_catalog.py` is the executable form of this catalog (name, FB
|
||||
block, sub-components, color, CAD symbol per type).
|
||||
3. **`doc/HundM/EA-Listen-Analyse.md`** — analyzes the raw I/O list Excel exports
|
||||
(`*_EA.xlsx`/`*_TIA.xlsx`/`*_WSCAD.xlsx`) and companion position/cabling JSON exports,
|
||||
and what can vs. cannot be auto-derived from them (signal naming prefixes `BG/SF/DI/BP`
|
||||
for inputs, `MB/MA/QA/DQ/FC/PF` for outputs; topology/timing/customCode cannot be
|
||||
derived from I/O lists alone — those must come from the JSON model or CAD symbol).
|
||||
4. **`doc/BricsCAD_TRO_Symbol.md`** — proposes a BricsCAD block symbol whose attributes
|
||||
feed the JSON `tros[]` entries; documents which fields are captured on the symbol vs.
|
||||
derived from drawing topology or type-based timing defaults.
|
||||
5. **`doc/SCL_Analyse_Standardisierung.md`** — cross-controller duplication analysis;
|
||||
4. **`doc/HundM/BricsCAD_TRO_Symbol.md`** — proposes a BricsCAD block symbol whose
|
||||
attributes feed the JSON `tros[]` entries; documents which fields are captured on the
|
||||
symbol vs. derived from drawing topology or type-based timing defaults.
|
||||
`lib/tro_annotate.py` implements a first version of this (marker blocks with `ID`/
|
||||
`TYPE`/`FB_BLOCK` attributes), plus the `TROEDIT` BricsCAD dialog (`cad/tro_types.lsp`,
|
||||
generated by `tro_annotate.py --emit-lisp`).
|
||||
5. **`doc/HundM/SCL_Analyse_Standardisierung.md`** — cross-controller duplication analysis;
|
||||
identifies ~22 blocks duplicated identically across all 5 controllers (candidates for
|
||||
a shared library) and flags "version chaos" areas (e.g. `FB_StockRemovalBLKModul*`
|
||||
variants) that should NOT be naively merged.
|
||||
6. **`doc/suggestion.md`** — a follow-up proposal to collapse the 7 `FB_ILS_MTRO_*`
|
||||
6. **`doc/HundM/suggestion.md`** — a follow-up proposal to collapse the 7 `FB_ILS_MTRO_*`
|
||||
variants into a single `FB_ILS_MTRO` block driven by an array/config descriptor
|
||||
instead of hand-duplicated numbered members (`...1`, `...2`, `Dir1..Dir4`). References
|
||||
a not-yet-written `lib/create_skel.py` (`guess_fbtype()`) as the intended generator
|
||||
entry point — this is the planned shape of the generator, not existing code.
|
||||
entry point — this is still the planned shape of the SCL-emitting generator itself;
|
||||
the current `lib/` tooling derives TROs from a layout but does not yet emit SCL.
|
||||
7. **`doc/500573_Mubea/TRO_Identifikation_500573.md`** — the derivation rules
|
||||
`lib/tro_flow.py` implements: how to infer a TRO's type from its separator's host
|
||||
object (Gefällestrecke/Strecke/Kreisel) when no I/O list or `FB_Main` exists yet.
|
||||
8. **`doc/TRO_Katalog/TRO_Katalog.md`** — central image/concept catalog per TRO type
|
||||
(schematic, real layout image, SCL template, JSON example, CAD symbol attributes);
|
||||
its generated images come from `doc/TRO_Katalog/tro_graphs/gen_tro_graphs.py`
|
||||
(doc-tooling, not part of the generator — see `doc/Python_Scripts.md` §8) built from
|
||||
`doc/TRO_Katalog/connect.ini`.
|
||||
|
||||
### Used libraries (referenced but not vendored)
|
||||
|
||||
Most `FB_ILS_MTRO_*` types exist in this repo **only as `.liblink`** references to an
|
||||
external `ILSLib` library — the actual FB source is not in this Git repo. `data/*.scl`
|
||||
contains the real **call-site/instantiation code** (parametrization in `FB_Main`) for
|
||||
those types, not the FB body. Only a few types have local, fully-vendored SCL source
|
||||
(`FB_ILS_MTRO_Vario_workStation`, `FB_EmptyCarrBuffer`, `FB_LoadingBoom_INBOUND`,
|
||||
`FB_ILS_MTRO_2Sep1Swi` — the last one unused/orphaned). Treat `data/*.scl` as **read-only
|
||||
reference material** for pattern extraction, not code to execute or modify.
|
||||
external `ILSLib` library — the actual FB source is not in this Git repo.
|
||||
`doc/TRO_Katalog/scl_templates/*.scl` contains the real **call-site/instantiation code**
|
||||
(parametrization in `FB_Main`) for those types, not the FB body. Only a few types have
|
||||
local, fully-vendored SCL source (`FB_ILS_MTRO_Vario_workStation`, `FB_EmptyCarrBuffer`,
|
||||
`FB_LoadingBoom_INBOUND`, `FB_ILS_MTRO_2Sep1Swi` — the last one unused/orphaned). Treat
|
||||
`doc/TRO_Katalog/scl_templates/*.scl` as **read-only reference material** for pattern
|
||||
extraction, not code to execute or modify.
|
||||
|
||||
## Standard Programm Template
|
||||
|
||||
@@ -107,18 +143,24 @@ This project follows the user's standard Python project scaffold convention:
|
||||
|
||||
```
|
||||
sps_skel/
|
||||
bin/ environment scripts (see above)
|
||||
cfg/ config files (INI/JSON) — empty for now
|
||||
data/ input data, gitignored except the .scl reference templates
|
||||
doc/ documentation
|
||||
bin/ environment scripts, plus one .bat/.sh wrapper pair per lib/ CLI tool
|
||||
cad/ generated BricsCAD LISP support (tro_types.lsp) for the TROEDIT dialog
|
||||
cfg/ config files (INI/JSON); dxf_registration.json holds the persisted,
|
||||
verified CSV<->DXF coordinate transform
|
||||
data/ input CSV exports — gitignored, not committed
|
||||
doc/ documentation — see doc/Python_Scripts.md for the CLI tools, plus the
|
||||
domain-model documents listed above
|
||||
examples/ example files — empty for now
|
||||
lib/ Python source — empty for now, this is where the generator belongs
|
||||
lib/ Python source, importable via SKEL_LIB on PYTHONPATH — CLI tools and
|
||||
libraries that derive material flow / TRO lists / CAD annotations from a
|
||||
layout (see doc/Python_Scripts.md); the JSON-driven SCL generator itself
|
||||
is not yet written
|
||||
log/ gitignored
|
||||
results/ gitignored
|
||||
results/ gitignored — CLI tool output (.dot/.svg/.md/.dxf)
|
||||
tests/ unit tests — empty for now
|
||||
```
|
||||
|
||||
When adding the generator, put it under `lib/` (importable via `SKEL_LIB` on
|
||||
`PYTHONPATH`), keep `bin/*.bat`/`*.sh` scripts environment-only (do not add
|
||||
project-specific script invocations to them per the user's convention), and add tests
|
||||
under `tests/`.
|
||||
When adding the SCL generator, put it under `lib/` (importable via `SKEL_LIB` on
|
||||
`PYTHONPATH`), add a `bin/<name>.bat`/`.sh` wrapper pair for it following the pattern of
|
||||
`bin/tro_flow.bat`/`.sh` (see "Environment scripts" above), document its switches in
|
||||
`doc/Python_Scripts.md`, and add tests under `tests/`.
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
# 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`.
|
||||
Reference in New Issue
Block a user