- Klassenhierarchie.md, Kapitel Daten: vollstaendige Rohangaben aus Anlagen-Hardware (CSV-Spalten, Merkmale je TeileArt) und Hardwareplanung (EA-Liste, TIA-Import, WSCAD, positionsdraw) - Datenquellen_Layout_Hardwareplanung.md: was TROs/SCL aus Layout, Hardwareplanung und Defaults bekommen; 1Sep1Swi- und Vario-Aufruf zeilenweise mit Herkunft - Konzept_Layout_Hardware_SCL.md: Zielablauf tro_flow -> hw_import -> hw_assign -> scl_skeleton, Rolle der bestehenden Skripte, Festlegungen zu TRO-IDs (stabil ueber Lage, --renumber) und Staubereichen - CLAUDE.md: beide neuen Dokumente in der Leseliste Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
16 KiB
Konzept: Layout und Hardwareplanung → Anlagen-JSON → SCL
Stand 2026-10-11. Zielbild für den Ausbau der Pipeline, damit die beiden
Fachabteilungen unabhängig voneinander und zeitversetzt liefern können. Welche
Angaben aus welcher Quelle kommen, steht in doc/Datenquellen_Layout_Hardwareplanung.md;
die Rohangaben beider Quellen in doc/Klassenhierarchie.md, Kapitel "Daten".
Ausgangslage
Die Produktion läuft über zwei Abteilungen:
- Anlagenlayout (aus dem Angebotswesen, detaillierter aus der Projektierung). Liefert alles für die TROs: Bauteile, Abfolge, Weichen, Staubereiche, Systemgrenzen.
- Hardwareplanung (Karten, Kabel, Sensoren, Aktoren). Liefert die globalen Variablen und die tatsächlichen Sensoren und Aktoren mit Namen und Adressen.
Die Hardwareplanung kommt Tage bis Wochen später als das Layout. Das System muss deshalb mit dem Layout allein ein brauchbares SCL-Skelett erzeugen und die Hardware später nachtragen können, ohne Layout-Arbeit zu wiederholen.
Zielbild
Abteilung 1: Anlagenlayout Abteilung 2: Hardwareplanung (später)
CSV ──tro_flow──> <csv>_tro.json EA/TIA/WSCAD.xlsx, positionsdraw.json
(TROs, Abfolge, ──hw_import──> <projekt>_hw.json
Staubereiche, Slots) (globale Variablen, Geräte)
│ │
└──────────── hw_assign ─────────────────┘
│
<csv>_anlage.json (Layout + Zuordnungen)
│
scl_skeleton ──> FB_Main.scl, FB_CallSensors.scl, …
| Stufe | Skript | Eingabe | Ausgabe | Status |
|---|---|---|---|---|
| 1 Layout | tro_flow.py --json |
CSV, cfg/tro_overrides.ini |
<csv>_tro.json |
vorhanden, wird erweitert |
| 2 Hardware | hw_import.py |
*_TIA.xlsx, *_EA.xlsx, *_WSCAD.xlsx, *_positionsdraw.json |
<projekt>_hw.json |
neu |
| 3 Zuordnung | hw_assign.py |
<csv>_tro.json, <projekt>_hw.json, Regeln, cfg/hw_overrides.ini |
<csv>_anlage.json, Bericht .md |
neu (Logik aus e_planning.py) |
| 4 SCL | scl_skeleton.py |
<csv>_anlage.json (oder nur <csv>_tro.json) |
.scl |
vorhanden, wird umgestellt |
Grundsätze:
- Stufe 1 allein reicht für ein Skelett. Ohne Hardware wird jeder offene Wert
wie heute
TODO(E-Planung). - Die Stufen verändern sich nicht gegenseitig. Die Zuordnung legt ihre Ergebnisse neben das Layout, statt es zu überschreiben. Ein neuer Layoutstand oder ein neuer Hardwarestand heißt: die betroffene Stufe und alles danach neu ausführen.
- Lieber eine Lücke als ein falscher Name (wie heute in
cfg/e_planning.ini): was keine Regel sicher trifft, bleibt offen und steht im Bericht. - Drei Quellen, jede sichtbar: Layout, Hardwareplanung und Defaults
(
cfg/defaults.ini, Typ-Katalog). Jede SCL-Zeile lässt sich einer davon zuordnen.
Umbauten
1. TRO-JSON zur Layout-JSON ausbauen (Stufe 1)
Heute fehlt der Zuordnung ein Ziel: die TRO-JSON sagt nicht, welche Stellen ein
TRO hat, an die Hardware gehört. Daran scheitern heute Stausensoren und
Weichenventile (doc/E-Planung_Bruecke.md, "Offen").
-
Slots je TRO: je Separator, Weiche, Ausgang und Antrieb ein Eintrag mit der Layout-ID des Bauteils und den Rollen, die die Hardwareplanung dort füllen muss.
"slots": [ {"slot": "separator1", "layoutId": "0008", "roles": ["sensor", "stopper", "jamSensor?", "partSensor?"]}, {"slot": "switch1", "layoutId": "0037", "exit": 3, "roles": ["valve", "exitSensor?"]}, {"slot": "drive", "layoutId": "0002", "roles": ["carouselRun"]} ]Die Slots ergeben sich aus dem Katalogtyp (
items) und der Topologie;?= optional, fehlt das Gerät, wird der zugehörigexPlugged*-SchalterFALSE. -
Staubereiche als eigene Liste
jamAreas[]: ein Staubereich je TRO-Eingang, mit allen Vorgängern, dem Förderer, auf dem er liegt, und seiner Lage auf dem Förderer (siehe "Staubereiche" unten). Heute nur abgeleitet beim Rendern (scl_context.SclJam). Dabei korrigieren:scl_skeletonerzeugt heute je Vorgänger einen eigenen Eingang (arInOutJamEntr1,…Entr2); in den Referenzen laufen mehrere Vorgänger in einem Staubereich zusammen, der TRO hat einen Eingang (Ausnahme2Sep1Swi, PinStore). -
Weitere Layout-Angaben:
xIsBorner, Vorfahrt ja/nein, tragender Förderer mit Rolle (heutehostsohne Rolle), Längen fürtConvEmptyund Staulängen. -
Ableitungen aus
scl_contextnachtro_flow/modelverschieben, damit die JSON sie trägt und nicht erst das Rendern sie kennt. -
Schema
sps_skel-tro-v4.
2. Neues Skript hw_import.py (Stufe 2)
- Liest TIA-Import (PLC Tags + Constants), EA-Liste, WSCAD-Import und optional
positionsdraw.json. - Schreibt ein neues Modell
HardwareDocument:- Geräte je BMK: Adresse, Index-Konstante (
cInBG3306), Kommentar, VERW, Steuerung, Station/Schrank, Position (falls vorhanden); - globale Variablen: alle Tags und Konstanten, Motor↔Motorschutz-Paare, Taster, Not-Halt.
- Geräte je BMK: Adresse, Index-Konstante (
- Prüft die Exporte gegeneinander: BMK fehlt in einer Liste, doppelte BMK, Adresse ohne Tag.
- Übernimmt aus
e_planning.py:load_positionsdraw,EDevice,pair_drives. - Erste Quelle: der TIA-Import, weil er Namen und Konstanten 1:1 liefert und die spätere Prüfung des SCL ermöglicht.
3. Neues Skript hw_assign.py (Stufe 3)
-
Eingabe:
<csv>_tro.json+<projekt>_hw.json; das CSV wird nicht mehr gelesen. -
Zuordnungswege, als Regeln in einer INI (heute
cfg/e_planning.ini):- räumlich über
positionsdraw: die bestehende Logik ause_planning.py(Lagebezug überdxf_registration, Höchst-/Sollabstand), jetzt gegen die Slots; - Nummernregel:
MB = BG + 1bzw. gleiche Nummer, Motor = Motorschutz; - nur EA-Liste, ohne Positionen: über die Kommentare ("in Separator 1 (ILS-CV M0108)") und eine von Hand gepflegte Tabelle M-Nummer → Layout-Förderer.
- räumlich über
-
Handkorrekturen in
cfg/hw_overrides.ini(analogcfg/tro_overrides.ini). -
Ausgabe
<csv>_anlage.json: Layoutteil unverändert, daneben"bindings": [ {"layoutId": "0008", "role": "sensor", "bmk": "BG3306", "constant": "cInBG3306", "address": "%E330.6", "source": "positionsdraw", "rule": "raeumlich", "distance": 12.0, "status": "zugeordnet"} ]status:zugeordnet|offen|widerspruch. -
Stabile Schlüssel: Zuordnungen hängen an TRO-ID + Slot + Rolle. Die TRO-IDs sind ab der Festlegung durch die SPS-Programmierer stabil (siehe "TRO-IDs" unten). Die Layout-
TeileIdtaugt dafür nicht: sie ändert sich zwischen zwei CSV-Exporten (siehe dort).layoutIdinbindingsdient nur zur Nachverfolgung im aktuellen Stand. -
Gegenprüfung beider Quellen (Anzahl Separatoren vs.
IN SEP, Weichen vs.AE ABZWEIG, angetriebene Strecken vs.MA) in den Bericht.
4. scl_skeleton.py / scl_context.py (Stufe 4)
- Liest eine Eingabe:
<csv>_anlage.json; ohne Hardwareteil wie heute<csv>_tro.json. --eplanund die Zusammenführung inscl_context._separatorentfallen; der Kontext liest Namen ausbindings, offene Slots werdenTODO(E-Planung).- Prüfung gegen die globalen Variablen: jeder Tag und jede
cIn…-Konstante im SCL muss im TIA-Import stehen, sonst Abbruch mit Liste. - Neue Bausteine nach Stufe 2:
FB_CallSensorsaus der Sensorliste, Antriebsaufrufe (fbCarousel0102) aus den Motorpaaren, Staubereichs-DBs.
5. Defaults als dritte Quelle
Zeiten und Projektkonstanten, die heute fest in scl_skeleton.py stehen
(t#600ms, T#1500ms …), wandern in den Typ-Katalog (tro_catalog.py) bzw. eine
Projektdatei cfg/defaults.ini.
Bestehende Programme
| Programm | Rolle im neuen Ablauf |
|---|---|
material_flow.py, tro_flow.py |
bleiben Stufe 1; Ausbau um Slots und jamAreas |
tro_catalog.py, model.py, tro_overrides.py, dxf_registration.py |
bleiben Bibliotheken; model.py bekommt Slots, jamAreas, Anlagen-JSON |
e_planning.py |
wird aufgeteilt (unten) |
tro_annotate.py |
bleibt als Kontrollansicht, liest künftig die JSON (unten) |
tro_extract.py |
entfällt bzw. wird umgebaut (unten) |
scl_skeleton.py, scl_context.py |
Stufe 4, Umstellung auf <csv>_anlage.json |
e_planning.py → hw_import + hw_assign
| Teil heute | Wohin |
|---|---|
load_positionsdraw, EDevice, pair_drives |
hw_import.py |
resolve_transform, load_rules, _assign_spatial, _assign_by_number, Bericht |
hw_assign.py, Ziele = Slots statt CSV-Bauteile |
cfg/e_planning.ini |
Regeldatei von hw_assign |
EplanDocument / <csv>_eplan.json |
entfällt, ersetzt durch bindings[] |
Übergang: e_planning.py bleibt kurz als Hülle, die hw_import und hw_assign
nacheinander aufruft, damit bin/e_planning.bat weiter funktioniert; danach
löschen.
tro_annotate.py → Kontrollansicht für Layout und Zuordnung
- Aus der JSON zeichnen statt
analyse_trosselbst aufzurufen: die Zeichnung zeigt dann genau das, woraus das SCL entsteht. - Zuordnungen einzeichnen: neben jedem Slot das BMK (
BG3306,MB3306), offene Slots und Widersprüche rot. Für die Hardwareplanung die schnellste Kontrolle der räumlichen Zuordnung. --emit-lisp(TROEDIT) bleibt, solange Marker in BricsCAD bearbeitet werden; hängt an der Entscheidung zutro_extract.
tro_extract.py → entfällt im neuen Ablauf
Es wäre ein dritter Korrekturweg neben cfg/tro_overrides.ini (Layout) und
cfg/hw_overrides.ini (Zuordnung) und schreibt noch das alte Schema
sps_skel-tro-extract-v1, das niemand mehr liest.
- Löschen (Empfehlung), zusammen mit
TROEDIT/--emit-lisp. Korrekturen nur in den INI-Dateien: nachvollziehbar und versioniert. - Umbauen, falls die Projektierung in BricsCAD korrigieren will: es schreibt
dann Einträge in
tro_overrides.ini/hw_overrides.ini, keine eigene JSON.
Bis zur Entscheidung bleibt es geparkt.
Festlegungen (2026-10-11)
TRO-IDs
Festgelegt: Die TRO-IDs vergeben die SPS-Programmierer, die zugleich die Anwender der Skripte sind. Eine ID muss nur eindeutig sein. Üblich ist eine Nummerierung entlang des Materialflusses und eine Benennung nach den Bauteilen (Kreisel usw.), vorgeschrieben ist das nicht. Sobald größere Teile des SPS-Codes stehen, ändern sich die IDs nicht mehr; in der frühen Projektphase dürfen sie mehrmals neu vergeben werden.
Befund: Heute vergibt tro_flow laufende Nummern je Lauf (TRO01, TRO02 …,
tro_flow.py Zeile ~1163); cfg/tro_overrides.ini warnt bereits, dass sich die
Nummern bei neuer Datenbasis verschieben. Die Layout-TeileId ist ebenfalls nicht
stabil: Vergleich zweier Exporte derselben Anlage
| Vergleich | Bauteile | gleiche Id und Lage | gleiche Lage, andere Id |
|---|---|---|---|
mubea.csv ↔ mubea_export.csv |
119 / 125 | 46 | 27 |
HundM05.csv ↔ HundM05_14.csv |
45 / 44 | 22 | 16 |
Stabil ist nur die Lage des Bauteils.
Vorschlag:
-
Eine versionierte ID-Datei je Anlage, z. B.
cfg/<anlage>_tro_ids.ini: je TRO die ID und die Lage seines Anker-Separators (x, y in mm), optional ein Name. Vontro_flowangelegt, von den SPS-Programmierern umbenannt.; Beispiel, Werte erfunden [mubea] TRO107 = 12450.0, 3310.0 ; Kreisel 2 vor Beladung TRO108 = 13250.0, 3310.0 -
Standard (IDs halten):
tro_flowliest die ID-Datei und findet jeden TRO über die Lage des Anker-Separators wieder (Toleranz einstellbar). Gefundene TROs behalten ihre ID. Neue TROs bekommen eine vorläufige ID (nächste freie Nummer entlang des Materialflusses) und stehen im Bericht; weggefallene TROs stehen im Bericht, ihre ID wird nicht automatisch wiederverwendet. -
Programmschalter
--renumber(frühe Phase): alle IDs neu entlang des Materialflusses vergeben und die ID-Datei neu schreiben. -
Dadurch werden auch die Abschnitte
[<csv>.tro.<TRO-ID>]incfg/tro_overrides.iniund die Zuordnungen vonhw_assignstabil.
Staubereiche
Bisheriges Namensschema (Referenzen UH01–UH05, doc/TRO_Katalog/connect.ini,
286 Staubereiche):
"DB_JamArea<NNNN>".stJam<NNNN>_<k> Kurzform JA<NNNN>_<k>
<NNNN>= Förderer, auf dem der Staubereich liegt, ein DB je Förderer:0102= Kreisel K0102 (vgl.#fbCarousel0102),0103/0104= Strecken,4103/4104= Vario-Förderer.<k>= laufende Nummer entlang des Materialflusses auf diesem Förderer; Kreisel K0102 hat_1…_6in Umlaufrichtung.- 249 der 286 folgen diesem Schema. Sonderfälle: Lagerlinien
Storage1.1.2(24), Übergabe an eine andere SteuerungIO_Device_UHxx_TO_UHyy…bzw. lokal#arCarrierHandoverJam5000(9),JamBuffer101im Leerträgerpuffer (2), F2H (1).
Prüfung der Annahme "ein Staubereich = Ausgang des Vorgängers und Eingang des Nachfolgers":
- Kein Staubereich hat mehr als einen Nachfolger-TRO.
- 65 Staubereiche haben mehrere Vorgänger: dort laufen Ströme zusammen, z. B.
JA0102_2mit Vorgängern TRO101, TRO106 und TRO107 (Weichenausgang), alle mit Nachfolger TRO112. - Jeder TRO hat genau einen Eingangs-Staubereich; einzige Ausnahme sind die PinStore-TROs (zusätzlich die Lagerlinie).
Ein Staubereich ist also immer der Eingang genau eines TRO, aber nicht immer
der Ausgang genau eines Vorgängers. Ein Name nach dem Schema ja_tro3tro4 ist bei
Zusammenführungen nicht eindeutig.
Vorschlag:
- Kennung in der JSON nach dem Nachfolger:
JA_<TRO-ID>, z. B.JA_TRO112; ein zweiter Eingang (PinStore)JA_TRO208_2. Eindeutig, solange die TRO-IDs eindeutig sind, und mit ihnen stabil. - Name im SCL nach dem bisherigen Schema
"DB_JamArea<NNNN>".stJam<NNNN>_<k>:<k>lässt sich aus dem Layout ableiten (Reihenfolge auf dem Förderer in Flussrichtung),<NNNN>ist die Förderernummer. Die vergeben wie die TRO-IDs die SPS-Programmierer bzw. sie kommt aus der Hardwareplanung (KR-K0102); sie steht in derselben ID-Datei ([mubea.foerderer],K0102 = <Lage>). Ohne Förderernummer bleibt der NameTODO(E-Planung)wie heute. - Alternative, falls das alte Schema nicht nötig ist: SCL-Name direkt aus der
Kennung (
"DB_JamArea".JA_TRO112); braucht keine Förderernummern, weicht aber von den bestehenden Projekten und derenFC_Call_Jamsab. Entscheidung offen.
Korrekturen in BricsCAD
Zurückgestellt. Eine Alternative wäre, die <csv>_tro.json zu visualisieren
und von Hand zu bearbeiten. Bis dahin bleibt tro_extract.py geparkt, TROEDIT
unverändert.
Reihenfolge
- TRO-IDs stabil machen: ID-Datei, Wiederfinden über die Lage,
--renumber. Darauf bauen Overrides, Staubereiche und Zuordnungen auf. - Slots und
jamAreasin die TRO-JSON (Umbau 1), ein Eingangs-Staubereich je TRO — ohne Slots hat die Zuordnung kein Ziel. hw_importmit dem TIA-Import als erster Quelle.hw_assignmit der räumlichen Logik ause_planning.py;e_planning.pyals Übergangshülle.scl_skeletonauf<csv>_anlage.jsonumstellen,--eplanentfernen;tro_annotateauf JSON umstellen.- Defaults (
cfg/defaults.ini),FB_CallSensors, EA-Liste ohne Positionen.
Zu jedem Schritt: bin/-Wrapper für neue Skripte, Tests unter tests/
(kleine TIA-Datei als Testdaten), Golden Files bei Schemawechsel bewusst neu
erzeugen, doc/Python_Scripts.md ergänzen.
Offene Entscheidungen
- SCL-Name der Staubereiche: bisheriges Schema mit Förderernummer (Empfehlung)
oder neues Schema direkt aus
JA_<TRO-ID>. - Toleranz beim Wiederfinden der TROs über die Lage; Verhalten, wenn ein Separator weiter verschoben wurde (Vorschlag: als "neu" + "weggefallen" melden, der Programmierer übernimmt die ID von Hand).
- Korrekturen in BricsCAD oder in der JSON: zurückgestellt.