model.py: gemeinsames TRO-Modell; Hauptweg CSV -> tro_flow --json -> scl_skeleton
- lib/model.py (neu, pydantic): TroBase -> DerivedTro, Connection, OpenPoint, Analysis (aus tro_flow verschoben), TroDocument = TRO-JSON (Schema sps_skel-tro-v2). items/fbType werden immer ueber den Typ aus tro_catalog gelesen, nie gespeichert; abweichende Werte in einer JSON sind ein Fehler. JSON-Schluessel wie bisher (id, type, fbType ...), extra="forbid". - tro_flow: Tro/Analysis aus model.py; neuer Schalter --json schreibt <name>_tro.json (TroDocument) - scl_skeleton: liest die JSON ueber TroDocument statt per Dict-Zugriff, Bauteile ueber TroItem-Konstanten; ungueltige JSON -> Exit 1 ohne SCL, alte tro_extract-JSON (v1) mit Hinweis auf tro_flow --json - tro_annotate: nur noch Ansicht; derselbe analyse_tros-Aufruf wie tro_flow (inkl. sepliste-Gegenprobe), damit Zeichnung und JSON uebereinstimmen - tro_extract: geparkt (unveraendert) - tests/test_model.py + conftest.py, pytest in requirements.txt aktiviert - Doku: Python_Scripts.md (§6b model.py), Commandlines.md, CLAUDE.md, Aufrufkommentare in bin/ (scl_skeleton.bat zeigte tro_flow-Aufrufe) Geprueft: alle tro_flow/tro_annotate-Ausgaben (8 CSVs) bis auf Zeitstempel identisch zum vorherigen Stand; scl_skeleton alt/neu auf derselben JSON byte-identisch (export, mubea, HundM05); 10 Tests gruen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
90cafec99c
commit
97a0db6707
@@ -10,22 +10,24 @@ of Siemens SCL code** ("TRO" — Transfer Route Object — blocks for a conveyor
|
||||
control system) that can be imported directly into TIA Portal.
|
||||
|
||||
The repository has moved past pure analysis: `lib/` now holds working Python tooling that
|
||||
runs the **full DXF → JSON → SCL pipeline in a first version**. From a CSV export (ILS 2.0)
|
||||
it derives a material-flow graph and a TRO list, annotates a copy of the BricsCAD drawing
|
||||
with the result, reads the (possibly hand-edited) drawing back into a TRO-JSON, and emits an
|
||||
`FB_Main` **SCL skeleton** from that JSON. The skeleton is deliberately not a running
|
||||
runs the **full CSV → TRO-JSON → SCL pipeline in a first version**. From a CSV export (ILS
|
||||
2.0) it derives a material-flow graph and a TRO list, writes the TROs as a TRO-JSON defined
|
||||
by the shared pydantic model `lib/model.py`, and emits an `FB_Main` **SCL skeleton** from
|
||||
that JSON. A copy of the BricsCAD drawing annotated with the same TROs serves as a viewer
|
||||
for visual checking; it is no longer a data source. The skeleton is deliberately not a running
|
||||
program — every value that must come from the electrical planning is left as a visible
|
||||
`TODO(E-Planung)` gap rather than guessed. What is **not** done yet is the fuller layout-JSON
|
||||
schema (`doc/HundM/Json_Layout-Konzept.md`) as an intermediate format and the generation of
|
||||
the other per-controller blocks (`FB_CallSensors`, `FC_Direction`/`FC_Call_Jams` as
|
||||
standalone files); see "Roadmap" below. `tests/` and `examples/` are still empty scaffolding
|
||||
(see "Standard Programm Template" below). What exists today is:
|
||||
standalone files); see "Roadmap" below. `tests/` holds the first tests
|
||||
(`tests/test_model.py`); `examples/` is still empty scaffolding (see "Standard Programm
|
||||
Template" below). What exists today is:
|
||||
|
||||
- `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, an annotated copy of the drawing, a
|
||||
TRO-JSON read back out of that drawing, and an `FB_Main` SCL skeleton.
|
||||
- `lib/*.py` — CLI tools and libraries that turn a CSV export into a material-flow graph,
|
||||
a derived TRO list/diagram, a TRO-JSON (`lib/model.py`), an `FB_Main` SCL skeleton, and
|
||||
(with the BricsCAD DXF) an annotated copy of the drawing for visual checking.
|
||||
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
|
||||
@@ -73,13 +75,12 @@ source bin/activate_venv.sh
|
||||
```
|
||||
|
||||
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.
|
||||
for validated models), `ezdxf>=1.4.0` (DXF read/write, `tro_annotate.py` only) and
|
||||
`pytest>=9.0.0`.
|
||||
|
||||
There is no build/lint/test command configured yet — `tests/` is empty and no test
|
||||
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/`.
|
||||
Tests: `python -m pytest tests/` with `.venv` active. `tests/conftest.py` puts `lib/` on
|
||||
`sys.path`, so `bin/setenv` is not required for the tests. No build step or linter is set
|
||||
up.
|
||||
|
||||
## Domain model (from doc/)
|
||||
|
||||
@@ -89,8 +90,8 @@ this order for onboarding:
|
||||
|
||||
0. **`doc/Python_Scripts.md`** — the existing CLI tooling (`lib/material_flow.py`,
|
||||
`lib/tro_flow.py`, `lib/tro_annotate.py`, `lib/tro_extract.py`, `lib/scl_skeleton.py`,
|
||||
plus the `lib/tro_catalog.py`, `lib/dxf_registration.py` and `lib/tro_overrides.py`
|
||||
libraries they share): what each script does, its switches, inputs/outputs. This is
|
||||
plus the `lib/tro_catalog.py`, `lib/model.py`, `lib/dxf_registration.py` and
|
||||
`lib/tro_overrides.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[]`,
|
||||
@@ -146,19 +147,20 @@ local, fully-vendored SCL source (`FB_ILS_MTRO_Vario_workStation`, `FB_EmptyCarr
|
||||
`doc/TRO_Katalog/scl_templates/*.scl` as **read-only reference material** for pattern
|
||||
extraction, not code to execute or modify.
|
||||
|
||||
## Roadmap: DXF → JSON → SCL (first version implemented)
|
||||
## Roadmap: CSV → TRO-JSON → SCL (first version implemented)
|
||||
|
||||
The DXF → JSON → SCL pipeline now runs end-to-end in a first version. After `tro_annotate.py`
|
||||
burns the TROs into a copy of the drawing, the user can hand-edit that DXF in BricsCAD (via
|
||||
the `TRO_INSERT`/`TRO_EDIT` commands, see `doc/HundM/BricsCAD_TRO_Symbol.md`) — moving TROs,
|
||||
adding new ones, changing a type — and two further `lib/` tools carry the drawing the rest of
|
||||
the way to importable SCL:
|
||||
Since 2026-10-09 the main path is **CSV → `tro_flow.py --json` → TRO-JSON →
|
||||
`scl_skeleton.py` → SCL**. Layer order (who may import whom): `tro_catalog.py` (TRO *types*)
|
||||
← `lib/model.py` (TRO *instances* and the TRO-JSON: `TroBase` → `DerivedTro`, `Connection`,
|
||||
`OpenPoint`, `Analysis`, `TroDocument`) ← derivation (`material_flow.py`, `tro_flow.py`) ←
|
||||
outputs (`scl_skeleton.py`, `tro_annotate.py`, reports). `items`/`fbType` are always read
|
||||
from the catalog via the TRO type, never stored. See `doc/Python_Scripts.md` §6b.
|
||||
|
||||
1. **`lib/tro_extract.py`** (implemented) — reads the (possibly hand-edited) annotated DXF
|
||||
**only** (not the CSV) and derives a TRO-JSON (`<drawing>_tro.json`): the TROs tagged with
|
||||
XDATA, their `predecessors`/`successors` computed from the flow arrows, and plant
|
||||
coordinates resolved through the persisted registration. See `doc/Python_Scripts.md` §5a.
|
||||
2. **`lib/scl_skeleton.py`** (implemented) — reads that TRO-JSON and emits an `FB_Main` SCL
|
||||
1. **`lib/tro_flow.py --json`** (implemented) — writes `<csv>_tro.json` (schema
|
||||
`sps_skel-tro-v2`, `model.TroDocument`): TROs, system boundaries `SYSn`, connections with
|
||||
their kind, findings. See `doc/Python_Scripts.md` §4.
|
||||
2. **`lib/scl_skeleton.py`** (implemented) — reads that TRO-JSON through `TroDocument` (a
|
||||
wrong/renamed key or `items` not matching the catalog stops the run) and emits an `FB_Main` SCL
|
||||
skeleton (`<source>_FB_Main.scl`): one `REGION` per TRO with the instance call and every
|
||||
parameter line in the right order, plus inline `FC_Direction` calls for switch TROs.
|
||||
Everything derivable from the layout is filled (REGION order, FB type, parameter-block
|
||||
@@ -166,20 +168,27 @@ the way to importable SCL:
|
||||
everything that must come from the electrical planning is a `TODO(E-Planung)` gap.
|
||||
Switches `--json`, `--out`, `--start` (the last picks an entry point while the plant is a
|
||||
closed loop with no loading/unloading station). See `doc/Python_Scripts.md` §5b.
|
||||
3. **`lib/tro_annotate.py`** — **viewer only**: draws the same TROs (same `analyse_tros`
|
||||
call as `tro_flow.py`) into a copy of the DXF for a visual check in BricsCAD.
|
||||
4. **`lib/tro_extract.py`** — **parked**: reads the annotated DXF back into the old
|
||||
`sps_skel-tro-extract-v1` JSON, which `scl_skeleton.py` no longer accepts. Not deleted, not
|
||||
extended; if drawing edits (`TRO_INSERT`/`TRO_EDIT`) are ever needed again, it should
|
||||
write `model.TroDocument`. See `doc/Python_Scripts.md` §5a.
|
||||
|
||||
What is **not** built out yet, relative to the original two-tool design:
|
||||
|
||||
- the fuller **layout-JSON schema** of `doc/HundM/Json_Layout-Konzept.md` (`plc`,
|
||||
`controlUnits`, `sensors[]`, `conveyors[]`, `tros[]`, `loadingBooms[]`,
|
||||
`emptyCarrBuffers[]`, `routing`, `jamAreas[]`, `scanners[]`, `connections[]`,
|
||||
`destinations[]`) as the intermediate format — `tro_extract.py` currently emits a
|
||||
TRO-focused JSON, not this full schema;
|
||||
`destinations[]`) as the intermediate format — `model.TroDocument` is a TRO-focused
|
||||
JSON, not this full schema yet;
|
||||
- the **other per-controller blocks** (`FB_CallSensors`, `FC_Direction`/`FC_Call_Jams` as
|
||||
standalone files) — only `FB_Main` is generated today;
|
||||
- **type-based timing defaults** from `doc/TRO_Typen.md` and the `OVERRIDE_TIMING_JSON` CAD
|
||||
attribute (timings are emitted as `TODO(E-Planung): pruefen` placeholders for now);
|
||||
- a **`--skip-json`** convenience path that would read DXF + CSV directly and emit SCL
|
||||
without an intermediate JSON file.
|
||||
- `tro_overrides.py` using the shared `model.Connection` / `model.OpenPoint` classes;
|
||||
- `Component` classes per part type (Separator, Switch, Scanner, VarioDrive, …) on the TRO,
|
||||
driving the per-part SCL emitters in `scl_skeleton.py`.
|
||||
|
||||
Note the `create_skel.py` / `guess_fbtype()` generator sketched in `doc/HundM/suggestion.md`
|
||||
and `doc/HundM/Json_Layout-Konzept.md` §14.5 is a **separate concept** and is not implemented
|
||||
@@ -203,12 +212,12 @@ sps_skel/
|
||||
domain-model documents listed above
|
||||
examples/ example files — empty for now
|
||||
lib/ Python source, importable via SKEL_LIB on PYTHONPATH — CLI tools and
|
||||
libraries that derive material flow / TRO lists / CAD annotations from a
|
||||
layout, read the TROs back into JSON, and emit an FB_Main SCL skeleton
|
||||
(see doc/Python_Scripts.md)
|
||||
libraries that derive material flow / TRO lists from a layout, write
|
||||
them as TRO-JSON (model.py), emit an FB_Main SCL skeleton, and draw
|
||||
the TROs into the CAD drawing (see doc/Python_Scripts.md)
|
||||
log/ gitignored
|
||||
results/ gitignored — CLI tool output (.dot/.svg/.md/.dxf/.scl/.json)
|
||||
tests/ unit tests — empty for now
|
||||
tests/ unit tests (pytest) — test_model.py for the TRO-JSON model
|
||||
```
|
||||
|
||||
When extending the pipeline (the remaining pieces in "Roadmap" above), put new modules under
|
||||
|
||||
Reference in New Issue
Block a user