# Datenquellen für TROs und SCL: mechanisches Layout und Hardwareplanung Stand 2026-10-11. Welche Angaben für die TRO-Liste und die erzeugten `.scl`-Bausteine aus dem **mechanischen Layout** kommen, welche aus der **Hardwareplanung** (EA-Liste und TIA-Import), und was als **Defaultvorbelegung** gesetzt wird. Die vollständige Liste der Rohangaben beider Quellen (Spalten, Merkmale, Attribute) steht in `doc/Klassenhierarchie.md`, Kapitel "Daten", Abschnitte "Angaben 1" und "Angaben 2"; die Zuordnung jedes SCL-Parameters zu seiner Quelle in den Tabellen danach. Wie beide Quellen künftig über eine gemeinsame JSON zum SCL werden: `doc/Konzept_Layout_Hardware_SCL.md`. ## Die drei Quellen | Quelle | Dateien | Liefert im Kern | |---|---|---| | **Mechanisches Layout** (Anlagen-Hardware) | CSV-Export ILS 2.0 (`data/*.csv`), aus der BricsCAD-Layoutzeichnung | **Struktur**: welche Bauteile, wer folgt auf wen, Drehrichtung, Längen und Höhen, Anzahl Separatoren/Scanner | | **Hardwareplanung** (E-Planung) | `-_EA.xlsx`, `-_TIA.xlsx` (PLC Tags + Constants), `-_WSCAD.xlsx`, `_positionsdraw.json` | **Namen und Adressen**: jedes Signal mit BMK, Adresse, Index-Konstante, Rolle, Steuerung, Schaltschrank; mit `positionsdraw` auch die Lage | | **Defaultvorbelegung** | Typ-Katalog (`lib/tro_catalog.py`), Namensregeln (`scl_context.py`), Projektkonstanten | alles, was weder Layout noch E-Planung kennen: Zeiten, Konstanten-Namen nach Regel, Freigaben, WCS-Ziele | Die Schlüssel zwischen den Quellen: ```text Layout-Bauteil (TeileId) --[Lage, e_planning.py]--> E-Symbol (BMK, positionsdraw) E-Symbol (BMK) --[Name]-----------------> TIA PLC Tag (Adresse, Kommentar) --[cIn]--------------> TIA Constant (Index in DB_Inputs) E/A-Adresse --[Anschluss]-------------> WSCAD Bezug (Feldstation, Karte) ``` EA-Liste und TIA-Import allein haben **keine Lage**, `positionsdraw` hat **keine Adresse**. Erst über das BMK als gemeinsamen Schlüssel wird aus "Sensor neben Separator 0008" ein vollständiger SCL-Eintrag mit Adresse und Indexkonstante. ## Was die Hardwareplanung liefert ### Für die TROs | Angabe | aus | Regel | |---|---|---| | Signal gehört zu welchem Layout-Bauteil | `positionsdraw` `pos` | räumlich, `cfg/e_planning.ini` (heute umgesetzt) | | Rolle des Signals im TRO | `positionsdraw` `VERW`; ersatzweise Kommentar der EA/TIA-Liste | `IN SEP` → Sensor im Separator, `SEP` → Stopperventil, `STAU_REF-LT` → Stausensor, `AE ABZWEIG` → Ausschleusventil, `BT BELADEN` → Beladesensor, `MT in Position`/`ABFR.FINGER`/`conveyor full` → Vario | | Welche optionalen Sensoren verbaut sind | vorhanden / nicht vorhanden je Rolle | ergibt die `xPlugged*`-Schalter | | Fördereinheit (M-Nummer) | Kommentar `(ILS-CV M0108)`, `BEZEICHNUNG` `KR-K0102` | Instanzname des Antriebs (`#fbCarousel0102`), Name der Staubereiche (`DB_JamArea0102`) | | Steuerung, TRO-Nummernkreis | `KENNZEICHNUNG` `=A1+UH01-KF102`, Dateinummer `-`, `mappings` | `UH01` → TRO 1xx | | Schaltschrank / Bedienfeld | `KENNZEICHNUNG`, WSCAD `Bezug`, `schaltschrank_elemente` | `stInOutMachineState`, Taster `SF…` | | Motor ↔ Motorschutz | `MA`/`FC` mit gleicher Nummer | `xOutVarioMotor`, `xInMotorProtection` | | Safety-Signale | WSCAD `Bezug` auf F-Karte (`KF1FDQ…`) | Not-Halt-Kreis, nur Hinweis | | Plausibilisierung des TRO-Typs | Anzahl "in Separator n", "AE Abzweig", "Pin Abfrage" je M-Nummer | Gegenprüfung des aus dem Layout abgeleiteten Typs | ### Für die SCL-Dateien | Ziel | aus | Bemerkung | |---|---|---| | Namen in `FB_Main` (`=> "MB3306"`, `:= "FC0145"`, `"SF0002"`) | TIA PLC Tags `Name` | 1:1 | | Sensor-Indizes `"DB_Inputs".Sensors["cInBG3306"]` | TIA Constants `cIn` | 1:1; jede Konstante, die der Generator schreibt, muss in diesem Blatt stehen → **Prüfung möglich** | | `FB_CallSensors`, Größe `DB_Inputs` | alle `cInBG…`/`cInFC…` mit `Value` | noch nicht generiert | | Variablen- und Konstantentabelle im TIA Portal | der TIA-Import selbst | wird nicht generiert, sondern importiert | | `stInOutMachineState`, `xInAutomatic`, `xInErrorQuit` | Schrankelemente `SF…`, `KENNZEICHNUNG` | heute `TODO(E-Planung)` | | `xInSftyOk` | Safety-Programm; WSCAD nur als Hinweis | heute `TODO(E-Planung)` | | Scanner `BX…`, Cognex-Variablen | **nicht** in EA/TIA-Tagliste (PROFINET) | TIA-Gerätekonfiguration oder `positionsdraw` mit `BX` | ## Was das mechanische Layout liefert ### Für die TROs | Angabe | aus | Regel / Modul | |---|---|---| | Existenz und Grenzen der TROs | Separatoren (`ILS 2.0 Separator`) und ihr Host (`Zuordnung`, `TrackIds`) | `tro_flow.analyse_tros()` | | TRO-Typ und damit FB | Host Kreisel/Strecke/Gefälle, Weiche, Aus-/Einschleuselement, Scanner | `doc/500573_Mubea/TRO_Identifikation_500573.md`, `tro_catalog` | | Anzahl Separatoren, Weichen, Scanner je TRO | `Zuordnung`, `Naechster Separator`, Weichen-Merkmale | Parameterblöcke `stInSeparator`, `stInSwitch` | | Vorgänger/Nachfolger | `Nachbarn` (mit Bahn `-L`/`-R`), `TrackIds`, `Drehrichtung` | `material_flow` → Kanten, Ein-/Ausgangs-Staubereiche | | Systemgrenzen | `BTMT Beladung`/`Entladung`, `Eingang`/`Ausgang` | `SYSn`, `xIsBorner` | | Ziele je Weichenabgang | Erreichbarkeit im TRO-Graphen | `nTo1Destinations`, Zielliste | | Vorfahrt nötig | Einschleuselement / zwei Ströme in einen Staubereich | `xPrioDir`, `xReleaseOk` | | Tragende Fördertechnik | Host-Kreisel bzw. Gefälle | `xInCarouselRun1/2` | | angetriebene Strecke | `L_VF_m`, `Antriebfahrtrichtung` `Auf` | Vario | | Längen | `L_VF_m`, `L_GF_m`, Kreiselabstand | Grundlage für `tConvEmpty`, Staulängen | ### Für die SCL-Dateien REGION-Reihenfolge, FB-Typ, Instanzname, Zahl und Reihenfolge der Parameterzeilen, Staubereichs-Verkettung (Exit von A = Entr von B), `FC_Direction`-Aufruf mit dem Carrier aus dem Eingangs-Staubereich, `nTo1Destinations`, Cognex-Dummy bei TROs ohne Scanner. Das ist heute der Teil, den `scl_skeleton.py` schon ohne E-Planung füllt. ## Überschneidungen: gegenseitige Prüfung Beide Quellen beschreiben dieselbe Anlage, aber unabhängig voneinander. Wo sie sich überschneiden, prüft die eine die andere: | Angabe | Layout | Hardwareplanung | |---|---|---| | Separatoren je Strecke/Kreisel | `Anzahl_Separator`, `Zuordnung` | Anzahl `IN SEP`/"in Separator n" je M-Nummer | | Weiche/Abzweig vorhanden | `ILS Weiche`, `ILS Ausschleuselement` | `AE ABZWEIG`, `ABZWEIG-K104`, `ES branch` | | Scanner | `ILS 2.0 Scanner` | `BX…` (nur in `positionsdraw` mancher Projekte) | | angetriebene Strecke | `L_VF_m`, `Auf` | `MA…`/`FC…` mit Bezeichnung der Strecke | | Lage | `Position` | `pos` (nach Lagebezug `dxf_registration`) | Ein Widerspruch (z. B. Layout 6 Separatoren, E-Planung 5 `IN SEP`) heißt meist: unterschiedliche Planungsstände. Er gehört in den Bericht `_eplan.md`, nicht stillschweigend in die SCL. ## Beispielzeilen mit Herkunft Zwei reale Aufrufstellen aus `doc/TRO_Katalog/scl_templates/` (UH01), Zeile für Zeile mit der Quelle als Kommentar: - **Layout** = mechanisches Layout (CSV) - **HW-Planung** = Hardwareplanung (EA-Liste, TIA-Import, WSCAD, `positionsdraw`) - **Default** = Defaultvorbelegung (Typ-Default, Namensregel, Projektkonstante) Bei zwei Quellen steht die führende zuerst: "HW-Planung + Layout" heißt, der Name kommt aus der Hardwareplanung, die Zuordnung zu diesem TRO bzw. Ausgang aus dem Layout. Der Status heute (Generator setzt / `TODO(E-Planung)`) steht in den Tabellen von `doc/Klassenhierarchie.md`. Die Codeblöcke sind als `pascal` ausgezeichnet: Markdown-Renderer (VS Code, GitHub, Gitea) kennen kein `scl`, und SCL ist Pascal-basiert. So werden Schlüsselwörter, Zuweisungen, Zahlen und `//`-Kommentare hervorgehoben. ### `FB_ILS_MTRO_1Sep1Swi` (TRO 107, Separator mit Weiche am Kreisel) ```pascal REGION TRO 107(1Sep1Swi) // Layout: Typ aus Separator am Kreisel + Ausschleuselement; Nummer 107: Default (Nummernkreis UH01 aus HW-Planung) #TRO107.stInSeparator1.Settings.nSeparatorNo := "cSep107.1"; // Default: Namensregel cSep.; Anzahl Separatoren: Layout #TRO107.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short"; // Default; Short/Medium je Host (Kreisel/Strecke): Layout #TRO107.stInSeparator1.Settings.tTrailingTime := t#100ms; // Default: Typ-Default, bei IBN prüfen #TRO107.stInSeparator1.Settings.tHandlingTime := t#50ms; // Default: Typ-Default, bei IBN prüfen #TRO107.stInSeparator1.Settings.tJam := "TimeForSepJam"; // Default: Projektkonstante #TRO107.stInSeparator1.Settings.xPluggedJam := TRUE; // HW-Planung: Stausensor (VERW STAU_REF-LT) vorhanden #TRO107.stInSeparator1.Settings.xPluggedPart := FALSE; // HW-Planung: kein Beladesensor (VERW BT BELADEN) #TRO107.stInSeparator1.Settings.xPluggedScanner := FALSE; // Layout: kein ILS 2.0 Scanner mit "Naechster Separator" = dieser #TRO107.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG3306"]; // HW-Planung + Layout: BG mit VERW IN SEP am Separator; cInBG3306 aus TIA Constants #TRO107.stInSenJam2 := "DB_Inputs".Sensors["cInBG3305"]; // HW-Planung + Layout: Stausensor; Ausgang 2 = Weiterfahrt auf dem Kreisel #TRO107.stInSenJam3 := "DB_Inputs".Sensors["cInBG3330"]; // HW-Planung + Layout: Stausensor; Ausgang 3 = Abzweig am Ausschleuselement #TRO107.stInSwitch1.Settings.nSwitchNo := "cSwi107.1"; // Default: Namensregel cSwi.; Anzahl Weichen: Layout #TRO107.stInSwitch1.Settings.xPluggedExSen3 := FALSE; // HW-Planung: Abgangssensor Exit 3 verbaut? #TRO107.stInSwitch1.Settings.xPluggedExSen4 := FALSE; // HW-Planung: Abgangssensor Exit 4 verbaut? #TRO107.stInSwitch1.Settings.nTo1Destinations := 3; // Layout: über Abgang 1 erreichbare Ziele (reachable_via) #TRO107.stInSettings.xPrioDir2 := TRUE; // Layout: Zusammenführung vor Ausgang 2 -> Vorfahrt nötig #TRO107(stInPriorityManagerDir2 := "DB_Prozessdaten".stPriorityManager.udt_TRO107.TroIn, // Default: Namensregel udt_TRO; ob nötig: Layout stOutPriorityManagerDir2 => "DB_Prozessdaten".stPriorityManager.udt_TRO107.TroOut, // Default: Namensregel nInMainTroNo := "cMainTro107", // Default: Namensregel cMainTro xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMainOF1.Q, // HW-Planung: Not-Halt-Kreis OF1 (Safety-Programm, F-Karten im WSCAD) xInAllRdyToStart := TRUE, // Default xInCarouselRun1 := #fbCarousel0102.xOutConveyorFullSpeed, // Layout: Host-Kreisel; Name 0102: HW-Planung (KR-K0102, MA/FC-Bezeichnung) xInRelease := TRUE, // Default: Freigabe/Testlogik stInOutMachineState := #stInOutControlUnitCabinetOF1, // HW-Planung: Schaltschrank OF1 (KENNZEICHNUNG, WSCAD Bezug) stInOutCognexInterface := #stCognexInterfaceDummy, // Layout: kein Scanner am TRO arInOutJamEntr1 := "DB_JamArea0102".stJam0102_1.arCarrier, // Layout: Vorgänger-Staubereich; DB-Name 0102: HW-Planung (Kreisel K0102) + Default (Index _1) stInOutJamEntr1 := "DB_JamArea0102".stJam0102_1.stData, // wie oben arInOutJamExit2 := "DB_JamArea0103".stJam0103_1.arCarrier, // Layout: Nachfolger an Ausgang 2; DB-Name: HW-Planung + Default stInOutJamExit2 := "DB_JamArea0103".stJam0103_1.stData, // wie oben arInOutJamExit3 := "DB_JamArea0102".stJam0102_2.arCarrier, // Layout: Nachfolger an Ausgang 3; DB-Name: HW-Planung + Default stInOutJamExit3 := "DB_JamArea0102".stJam0102_2.stData, // wie oben stInOutHMI := "DB_Interface_HMI".stTRO.TRO107, // Default: Namensregel nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro107"], // Default: Namensregel xOutStopper1 => "MB3306", // HW-Planung: MB mit VERW SEP, Nummernregel ab BG3306 (TIA PLC Tag) xOutSw1ExTo3 => "MB3304"); // HW-Planung + Layout: MB AE ABZWEIG am Ausschleuselement von Ausgang 3 REGION Direction "FC_Direction"(nInSwitchNo := "cSwi107.1", // Default: Namensregel nOutDirection => #TRO107.nInDirection, // Default: fest InOutCarrier := "DB_JamArea0102".stJam0102_1.arCarrier[1]); // Layout: Carrier aus dem Eingangs-Staubereich END_REGION END_REGION ``` ### `FB_ILS_MTRO_Vario` (TRO 115, angetriebene Strecke mit Separator) ```pascal REGION TRO 115 (Vario) // Layout: Strecke mit L_VF_m / Antriebfahrtrichtung "Auf"; HW-Planung bestätigt (MA, MT in Position) #TRO115.stInSeparator1.Settings.nSeparatorNo := "cSep115.1"; // Default: Namensregel; Anzahl Separatoren: Layout #TRO115.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short"; // Default; Wahl je Host: Layout #TRO115.stInSeparator1.Settings.tTrailingTime := t#800ms; // Default: Typ-Default Vario, bei IBN prüfen #TRO115.stInSeparator1.Settings.tHandlingTime := t#300ms; // Default: Typ-Default Vario, bei IBN prüfen #TRO115.stInSeparator1.Settings.tJam := "TimeForSepJam"; // Default: Projektkonstante #TRO115.stInSeparator1.Settings.xPluggedJam := FALSE; // HW-Planung: kein Stausensor am Separator #TRO115.stInSeparator1.Settings.xPluggedPart := FALSE; // HW-Planung: kein Beladesensor #TRO115.stInSeparator1.Settings.xPluggedScanner := FALSE; // Layout: kein Scanner #TRO115.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG3025"]; // HW-Planung + Layout: BG IN SEP am Separator; Index aus TIA Constants #TRO115.stInSeparator1.Settings.tSenFree := t#2000ms; // Default: Typ-Default #TRO115.stInSeparator1.Settings.tSenWait := T#5000ms; // Default: Typ-Default #TRO115.stInVario.Settings.xContinousEmptying := FALSE; // Default: Prozessentscheidung #TRO115.stInVario.Settings.tWaitForJog := T#300ms; // Default: Typ-Default #TRO115.stInVario.Settings.tConvEmpty := T#45000ms; // Layout: Förderlänge L_VF_m / Geschwindigkeit (Default) -> heute fest #TRO115.stInVario.Settings.nCountCarrier := 1; // Default: Prozessentscheidung #TRO115.stInVario.Settings.tWaitForStop := t#3s; // Default: Typ-Default #TRO115.stInVario.Settings.tCarrierInPosDelay := t#1200ms; // Default: Typ-Default #TRO115.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms; // Default: Typ-Default #TRO115.stInVario.Settings.tRasterHigh := t#5s; // Default: Typ-Default #TRO115.stInVario.Settings.tRasterLow := t#5s; // Default: Typ-Default #TRO115.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG3026"]; // HW-Planung: VERW "MT in Position" an dieser Strecke #TRO115.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG3027"]; // HW-Planung: VERW "Finger in position" / ABFR.FINGER #TRO115.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG3000"]; // HW-Planung: VERW "conveyor full" #TRO115.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG3001"]; // HW-Planung: VERW "Jam detector" / STAU_REF-LT #TRO115.stInPriorityManager.xReleaseOk := TRUE; // Layout: keine Zusammenführung -> keine Vorfahrt #TRO115.stInVario.Settings.xJamSenDelayActive := TRUE; // Default (nur sinnvoll, wenn HW-Planung einen Stausensor hat) #TRO115.stInVario.Settings.tJamSenDelay := T#2s; // Default: Typ-Default #TRO115.stInSettings.xIsBorner := TRUE; // Layout: erster TRO nach Systemgrenze (Beladung/Eingang) #TRO115(nInMainTroNo := "cMainTro115", // Default: Namensregel xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMainOF1.Q, // HW-Planung: Not-Halt-Kreis xInMotorProtection := "FC0145", // HW-Planung: FC mit Nummer des Motors (schaltschrank_elemente, TIA "Meldekontakt Motorschutzschalter") xInAllRdyToStart := TRUE, // Default xInReset := "cTodoFalse", // Default xInErrorQuit := "SF0002", // HW-Planung: Quittiertaster (SF, Schrank) xInAutomatic := #t_Automatik_OF1 AND "SF0120", // HW-Planung: Schlüsselschalter SF0120; Verknüpfung: Default xInRelease := "DB_TRO_TEST".TRO115, // Default: Test-/IBN-Freigabe arInOutJamEntr := "DB_JamArea4104".stJam4104_1.arCarrier, // Layout: Vorgänger-Staubereich; Nummer: HW-Planung (M-Nummer) + Default stInOutJamEntr := "DB_JamArea4104".stJam4104_1.stData, // wie oben arInOutJamFinger := "DB_JamArea4103".stJam4103_1.arCarrier, // Layout: Staubereich auf der Vario-Strecke selbst; Nummer: HW-Planung + Default stInOutJamFinger := "DB_JamArea4103".stJam4103_1.stData, // wie oben stInOutMachineState := #stInOutControlUnitCabinetOF1, // HW-Planung: Schaltschrank OF1 stInOutCognexInterface := #stCognexInterfaceDummy, // Layout: kein Scanner stInOutHMI := "DB_Interface_HMI".stTRO.TRO115, // Default: Namensregel nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro115"], // Default: Namensregel xOutStopper => "MB3025", // HW-Planung: MB VERW SEP, Nummernregel ab BG3025 xOutVarioMotor => "MA0145"); // HW-Planung + Layout: MA an dieser angetriebenen Strecke (Lage bzw. Bezeichnung) END_REGION ``` ### Auszählung der beiden Beispiele | Führende Quelle | 1Sep1Swi (39 Zeilen) | Vario (47 Zeilen) | |---|---|---| | Layout | 13 | 10 | | HW-Planung | 11 | 14 | | Default | 15 | 23 | Gezählt sind alle kommentierten Zeilen (Zuweisungen und REGION-Kopf) nach der zuerst genannten Quelle; "wie oben" zählt wie die Zeile davor. Die Struktur (welche Zeilen es gibt, wie oft, in welcher Reihenfolge) kommt immer aus dem Layout; die Tabelle zählt, woher der **Wert** einer Zeile kommt. Der Großteil der Defaults sind Namensregeln und Zeiten, die nach dem Typ-Katalog vorbelegt und bei der Inbetriebnahme geprüft werden. Fast alle HW-Planung-Zeilen lassen sich aus TIA-Import und `positionsdraw` füllen; offen bleiben `xInSftyOk` (Safety-Programm) und die Scanner (PROFINET, nicht im Tag-Import).