Stufen 2 und 3 aus doc/Konzept_Layout_Hardware_SCL.md: - lib/hw_import.py: TIA-Import (*_TIA.xlsx, ohne openpyxl gelesen) + Positionsdatei (*_positionsconv.json) -> <projekt>_hw.json: je BMK Adresse, Index-Konstante, VERW, Station, Lage, Foerderer (K0102, #106 -> K0106); Antriebe MA/FC/GF; Gegenpruefung beider Quellen. - lib/merge_hw_layout.py: <csv>_tro.json + <projekt>_hw.json -> <csv>_anlage.json (model.AnlageDocument): bindings je TRO-ID + Slot + Rolle mit Konstante und Adresse, Foerderer per Mehrheit (Mubea: K0102 = Kreisel3, K0104 = Kreisel2, K0105 = Kreisel1), Handkorrekturen cfg/hw_overrides.ini. Zuordnungslogik aus e_planning.py hierher verschoben; e_planning re-exportiert sie, Ergebnis unveraendert. - TRO-JSON traegt optional `parts` (Lage/Huellbox, tro_flow --json), PinStore bekommt Slots line<n>. - Gespeicherter Lagebezug mit SHA-256 der Positionsdatei; Unterordner in Eingabenamen relativ zu SKEL_DATA. - Doku: Python_Scripts.md 5d/5e, Konzept, E-Planung_Bruecke (Abgleich mubea_layout.dxf / CSV / E-Planung). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
417 lines
22 KiB
Markdown
417 lines
22 KiB
Markdown
# 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 TIA.xlsx, positionsdraw.json
|
||
(TROs, Abfolge, ──hw_import──> <projekt>_hw.json
|
||
Staubereiche, Slots) (globale Variablen, Geräte)
|
||
│ │
|
||
└──────────── merge_hw_layout ─────────────────┘
|
||
│
|
||
<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`, `*_positionsdraw.json` (optional `*_EA.xlsx`/`*_WSCAD.xlsx` ohne Positionsdatei) | `<projekt>_hw.json` | vorhanden (2026-10-15), ohne EA/WSCAD |
|
||
| 3 Zuordnung | `merge_hw_layout.py` | `<csv>_tro.json`, `<projekt>_hw.json`, Regeln, `cfg/hw_overrides.ini` | `<csv>_anlage.json`, Bericht `.md` | vorhanden (2026-10-15, 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`.
|
||
|
||
**Stand (2026-10-11), erster Teil umgesetzt:**
|
||
|
||
- `model.Slot` und `DerivedTro.slots`: `separator<n>`, `switch<n>`,
|
||
`scanner<n>`, `drive` mit Rollen, Anzahl aus dem Katalog (`derive_slots`).
|
||
Weichen-Slots haben noch keine `layoutId`: `tro_flow` hält das Weichen- bzw.
|
||
Ausschleuselement nicht am TRO fest.
|
||
- `model.JamArea` und `TroDocument.jamAreas`: je Separator laut Katalog ein
|
||
Eingangs-Staubereich `J<Separator>` mit allen Vorgängern, dem Host und der
|
||
Lage (`derive_jam_areas`). Bei 2Sep-Typen ist die Aufteilung der Vorgänger
|
||
auf die zwei Eingänge offen (Hinweis im Feld `note`); beim PinStore heißt
|
||
der Eingang vorläufig nach dem ersten Linien-Separator.
|
||
- `scl_context` liest die Staubereiche aus der JSON: **ein** `JamEntr` je
|
||
eigenem Staubereich statt je Vorgänger (Abweichung zu UH01–UH05 behoben),
|
||
jeder Ausgang nennt im Kommentar den Staubereich des Nachfolgers. Golden
|
||
Files neu erzeugt. Eine v3-Datei ohne `jamAreas` wird weiter gelesen.
|
||
- **Noch offen aus Umbau 1:** Layout-ID der Weichen, `xIsBorner`, Vorfahrt,
|
||
Host-Rolle, Längen (`tConvEmpty`, Staulängen), `<NNNN>`/`<k>` für den
|
||
SCL-Namen der Staubereiche.
|
||
|
||
### 2. Neues Skript `hw_import.py` (Stufe 2)
|
||
|
||
- Liest TIA-Import (PLC Tags + Constants) und `positionsdraw.json`. Das genügt:
|
||
bei Mubea stehen alle BMK der Positionsdatei im TIA-Import, die Kommentare sind
|
||
gleich; EA-Liste und WSCAD-Import bringen nichts dazu (EA ohne Namen, WSCAD nur
|
||
die E/A-Baugruppe, die `KENNZEICHNUNG` schon trägt). EA/WSCAD nur als Ersatz,
|
||
wenn keine Positionsdatei vorliegt (Weg "nur EA-Liste" in Stufe 3). Befund in
|
||
`doc/E-Planung_Bruecke.md`, "Nachprüfung 2026-10-15".
|
||
- 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 `merge_hw_layout.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.
|
||
|
||
**Stand Umbau 2/3 (2026-10-15), umgesetzt:**
|
||
|
||
- `lib/hw_import.py` (`bin/hw_import.bat`): TIA-Import (Blätter an der
|
||
Kopfzeile erkannt, xlsx ohne openpyxl gelesen) + Positionsdatei →
|
||
`<projekt>_hw.json` (`HardwareDocument`, `sps_skel-hw-v1`): je BMK Adresse,
|
||
Richtung, Index-Konstante, VERW, Station, Lage, Förderer; Antriebe mit
|
||
Motorschutz und Geber; Gegenprüfung beider Quellen. EA-Liste/WSCAD nicht
|
||
gelesen (Weg "nur EA-Liste" bleibt offen).
|
||
- `lib/merge_hw_layout.py` (`bin/merge_hw_layout.bat`): `<csv>_tro.json` +
|
||
`<projekt>_hw.json` → `<csv>_anlage.json` (`model.AnlageDocument`,
|
||
`sps_skel-anlage-v1`): Layout unverändert unter `layout`, daneben
|
||
`bindings[]` (Schlüssel TRO-ID + Slot + Rolle, mit Konstante und Adresse aus
|
||
dem TIA-Import, Status `zugeordnet`/`offen`/`widerspruch`/`ohne_slot`) und
|
||
`conveyors[]`. Handkorrekturen `cfg/hw_overrides.ini`, Zahlenwerte
|
||
`cfg/parameter.ini [merge_hw_layout]`.
|
||
- Damit `merge_hw_layout` kein CSV liest, trägt die TRO-JSON jetzt `parts` (Lage und
|
||
Hüllbox der Layout-Bauteile, von `tro_flow --json`; Schema bleibt v4, eine
|
||
Datei ohne `parts` liest sich weiter). Ein `PinStore_Auto` hat je Lagerlinie
|
||
einen Slot `line<n>`.
|
||
- **Förderernummer:** die E-Planung nennt Förderer im Klartext als `K0102` bzw.
|
||
`#106` (beides dieselbe Nummer, `CONVEYOR-#103` = `CONVEYOR-K0103`).
|
||
`merge_hw_layout` ordnet sie per Mehrheit der Feldgeräte einem Layout-Förderer zu
|
||
(Mubea: K0102 = Kreisel3, K0104 = Kreisel2, K0105 = Kreisel1). Das ist die in
|
||
"Staubereiche" gesuchte Quelle für `<NNNN>` und für `xInCarouselRun`.
|
||
- Gespeicherter Lagebezug mit SHA-256 der Positionsdatei; ein neuer Stand
|
||
gleichen Namens wird neu ermittelt.
|
||
- Noch offen: Weichen-/Ausschleus-Slots mit Layout-ID (sonst bleiben
|
||
Stausensoren und Ausschleusventile `ohne_slot`), Scanner (`BX`), Weg "nur
|
||
EA-Liste", Umstellung von `scl_skeleton` (Umbau 4).
|
||
|
||
### 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` + `merge_hw_layout`
|
||
|
||
| Teil heute | Wohin |
|
||
|---|---|
|
||
| `load_positionsdraw`, `EDevice`, `pair_drives` | `hw_import.py` |
|
||
| `resolve_transform`, `load_rules`, `_assign_spatial`, `_assign_by_number`, Bericht | `merge_hw_layout.py`, Ziele = Slots statt CSV-Bauteile |
|
||
| `cfg/e_planning.ini` | Regeldatei von `merge_hw_layout` |
|
||
| `EplanDocument` / `<csv>_eplan.json` | entfällt, ersetzt durch `bindings[]` |
|
||
|
||
Übergang: `e_planning.py` bleibt kurz als Hülle, die `hw_import` und `merge_hw_layout`
|
||
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.
|
||
|
||
**Umgesetzt (2026-10-11, `lib/tro_ids.py`, Schalter in `tro_flow.py`;
|
||
Einzelheiten in `doc/Python_Scripts.md` §4 "TRO-IDs"):**
|
||
|
||
- Eine versionierte ID-Datei je Anlage, `cfg/<csv>_tro_ids.ini`, Abschnitt
|
||
`[tro]`: je TRO die ID und die Lage seines Anker-Separators (x, y in mm), der
|
||
Kommentar dahinter nennt Typ, Bezeichnung und Separatoren. Von `tro_flow`
|
||
angelegt, von den SPS-Programmierern umbenannt. Weitere Abschnitte (später
|
||
Separator- und Förderernummern) bleiben bei jedem Lauf erhalten. Ein anderer
|
||
Export derselben Anlage nutzt dieselbe Datei über `--ids`.
|
||
|
||
```ini
|
||
[tro]
|
||
TRO01 = -400.0, 13920.0 ; 1Sep1Swi | Separator 0003 auf Kreisel2 Bahn L | Sep 0003
|
||
K0302_1 = 10310.0, -440.1 ; von Hand umbenannt
|
||
```
|
||
|
||
- **Standard (IDs halten):** `tro_flow` liest die ID-Datei und findet jeden TRO
|
||
über die Lage seiner Separatoren wieder (Toleranz `--id-tolerance`, Standard
|
||
100 mm, nächster Treffer zuerst, je TRO ein Eintrag). Gefundene TROs behalten
|
||
ihre ID, auch umbenannte. Neue TROs bekommen die nächste freie Nummer und
|
||
werden an `[tro]` angehängt; weggefallene stehen im Bericht (mit dem TRO, der
|
||
ihren Separator jetzt enthält), bleiben in der Datei, ihre ID wird nicht
|
||
wiederverwendet. `tro_annotate` liest dieselbe Datei, schreibt sie aber nicht.
|
||
- **Programmschalter `--renumber` (frühe Phase):** alle IDs neu entlang des
|
||
Materialflusses vergeben (Tiefensuche ab den Beladestationen, auf Kreisel und
|
||
Strecke in `TrackIds`-Reihenfolge) und `[tro]` neu schreiben. Ohne ID-Datei
|
||
geschieht dasselbe beim ersten Lauf.
|
||
- **Geprüft** mit `mubea.csv` → `mubea_export.csv` (andere TeileIds): 18 TROs
|
||
wiedergefunden, darunter eine umbenannte ID; `TRO14` als weggefallen gemeldet,
|
||
weil der Export die Separatoren 0005 und 0036 zu einem `2Sep2Swi` (`TRO13`)
|
||
zusammenfasst.
|
||
- **Noch offen:** die Abschnitte `[mubea.csv.tro.TRO03]` usw. in
|
||
`cfg/tro_overrides.ini` hängen an der alten Nummerierung und passen schon
|
||
heute nicht mehr (`TRO03` ist dort Sep 0010, im aktuellen Lauf Sep 0011).
|
||
Sie werden auf die IDs der ID-Datei umgestellt, sobald `tro_flow` die
|
||
Overrides wieder liest.
|
||
- Dadurch werden auch die Abschnitte `[<csv>.tro.<TRO-ID>]` in
|
||
`cfg/tro_overrides.ini` und die Zuordnungen von `merge_hw_layout` 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:**
|
||
|
||
**Ergänzung (2026-10-11):** In einem Mubea-Layout heißen die Staubereiche nach
|
||
**ihrem Separator**: der Staubereich vor `Sep1024` heißt `J1024`. Das passt zum
|
||
Befund oben: der Staubereich ist die Warteschlange vor dem Stopper, also der
|
||
Eingang genau eines TRO bzw. genau eines Separators. Das Layout liegt nicht im
|
||
Repo; Quelle der Separatornummer (Zeichnungsbeschriftung, E-Planung, Vergabe durch
|
||
die SPS-Programmierer) noch klären.
|
||
|
||
- **Kennung nach dem Separator:** `J<Separatornummer>`, z. B. `J1024`. Das ist
|
||
feiner als eine Kennung je TRO und deckt TROs mit mehreren Separatoren
|
||
(`2Sep1Swi` mit `JamEntr1`/`JamEntr2`) ohne Sonderregel ab. Zusammenführungen
|
||
sind kein Problem, weil der Name nur am Nachfolger hängt.
|
||
- **Separatornummern wie TRO-IDs behandeln:** in derselben ID-Datei, über die Lage
|
||
des Separators wiedergefunden, von den SPS-Programmierern vergeben bzw.
|
||
übernommen; `--renumber` vergibt sie in der frühen Phase neu.
|
||
- **Name im SCL — festgelegt: Standard sind die SCL-Dateien UH01–UH05,** also
|
||
`"DB_JamArea<NNNN>".stJam<NNNN>_<k>`. `J<Separatornummer>` ist nur die Kennung
|
||
in der JSON (und die Beschriftung im Layout), nicht der SCL-Name. Für den
|
||
SCL-Namen braucht es je Staubereich:
|
||
- `<NNNN>`: die **Förderernummer** des Förderers, auf dem der Staubereich liegt
|
||
(Kreisel K0102 → `0102`); vergeben von den SPS-Programmierern bzw. aus der
|
||
Hardwareplanung (`KR-K0102`), gepflegt in der ID-Datei wie TRO-IDs und
|
||
Separatornummern;
|
||
- `<k>`: laufende Nummer **entlang des Materialflusses** auf diesem Förderer,
|
||
aus dem Layout abgeleitet (Kreisel in Umlaufrichtung, beginnend an einer
|
||
festzulegenden Stelle, z. B. nach der Einschleusung).
|
||
|
||
Ohne Förderernummer bleibt der Name `TODO(E-Planung)` wie heute.
|
||
- Ausnahmen bleiben Sonderfälle mit eigenem Namen: Lagerlinien, Übergabe an eine
|
||
andere Steuerung, Leerträgerpuffer.
|
||
|
||
### 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.
|
||
**Erledigt** (2026-10-11).
|
||
2. Slots und `jamAreas` in die TRO-JSON (Umbau 1), ein Eingangs-Staubereich je
|
||
TRO — ohne Slots hat die Zuordnung kein Ziel. **Erster Teil erledigt**
|
||
(2026-10-11, siehe Umbau 1 "Stand").
|
||
3. `hw_import` mit dem TIA-Import als erster Quelle. **Erledigt** (2026-10-15,
|
||
siehe unten "Stand Umbau 2/3").
|
||
4. `merge_hw_layout` mit der räumlichen Logik aus `e_planning.py`; `e_planning.py` als
|
||
Übergangshülle. **Erledigt bis auf die Hülle** (2026-10-15): die Logik liegt
|
||
in `merge_hw_layout.py`, `e_planning.py` importiert sie und bleibt vollständig,
|
||
solange `scl_skeleton --eplan` die `<csv>_eplan.json` liest (Schritt 5).
|
||
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
|
||
|
||
- **Staubereiche:** woher die Separatornummer (`Sep1024` → `J1024`) stammt; wo auf
|
||
einem Kreisel die Zählung `<k>` beginnt (Referenz K0102 prüfen). Das SCL-Schema
|
||
ist festgelegt (UH01–UH05).
|
||
- **Toleranz** beim Wiederfinden der TROs über die Lage: vorläufig 100 mm
|
||
(`--id-tolerance`). Ein weiter verschobener Separator wird als "neu" und
|
||
"weggefallen" gemeldet, der Programmierer übernimmt die ID von Hand in der
|
||
ID-Datei. Mit echten Layoutänderungen prüfen, ob der Wert passt.
|
||
- **Korrekturen in BricsCAD oder in der JSON:** zurückgestellt.
|