Files
sps_skel/CLAUDE.md
T
Michael StanglandClaude Opus 5.5 0115ef68b7 TRO-JSON v4: Slots je TRO und Staubereiche (jamAreas)
- model: Slot (separator/switch/scanner/drive + Rollen), JamArea (J<Separator>,
  Eingang eines TRO mit allen Vorgaengern), derive_slots, derive_jam_areas;
  Schema sps_skel-tro-v4, v3-Dateien werden weiter gelesen
- scl_context: ein JamEntr je eigenem Staubereich statt je Vorgaenger (wie
  UH01-UH05), Ausgaenge nennen den Staubereich des Nachfolgers
- Golden Files neu erzeugt, Tests fuer Slots/Staubereiche, Doku nachgezogen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:44:02 +02:00

17 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project purpose

sps_skel takes a mechanical layout (from project planning/sales) together with an electrical layout (list of sensors, stoppers, switches, etc.) and generates a skeleton 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 has moved past pure analysis: lib/ now holds working Python tooling that 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/ 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 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; lib/e_planning.py assigns the E-planning's sensors/valves (from the cable-length tool's *_positionsdraw.json) to the layout parts so the skeleton can carry real names. 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; cfg/tro_overrides.ini — hand-maintained corrections to the derived TROs (see tro_overrides.py); cfg/e_planning.ini — project-specific rules for assigning E-planning symbols to layout parts; cfg/<csv>_tro_ids.ini — per-plant TRO-ID file (versioned, IDs renamed by the SPS programmers), created/extended by tro_flow.py via lib/tro_ids.py
  • doc/*.md — analysis documents that reverse-engineer the SCL patterns and propose the fuller JSON layout schema for the parts of the pipeline still to be built out

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. The four scripts below are environment/venv management only — they never invoke a concrete Python script:

Script Purpose
setenv.bat / source setenv.sh Sets SPS_SKEL (project root) and SKEL_BIN/LIB/CFG/DATA/LOG/RESULTS/EXAMPLES/TESTS; prepends SKEL_LIB to PYTHONPATH; creates missing folders
install_py.bat / install_py.sh Calls setenv, creates .venv (py -m venv / python3 -m venv), installs requirements.txt. Aborts with a message if .venv already exists
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:

bin\install_py.bat          # one-time: create venv + pip install
bin\activate_venv.bat       # each session: activate venv + show versions

Linux/macOS equivalents must be sourced, not executed:

bash bin/install_py.sh
source bin/activate_venv.sh

Requires Python 3.10+. requirements.txt pins pydantic>=2.0.0 (used throughout lib/ for validated models), ezdxf>=1.4.0 (DXF read/write, tro_annotate.py only) and pytest>=9.0.0.

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/)

The target system is a Siemens TIA Portal / SCL project for automated conveyor/carrier routing, modeled around TRO (Transfer Route Object) blocks. Key documents, read in this order for onboarding:

  1. 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, lib/e_planning.py, 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/.
  2. 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.
  3. doc/TRO_Typen.md — catalogs all 10 TRO function-block types actually found across the 5 reference controllers (UH01–UH05) and shows that 9 of them are additive 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. lib/tro_catalog.py is the executable form of this catalog (name, FB block, sub-components, color, CAD symbol per type).
  4. 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).
  5. 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).
  6. 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.
  7. 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 lib/create_skel.py (guess_fbtype()) as the intended generator entry point. That specific module does not exist in this repo — it is the HundM Excel-based generator sketch, a different input source (see "Roadmap" below). This repo's own SCL emitter is lib/scl_skeleton.py, which already emits an FB_Main skeleton from the TRO-JSON.
  8. 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.
  9. 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.
  10. doc/Datenquellen_Layout_Hardwareplanung.md — which TRO/SCL data comes from the mechanical layout (CSV), which from the hardware planning (EA list, TIA import, WSCAD, positionsdraw) and which is a default; two reference call sites annotated line by line. The full raw field lists of both sources are in doc/Klassenhierarchie.md, chapter "Daten".
  11. doc/Konzept_Layout_Hardware_SCL.md — the target workflow (planned, not built): layout → <csv>_tro.json (with slots, jamAreas), hardware planning → hw_import.py → <projekt>_hw.json, hw_assign.py → <csv>_anlage.json, then scl_skeleton.py; what happens to e_planning.py (split), tro_annotate.py (viewer reading the JSON) and tro_extract.py (dropped).

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. 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.

Roadmap: CSV → TRO-JSON → SCL (first version implemented)

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, TroCandidate, 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. Inside the SCL output, lib/scl_context.py (TRO-JSON → render context, all derivations) sits between model.py and scl_skeleton.py (context → text only). With --templates (opt-in) REGIONs come from Jinja2 templates in lib/scl_templates/<fbType>.scl.j2 (pilot: FB_ILS_MTRO_1Sep1Swi), each round-trip tested against its reference call site in doc/TRO_Katalog/scl_templates/ (tests/test_scl_templates.py); every line holding a placeholder must carry TODO(E-Planung). Migration steps, decisions per template line and status: doc/SCL_Templates.md. Golden files in tests/fixtures/scl/ pin the SCL output byte for byte — rewrite them (SKEL_UPDATE_GOLDEN=1) only for a reviewed, intended change.

  1. lib/tro_flow.py --json (implemented) — writes <csv>_tro.json (schema sps_skel-tro-v4, model.TroDocument): TROs with their hardware slots, system boundaries SYSn, connections with their kind, jamAreas (one per TRO entry, key J<Separator>, all predecessors that feed it), findings. TRO-IDs come from cfg/<csv>_tro_ids.ini (lib/tro_ids.py): each TRO is found again by the position of its separators, so IDs survive a new layout export (TeileIds do not); --renumber renumbers along the material flow, --ids points another export of the same plant at the same file. 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 counts, destination list per switch exit, nTo1Destinations for single-switch TROs); 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.
  5. lib/e_planning.py (implemented, first version) — CSV + E-planning *_positionsdraw.json → <csv>_eplan.json (EplanDocument): registers the E drawing to the CSV (dxf_registration.py) and assigns BMKs to layout parts by rules in cfg/e_planning.ini (distance, target distance, numbering rule MB = BG + 1). scl_skeleton.py --eplan fills separator sensor and stopper valve from it; jam sensors and outfeed/switch valves are assigned but not yet placed in the SCL. See doc/Python_Scripts.md §5c and doc/E-Planung_Bruecke.md.

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 — 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);
  • 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 here: it is designed to derive its skeleton JSON from HundM's Excel I/O-list exports (*_TIA.xlsx, *_positions.json, ...), a different input source than this repo's CSV+DXF pipeline. The JSON schema it targets is the same (doc/HundM/Json_Layout-Konzept.md); only the derivation source differs.

Standard Programm Template

This project follows the user's standard Python project scaffold convention:

sps_skel/
  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, importable via SKEL_LIB on PYTHONPATH — CLI tools and
             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 (pytest) — test_model.py for the TRO-JSON model

When extending the pipeline (the remaining pieces in "Roadmap" above), put new modules under lib/ (importable via SKEL_LIB on PYTHONPATH), add a bin/<name>.bat/.sh wrapper pair for each 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/.