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>
This commit is contained in:
Michael Stangl
2026-10-11 19:33:26 +02:00
co-authored by Claude Opus 5.5
parent c736288476
commit e2a80e6de1
4 changed files with 703 additions and 2 deletions
+10
View File
@@ -138,6 +138,16 @@ this order for onboarding:
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`.
9. **`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".
10. **`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)
+246
View File
@@ -0,0 +1,246 @@
# 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).
+124 -2
View File
@@ -443,14 +443,136 @@ Dateien.
| Kürzel | Quelle | Was sie liefert |
|---|---|---|
| **L** | Hardwarelayout (CSV-Export ILS 2.0, `data/*.csv`) | Bauteile (`TeileArt`: Separator, Scanner, Weiche, Kreisel, Strecke, Gefällestrecke, BTMT Be-/Entladung, Ein-/Ausschleuselement), `Nachbarn`/`TrackIds`, `Merkmale` (Drehrichtung, Antriebfahrtrichtung, Höhen, Längen, Anzahl Separatoren/Scanner, Zuordnung). Daraus abgeleitet: TRO-Typ, Topologie, Reihenfolge, Ziele. |
| **E** | Elektroplanung (EA-Liste/WSCAD/TIA-Variablentabelle, siehe `doc/HundM/EA-Listen-Analyse.md`) | Betriebsmittelkennzeichen und Variablennamen (`BG…` Sensoren, `MB…` Ventile, `MA…` Motoren, `FC…` Motorschutz, `SF…` Taster, `BX…` Scanner), Hardware-Kennungen, welche optionalen Sensoren verbaut sind, Zuordnung zu Schaltschrank und Not-Halt-Kreis. |
| **L** | Anlagen-Hardware = mechanisches Layout (CSV-Export ILS 2.0, `data/*.csv`) | Bauteile (`TeileArt`: Separator, Scanner, Weiche, Kreisel, Strecke, Gefällestrecke, BTMT Be-/Entladung, Ein-/Ausschleuselement), `Nachbarn`/`TrackIds`, `Merkmale` (Drehrichtung, Antriebfahrtrichtung, Höhen, Längen, Anzahl Separatoren/Scanner, Zuordnung). Daraus abgeleitet: TRO-Typ, Topologie, Reihenfolge, Ziele. |
| **E** | Hardwareplanung = Elektroplanung (EA-Liste, TIA-Import, WSCAD-Import, `*_positionsdraw.json`; siehe `doc/HundM/EA-Listen-Analyse.md`) | Betriebsmittelkennzeichen und Variablennamen (`BG…` Sensoren, `MB…` Ventile, `MA…` Motoren, `FC…` Motorschutz, `SF…` Taster, `BX…` Scanner), Hardware-Kennungen, welche optionalen Sensoren verbaut sind, Zuordnung zu Schaltschrank und Not-Halt-Kreis. |
| **K** | Namenskonvention | Name folgt aus TRO-Nummer bzw. Staubereichs-/Weichennummer (`cMainTro<n>`, `cSep<n>.<i>`, `"DB_Interface_HMI".stTRO.TRO<n>` …). Keine externe Quelle nötig, sobald Nummernkreis und Regel feststehen. |
| **P** | Parameter / Projektstandard | Weder Layout noch E-Planung: Zeiten, Schwellwerte, Projektkonstanten, WCS-/Inbetriebnahme-Logik. Kandidaten für Typ-Defaults (`doc/TRO_Typen.md`). |
`L + E` heisst: das Layout sagt, **dass/wie viele** es gibt und **wo**, die
E-Planung liefert den **Namen/die Adresse**. Das ist der häufigste Fall.
Die zwei folgenden Abschnitte listen **alle Angaben**, die die beiden externen
Quellen heute enthalten (Stand 2026-10-11, geprüft an `data/*.csv` und an den
Exporten unter `kabellaengen/work/`: `easy_sps-1_EA/_TIA/_WSCAD.xlsx`,
`Mubea_positionsdraw.json`). Was sich daraus für TROs und SCL gewinnen lässt und
zwei kommentierte SCL-Beispiele: `doc/Datenquellen_Layout_Hardwareplanung.md`.
### Angaben 1: Anlagen-Hardware (mechanisches Layout, CSV)
Eine Zeile je Bauteil, Trennzeichen `;`, `utf-8-sig`. Gelesen von
`material_flow.load_elements()`.
#### Spalten (alle Bauteilarten)
| Spalte | Beispiel | Bedeutung | Nutzen für TRO/SCL |
|---|---|---|---|
| `Elementnummer` | `1` | laufende Zeilennummer des Exports | keiner (nicht stabil) |
| `TeileArt` | `ILS 2.0 Separator` | Bauteilart (Liste unten) | Knotenart, TRO-Typ |
| `TeileId` | `0008` | stabile ID im Layout | Schlüssel für Topologie, Overrides, E-Brücke |
| `Bezeichnung` | `VF_1`, `Kreisel :3` | Klartext aus der Zeichnung | Anzeige, REGION-Kommentar |
| `Planquadrat` | `B/1-C/4` | Raster der Zeichnung | Bericht/Suche |
| `Anzahl` | `1` | Stückzahl | keiner |
| `Position` | `5878.63, 4330.96, 2128.70` | Einfügepunkt x, y, z in mm | Lagebezug zur E-Planung (`dxf_registration`), Abstände |
| `Boundingbox` | `2837.82, 6404.92, 731.58` | Ausdehnung x, y, z in mm | Lage von Weichen/Bahnen |
| `Insertpoint` | `TV0UEkxg…` | kodierter Einfügepunkt (Base64) | intern |
| `K1`–`K4` | `AK41AC7XAFQk` | Anschluss-Koordinatensysteme (Base64, je x/y/z) | Anschlussseite, Lage der AS/ES (`decode_kpoint`) |
| `Nachbarn` | `0006-L, 0014` | berührende Bauteile, bei Kreiseln mit Bahn `-L`/`-R` | Topologie (Kanten) |
| `TrackIds` | `0044, 0027, 0026` | Anbauteile eines Containers in Baureihenfolge bzw. Umlaufrichtung | Reihenfolge Separator/AS/ES auf Strecke und Kreisel |
| `Fehler`, `Warnungen` | `nur ein Partner`, `unverbunden` | Prüfmeldungen des Exports | Qualitätsprüfung |
| `Merkmale` | JSON | artspezifische Eigenschaften (unten) | siehe unten |
#### Merkmale je `TeileArt`
| TeileArt | Merkmale | Nutzen für TRO/SCL |
|---|---|---|
| `ILS 2.0 Kreisel` | `Name`, `Kreiselart` (`STANDARD`), `Drehrichtung` (`UZS`/`GUZ`), `Drehung`, `Höhe in m`, `Abstand (Kreiselachse A - Kreiselachse) in Meter`, `Anzahl der Separatoren`, `Anzahl der Scanner`, `Anzahl der Rampen`, `Geruest fuer Einzelmodul` | Host eines TRO (`xInCarouselRun1/2`), Umlaufrichtung → Reihenfolge, Länge → Staulänge; Anzahlen zur Plausibilisierung |
| `ILS 2.0 Strecke` | `Typ` (`Streckengruppe`), `Seite_AS`, `Seite_ES`, `Winkel`, `VF_Winkel`, `DeltaH_mm`, `DeltaL_mm`, `L_VF_m` (angetriebene Teilstücke), `L_GF_m` (Gefälleteilstücke), `Montagehoehe_m`, `Hoehe_Von_mm`, `Hoehe_Bis_mm`, `Antriebfahrtrichtung` (`horizontal`/`Auf`), `Anzahl_Separator`, `Anzahl_Scanner`, `Separatorlist` | angetrieben (`L_VF_m`, `Auf`) → Vario/Antrieb; Längen → `tConvEmpty`, Staulänge; Anzahlen zur Plausibilisierung |
| `ILS 2.0 Gefaellestrecke` | wie Strecke, `L_VF_m` und `Antriebfahrtrichtung` leer | Host "Gefälle" → `1Sep`, `xInCarouselRun1 := TRUE` |
| `ILS 2.0 Separator` | `Zuordnung` (Host, ggf. mit Bahn `-L`/`-R`), `ARTINR`, `Höhe`, `Drehung`, `Typ` | **TRO-Anker**: jeder Separator ist ein TRO oder Teil davon; Host → TRO-Typ |
| `ILS 2.0 Scanner` | `Zuordnung`, `Naechster Separator`, `ARTINR`, `Höhe`, `Drehung`, `Typ` | Scanner am TRO (`xPluggedScanner`, `stInBarcodeReader`, REGION-Titel) |
| `ILS Weiche` | `Kreisel A`, `Kreisel B`, `Achse von Kreisel`, `Beruehrung` (`Kreis/Kreis`), `Erzeugt aus` | Kreisel-Kreisel-Weiche → `1SepNSwi`, `xCar2NecRight/Left`, zweiter Kreisel `xInCarouselRun2` |
| `ILS Ausschleuselement` | `Kreisel`, `Strecke`/`Förderer`, `Streckenende` (`Anfang`), `Element` (`AS_Element_90_links_3D`), `ARTINR`, `Erzeugt aus` | Abgang Kreisel → Strecke: Weichenausgang `Exit3/4`, Ziel je Abgang |
| `ILS Einschleuselement` | wie Ausschleuselement, `Streckenende` `Ende` | Zusammenführung Strecke → Kreisel: Vorfahrt (`xPrioDir`, PriorityManager) |
| `ILS 2.0 BTMT Beladung` / `Entladung` | `ARTINR`, `Höhe`, `Drehung` | Systemgrenze `SYSn`, `xIsBorner`, Ziele; Ladeschleife |
| `Eingang` / `Ausgang` | `ARTINR`, `Höhe`, `Drehung` | Systemgrenze zu Nachbaranlage, Übergabe-Staubereich |
`ARTINR` (Artikelnummer) unterscheidet Bauarten, z. B. Separator `200000077`,
Scanner `829534306`; daran ließe sich die Weichenbauart (`xNewSwitch`) prüfen.
Zusätzlich gibt es den **Sivas-Stücklisten-Export** (`data/*_sivas.csv`:
`SivasNummer`, `Dispogruppe`, `Laenge[mm]`, `IDs`, `details` mit
Förder-/Gefällegruppen, Kurven, `MotorSeite`). Er ist eine Stückliste, keine
Topologie, und wird nicht gelesen; brauchbar wäre `MotorSeite` und die
Gruppenlängen.
**Nicht im Layout:** Betriebsmittelkennzeichen, E/A-Adressen, welche optionalen
Sensoren verbaut sind, Schaltschrank/Steuerung, Zeiten, Ziel-Nummern des WCS.
### Angaben 2: Hardwareplanung (EA-Liste, TIA-Import, WSCAD-Import, positionsdraw)
Vier Exporte derselben E-Planung. Gemeinsamer Schlüssel ist das
**Betriebsmittelkennzeichen (BMK)** `BG3306`, `MB3306` …; nur `positionsdraw`
kennt eine Lage, nur EA/TIA/WSCAD kennen die E/A-Adresse.
**`<projekt>-<n>_EA.xlsx`** — Blatt "Ein-, Ausgaenge", je SPS `n` eine Datei
| Spalte | Beispiel | Bedeutung |
|---|---|---|
| `Name` | `E324.0` | E/A-Adresse |
| `Kommentar` | `Stausensor 1 (ILS-CV M0108)` | Funktionsrolle, lfd. Nr., Fördereinheit (M-Nummer), Bereich |
| `Zeile` | `2` | Verweis Schaltplan |
**`<projekt>-<n>_TIA.xlsx`** — Importdatei für das TIA Portal
| Blatt / Spalte | Beispiel | Bedeutung | Nutzen für SCL |
|---|---|---|---|
| PLC Tags `Name` | `BG3240`, `MB3306`, `MA0062`, `FC0062` | BMK = Variablenname | direkt die Namen in `FB_Main` (`=> "MB3306"`, `:= "FC0145"`) |
| PLC Tags `Path` | `Import` | Variablentabelle | Ordner der Variablentabelle |
| PLC Tags `Data Type` | `Bool` | Datentyp (nur Bool) | – |
| PLC Tags `Logical Address` | `%E324.0`, `%A006.2` | Absolutadresse | Prüfung, `FB_CallSensors` |
| PLC Tags `Comment` | `Stausensor 1 (ILS-CV M0108)` | wie EA-Kommentar | Rolle, M-Nummer |
| PLC Tags `Hmi Visible/Accessible/Writeable` | `True` | HMI-Flags | – |
| PLC Tags `Typeobject ID`, `Version ID` | leer | – | – |
| Constants `Name` | `cInBG3240`, `cInFC0062`, `cOutMA0062` | Index-Konstante je Signal | genau die Indizes in `"DB_Inputs".Sensors["cInBG3306"]` |
| Constants `Data Type`, `Value` | `Int`, `1` | Array-Index | Dimensionierung `DB_Inputs` |
**`<projekt>-<n>_WSCAD.xlsx`** — Importdatei für das E-CAD
| Spalte | Beispiel | Bedeutung | Nutzen für SCL |
|---|---|---|---|
| `Anschluss` | `E324.0` | E/A-Adresse | Schlüssel zu EA/TIA |
| `Kommentar` | wie EA | | |
| `Bezug` | `=A01+UC0101-KF1DI1` | Anlage, Feldstation (`UC…`), Baugruppe (`KF1DI1`, `KF1FDQ2` = F-Karte) | Steuerungs-/Schaltschrankzuordnung, Safety-Signale |
| `Symboltext`, `Sondertext 1..8` | meist leer | | |
**`<zeichnung>_positionsdraw.json`** — Kabellängen-Tool, E-Symbole aus der Zeichnung
| Schlüssel / Attribut | Beispiel | Bedeutung | Nutzen für TRO/SCL |
|---|---|---|---|
| `sensors{BMK@SPS}` | `BG0542@UNKNOWN` | Feldgeräte (BG, MB, MA …) | Hauptquelle der Brücke |
| `.IO` / `.B` | `BG0542` | BMK | Schlüssel zu TIA |
| `.pos` | `[-42369.8, -11437.2]` | Lage in mm | **Zuordnung zum Layout-Bauteil** (`e_planning.py`) |
| `.VERW` | `IN SEP`, `SEP`, `STAU_REF-LT`, `AE ABZWEIG`, `ABZWEIG-K104`, `BT BELADEN`, `SYNC P1..4`, `ABFR.FINGER`, `ÜBERGABE`, `ÜBERNAHME`, `BANDBRUCH`, `KETTENBRUCH`, `ZAPPLER P1`, `MOT_0,37kW` | Verwendung (kontrolliertes Vokabular) | **Rolle** des Signals im TRO |
| `.BEZEICHNUNG` | `STAUSENSOR STR. 01`, `PRÜFUNG BT. POS.1 (KR-K0102 EINFAHRT PUFFER)` | Klartext | Strecken-/Kreiselnummer, Plausibilisierung |
| `.BESCHR` | `STAUSENSOR` | Gerätebeschreibung | – |
| `.KENNZEICHNUNG` | `=A1+UH01-KF102` | Steuerung `UH01`, E/A-Station `KF102` | Steuerung, TRO-Nummernkreis, Schaltschrank |
| `.ARTINR` | `829434300` | Artikelnummer Gerät | Gerätetyp |
| `.SPS` | `''`, `A/B` | SPS-Nummer (oft leer) | Steuerung |
| `.A`, `.C`, `.ID`, `.MENGE`, `.POSITION`, `.GRUPPE`, `.ETIKETTE`, `.AUFLOESE`, `.TEXT-D/E/ES/F` | | Blockattribute des Symbols | – |
| `schaltschrank_elemente{…}` | `FC0200` `MOTORSCHUTZ CONVEYER #100`, `SF…` Taster, `PF…` Leuchten, `QA7000` Hauptschütze, `GF` Encoder, `BP` Druckschalter | Elemente im Schrank, ohne Feldlage | Motorschutz ↔ Motor, Bedienelemente, Encoder |
| `mappings` | `UH01: [BMK …]` bzw. Verteiler → BMK | Zuordnung zur Steuerung/Verteiler aus der Verkabelung | Steuerungsaufteilung |
| `distributors`, `racks`, `tunnels` | | Verteiler, Trassen | – |
| `warnings`, `not_found`, `double_ids` | | Prüfprotokoll | Qualitätsprüfung |
**BMK-Präfixe:** `BG` Sensor, `SF` Taster/Schalter, `DI` Diagnose, `BP`
Druckschalter, `GF` Encoder, `BX` Scanner (nur PROFINET, nicht in den Digitallisten),
`MB` Ventil (Stopper, Weiche, Ausschleuser), `MA`/`QA` Motor/Schütz, `DQ`
Sonderausgang, `FC` Motorschutz, `PF` Leuchtmelder.
**Nicht in der Hardwareplanung:** Topologie (wer auf wen folgt), TRO-Grenzen,
Ziele/Weichenrichtungen, Zeiten, Analogwerte und PROFINET-Geräte (Cognex-Variablen
stehen in der TIA-Gerätekonfiguration, nicht im Tag-Import).
### TRO-Kopf und Instanzaufruf
| Daten | SCL-Stelle (Beispiel) | Quelle | Bemerkung |
+323
View File
@@ -0,0 +1,323 @@
# 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:
1. **Anlagenlayout** (aus dem Angebotswesen, detaillierter aus der Projektierung).
Liefert alles für die TROs: Bauteile, Abfolge, Weichen, Staubereiche,
Systemgrenzen.
2. **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
```text
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.
```json
"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örige `xPlugged*`-Schalter `FALSE`.
- **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_skeleton` erzeugt 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 (Ausnahme `2Sep1Swi`, PinStore).
- **Weitere Layout-Angaben:** `xIsBorner`, Vorfahrt ja/nein, tragender Förderer
mit Rolle (heute `hosts` ohne Rolle), Längen für `tConvEmpty` und Staulängen.
- **Ableitungen aus `scl_context` nach `tro_flow`/`model` verschieben,** 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.
- 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 aus `e_planning.py`
(Lagebezug über `dxf_registration`, Höchst-/Sollabstand), jetzt gegen die Slots;
- **Nummernregel**: `MB = BG + 1` bzw. 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.
- Handkorrekturen in `cfg/hw_overrides.ini` (analog `cfg/tro_overrides.ini`).
- Ausgabe `<csv>_anlage.json`: Layoutteil unverändert, daneben
```json
"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-`TeileId` taugt dafür **nicht**: sie ändert sich zwischen
zwei CSV-Exporten (siehe dort). `layoutId` in `bindings` dient 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`.
- `--eplan` und die Zusammenführung in `scl_context._separator` entfallen; der
Kontext liest Namen aus `bindings`, offene Slots werden `TODO(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_CallSensors` aus 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_tros` selbst 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 zu `tro_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.
Von `tro_flow` angelegt, von den SPS-Programmierern umbenannt.
```ini
; Beispiel, Werte erfunden
[mubea]
TRO107 = 12450.0, 3310.0 ; Kreisel 2 vor Beladung
TRO108 = 13250.0, 3310.0
```
- **Standard (IDs halten):** `tro_flow` liest 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>]` in
`cfg/tro_overrides.ini` und die Zuordnungen von `hw_assign` stabil.
### Staubereiche
**Bisheriges Namensschema** (Referenzen UH01–UH05, `doc/TRO_Katalog/connect.ini`,
286 Staubereiche):
```text
"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` … `_6` in Umlaufrichtung.
- 249 der 286 folgen diesem Schema. Sonderfälle: Lagerlinien `Storage1.1.2` (24),
Übergabe an eine andere Steuerung `IO_Device_UHxx_TO_UHyy…` bzw. lokal
`#arCarrierHandoverJam5000` (9), `JamBuffer101` im 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_2` mit 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 Name `TODO(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 deren `FC_Call_Jams` ab. 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
1. **TRO-IDs stabil machen:** ID-Datei, Wiederfinden über die Lage,
`--renumber`. Darauf bauen Overrides, Staubereiche und Zuordnungen auf.
2. Slots und `jamAreas` in die TRO-JSON (Umbau 1), ein Eingangs-Staubereich je
TRO — ohne Slots hat die Zuordnung kein Ziel.
3. `hw_import` mit dem TIA-Import als erster Quelle.
4. `hw_assign` mit der räumlichen Logik aus `e_planning.py`; `e_planning.py` als
Übergangshülle.
5. `scl_skeleton` auf `<csv>_anlage.json` umstellen, `--eplan` entfernen;
`tro_annotate` auf JSON umstellen.
6. 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.