Files
sps_skel/doc/Datenquellen_Layout_Hardwareplanung.md
T
Michael StanglandClaude Opus 5.5 e2a80e6de1 Doku: Datenquellen Layout/Hardwareplanung, Konzept Layout+Hardware -> SCL
- 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>
2026-10-11 19:33:26 +02:00

247 lines
19 KiB
Markdown

# 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) | `<projekt>-<n>_EA.xlsx`, `<projekt>-<n>_TIA.xlsx` (PLC Tags + Constants), `<projekt>-<n>_WSCAD.xlsx`, `<zeichnung>_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<BMK>]--------------> 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 `-<n>`, `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<BMK>` | 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<n>`, `stInSwitch<n>` |
| 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 `<csv>_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<TRO>.<n>; 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<TRO>.<n>; 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<n>; ob nötig: Layout
stOutPriorityManagerDir2 => "DB_Prozessdaten".stPriorityManager.udt_TRO107.TroOut, // Default: Namensregel
nInMainTroNo := "cMainTro107", // Default: Namensregel cMainTro<n>
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).