validate_anlage, stabiler TRO-Schluessel, Verbindungen aus BricsCAD, Zeichnung aus der Anlagen-JSON

- validate_anlage.py (+ bin-Wrapper): Pruefung vor der SCL fuer beide Wege
  (Struktur, Zuordnungen, Aktualitaet der JSON, Korrekturen ohne Ziel);
  scl_skeleton ruft sie auf (Warnung, --strict bricht ab)
- DerivedTro.key: stabiler Schluessel (ID der ID-Datei); hw_overrides.ini,
  <csv>_jam_names.ini und tro_overrides.ini greifen ueber ID oder Schluessel,
  eine Umbenennung in TRO_EDIT laesst sie bestehen; JAM_AREA traegt KEY
- --read-tros liest die CONNECTION_ARROW-Bloecke mit -> [<csv>.edit_connections];
  tro_flow.apply_connection_edits wendet sie nach link_tros an
- tro_annotate --anlage zeichnet Marker/Verbindungen aus der Anlagen-JSON
- INI-Korrekturen auch mit BOM lesbar (utf-8-sig)
- Ablauf CSV/DXF+TIA -> Anlagen-JSON -> (BricsCAD) -> SCL in doc/Python_Scripts.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 14:32:10 +01:00
parent 6c8c235287
commit 1ac17b95e2
13 changed files with 1100 additions and 48 deletions
+90 -3
View File
@@ -63,7 +63,40 @@ parked: tro_extract.py drawing ──► JSON (not extended; see §5a)
The drawing is a **view** for checking the result, not a data source: the
TRO-JSON is written by `tro_flow.py --json` straight from the CSV, and
`tro_annotate.py` derives exactly the same TROs to draw them.
`tro_annotate.py` derives exactly the same TROs to draw them — with
`--anlage` it draws the plant JSON itself (since 2026-10-27).
### The workflow, step by step (since 2026-10-27)
The plant JSON `<name>_anlage.json` is the **unified JSON**: layout (TROs,
connections, jam areas) + hardware bindings. It is always **regenerated**;
corrections made by people live in INI overlays in `%SKEL_CFG%` that are
keyed on stable IDs and survive a new CSV export:
| Overlay | Written by | Applied by | Keyed on |
|---|---|---|---|
| `tro_overrides.ini` `edit`/`edit_add`/`edit_connections` | `tro_annotate --read-tros` | `tro_flow` (and `tro_annotate`) | TRO key (`DerivedTro.key`) |
| `<csv>_jam_names.ini` | `tro_annotate --read-jams` | `scl_skeleton`, `tro_annotate` | `<TRO key>.<entry>` |
| `hw_overrides.ini` | by hand | `merge_hw_layout` | TRO ID **or** key |
```
1 tro_flow --file <csv> --json CSV -> <csv>_tro.json
2 hw_import --tia <x>_TIA.xlsx --positions|--dxf E-plan + TIA -> <projekt>_hw.json
3 merge_hw_layout --tro <csv>_tro.json --hw <projekt>_hw.json -> <csv>_anlage.json
4 validate_anlage --json <csv>_anlage.json ready for SCL? (§5f)
Path A (no changes): scl_skeleton --json <csv>_anlage.json [--templates] [--strict]
Path B (changes): tro_annotate --file <csv> --dxf <dwg>.dxf --flow --anlage <csv>_anlage.json
... edit in BricsCAD (TRO_EDIT, TRO_INSERT, JAM_EDIT,
CONNECTION_INSERT/_EDIT, delete markers/arrow blocks), save as DXF
tro_annotate --file <csv> --read-tros -> tro_overrides.ini
tro_annotate --file <csv> --read-jams -> <csv>_jam_names.ini
then steps 1, 3, 4 again, then Path A
```
`scl_skeleton` runs the step-4 check itself (warns; `--strict` aborts on
errors), so an outdated plant JSON — e.g. step 3 forgotten after step 1 — is
reported, not silently turned into SCL.
- `material_flow.py` models the material flow of the **mechanical** objects only
(Gefällestrecke, Strecke, Kreisel).
@@ -467,7 +500,36 @@ falls back to the nearest part of the same kind at that spot. The sections
replace all earlier `edit`/`edit_add` sections of the CSV in
`tro_overrides.ini` (a `reason =` added by hand is kept); the rest of the file
stays line for line. The next `tro_flow` / `tro_annotate` run applies them
(§4); a re-read of the new drawing gives the same sections. `--check` only
(§4); a re-read of the new drawing gives the same sections.
**Connections (since 2026-10-27).** `--read-tros` also reads every
`CONNECTION_ARROW` block. Each end is matched to a marker of the same drawing
by its visible name (`FROM_TRO`/`TO_TRO`), else by the internal number
(`FROM_UID`/`TO_UID`; older dxfmakros blocks `FROM_ID`/`TO_ID`) — so arrows
still point right after a marker was renamed. The arrows are compared with the
derivation *including* the TRO corrections (edges of a new or edited TRO do not
count as hand-drawn); the differences go to `[<csv>.edit_connections]` as
`+ KEY_A -> KEY_B | kind` / `- KEY_A -> KEY_B`, ends as stable keys.
`tro_flow.apply_connection_edits` applies them after `link_tros` and resets
predecessors/successors, so the jam areas follow. Station arrows carry no
block and stay as derived; an arrow is deleted by deleting its block. Before
this, `CONNECTION_INSERT`/`_EDIT` in dxfmakros wrote attribute names the
blocks did not have (`ID`/`FROM_ID`/`TO_ID`, marker name from `TRO_ID`) — fixed
there on the same day.
**Stable key (since 2026-10-27).** Every TRO in the TRO-JSON carries `key`,
its ID in `<csv>_tro_ids.ini` (or, for a TRO added in BricsCAD, its own ID).
It differs from `id` only after a rename in `TRO_EDIT`. All corrections are
resolved by ID **or** key (`TroDocument.resolve`, `scl_context.jam_override`),
so a rename does not orphan `hw_overrides.ini` or `<csv>_jam_names.ini`
entries. Jam blocks carry a hidden `KEY` (`<TRO key>.<entry>`) that
`--read-jams` writes; an entry under the old display ID is moved to the key.
**With `--anlage` the drawing shows the plant JSON** (since 2026-10-27):
markers, connections and stations come from `anlage.layout`
(`analysis_from_document`), i.e. exactly what becomes SCL. The CSV is still
read for the registration and the parts table; if its derivation differs from
the JSON, a warning says the JSON is probably outdated. `--check` only
reports. If the drawing has no marker of the derived TROs (wrong file, or
annotated before the `KEY`/`SLOTS` attributes), nothing is written —
re-annotating an old drawing adds the missing attributes to the existing
@@ -496,7 +558,7 @@ verified on every run, and cached per CSV/DXF filename pair in
| `--emit-lisp` | — | off | Regenerate `cad/tro_types.lsp` for the `TRO_INSERT`/`TRO_EDIT` dialog — type list (`*TRO-TYPES*`), slots per type with the storage-line default (`*TRO-SLOTS*`), part kinds per slot (`*TRO-SLOT-KINDS*`) — from `tro_catalog.py`/`model.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`. |
| `--anlage` | `NAME` | — | Plant JSON (`<csv>_anlage.json` from `merge_hw_layout`, in `%SKEL_RESULTS%` or a path): also draw the **jam areas** (see below). Must belong to the same CSV. |
| `--read-jams` | `[DXF]` | `<csv>_annotated.dxf` | Read the jam-area numbers edited in BricsCAD back from the annotated drawing (saved as DXF) into `%SKEL_CFG%\<csv>_jam_names.ini`, then exit — no `--dxf` needed. |
| `--read-tros` | `[DXF]` | `<csv>_annotated.dxf` | Read the TRO markers edited in BricsCAD (`TRO_EDIT`/`TRO_INSERT`, deleted markers) back from the annotated drawing (saved as DXF) into the `edit`/`edit_add` sections of `%SKEL_CFG%\tro_overrides.ini`, then exit — no `--dxf` needed. With `--check` only reported. |
| `--read-tros` | `[DXF]` | `<csv>_annotated.dxf` | Read the TRO markers edited in BricsCAD (`TRO_EDIT`/`TRO_INSERT`, deleted markers) and the connection blocks (`CONNECTION_INSERT`/`_EDIT`, deleted blocks) back from the annotated drawing (saved as DXF) into the `edit`/`edit_add`/`edit_connections` sections of `%SKEL_CFG%\tro_overrides.ini`, then exit — no `--dxf` needed. With `--check` only reported. |
**Jam areas (`--anlage`).** One block `JAM_AREA` per jam area of the plant
JSON on layer `TRO_JAM`: an upright grey rectangle with the name written
@@ -1007,6 +1069,31 @@ fingerprint of the stored registration, CLI end to end with a real offset,
merged drawing without registration, two drive TROs on one conveyor, Dematic
rules file).
## 5f. `validate_anlage.py` — is the plant JSON ready for SCL?
One check for both paths of the workflow (§1): directly after
`merge_hw_layout` and after BricsCAD corrections have been read back and the
JSON rebuilt. `scl_skeleton` calls it before writing (findings as warnings;
with `--strict`, errors stop the run). Works on a plant JSON and, reduced, on
a TRO-JSON.
| Area | ERROR (no SCL like this) | WARNING (SCL with open spots) |
|---|---|---|
| Structure | duplicate TRO-ID, type not in catalog, connection or jam area to an unknown TRO, separator in two TROs | separator slot without layout part, TRO without connection, TRO not reachable from the material entry |
| Bindings | binding to an unknown TRO/slot, status `widerspruch`, BMK missing in `<projekt>_hw.json` | open mandatory roles (counted per role) |
| Freshness | plant JSON older than TRO-JSON, hardware planning or `hw_overrides.ini` (only if it has sections for this CSV) → run `merge_hw_layout` again | `tro_overrides.ini` with BricsCAD corrections newer than the TRO-JSON → run `tro_flow --json` again |
| Corrections | — | entries in `hw_overrides.ini` / `<csv>_jam_names.ini` that match no TRO/jam area, neither by ID nor by key |
| Switch | Argument | Default | Meaning |
|---|---|---|---|
| `--json` | `NAME` | — | Plant JSON (or TRO-JSON) in `%SKEL_RESULTS%`, or a path. |
| `--hw` | `NAME` | `hwFile` of the plant JSON | Hardware planning for the BMK check. |
| `--strict` | — | off | Warnings also make the JSON "not ready". |
**Exit codes:** `0` ready · `1` input error · `5` not ready.
Mubea on 2026-10-27: the plant JSON in `results/` was reported older than the
TRO-JSON — exactly the TRO18/TRO19 mismatch `tro_annotate --anlage` showed.
## 6. `tro_catalog.py` — TRO type catalog (library, no CLI)
The single source of truth for everything needed to generate or draw a TRO