diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..cecfdfe --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,124 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project purpose + +`sps_skel` takes a mechanical layout (from project planning/sales) together with an +electrical layout (list of sensors, stoppers, switches, etc.) and generates a **skeleton +of Siemens SCL code** ("TRO" — Transfer Route Object — blocks for a conveyor/material-flow +control system) that can be imported directly into TIA Portal. + +The repository is currently in the **design/analysis phase**: `lib/`, `tests/`, `examples/`, +and `cfg/` are empty scaffolding directories (see "Standard Programm Template" structure +below). No generator code has been written yet. What exists today is: + +- `bin/` — environment/venv management scripts (see "Environment scripts" below) +- `data/*.scl` — real SCL code extracted from an existing plant ("HundM_Fortna", 5 + controllers UH01–UH05), used as reference templates for the planned generator +- `doc/*.md` — analysis documents that reverse-engineer the SCL patterns and propose the + JSON schema / code-generation approach + +Read `doc/` before writing any generator code — it contains the actual domain model this +project is meant to implement. + +## Environment scripts (bin/) + +Every script has a `.bat` (Windows) and `.sh` (Linux/macOS) pair. **None of them invoke a +concrete Python script** — they only manage the environment and virtualenv. + +| Script | Purpose | +|---|---| +| `setenv.bat` / `source setenv.sh` | Sets `SPS_SKEL` (project root) and `SKEL_BIN/LIB/CFG/DATA/LOG/RESULTS/EXAMPLES/TESTS`; prepends `SKEL_LIB` to `PYTHONPATH`; creates missing folders | +| `install_py.bat` / `install_py.sh` | Calls `setenv`, creates `.venv` (`py -m venv` / `python3 -m venv`), installs `requirements.txt`. Aborts with a message if `.venv` already exists | +| `activate_venv.bat` / `activate_venv.sh` | Calls `setenv`, activates `.venv` (errors if missing — run `install_py` first) | +| `get_cmd.bat` / `get_cmd.sh` | Calls `setenv`, opens a new shell with the environment variables set | + +Typical workflow on Windows: + +``` +bin\install_py.bat # one-time: create venv + pip install +bin\activate_venv.bat # each session: activate venv + show versions +``` + +Linux/macOS equivalents must be **sourced**, not executed: + +``` +bash bin/install_py.sh +source bin/activate_venv.sh +``` + +Requires Python 3.10+. `requirements.txt` currently has no real dependencies pinned yet +(placeholders for `pydantic`, `pytest`). + +There is no build/lint/test command configured yet — `tests/` is empty and no test +runner or linter is set up. Once code exists in `lib/`, use `pytest` (already anticipated +in `requirements.txt`) and set `PYTHONPATH` via `bin/setenv` first so imports resolve +against `lib/`. + +## Domain model (from doc/) + +The target system is a Siemens TIA Portal / SCL project for automated conveyor/carrier +routing, modeled around **TRO** (Transfer Route Object) blocks. Key documents, read in +this order for onboarding: + +1. **`doc/Json_Layout-Konzept.md`** — the core proposal: a JSON file as single source of + truth (`plc`, `controlUnits`, `sensors[]`, `conveyors[]`, `tros[]`, `loadingBooms[]`, + `emptyCarrBuffers[]`, `routing`, `jamAreas[]`, `scanners[]`, `connections[]`, + `destinations[]`) from which the repetitive, per-topology SCL code in `FB_Main`, + `FB_CallSensors`, `FC_Direction`, `FC_Call_Jams` would be generated. +2. **`doc/TRO_Typen.md`** — catalogs all 10 TRO function-block types actually found across + the 5 reference controllers (UH01–UH05) and shows that 9 of them are additive + combinations of one base type (`1Sep` = one separator/stopper) plus reusable + sub-blocks (`FB_ILS_STRO_Sep`, `FB_ILS_STRO_Switch`, `FB_ILS_STRO_Vario`, + `FB_BarcodeReaderCognex`, `FB_CarrAccumulate1Sep`). Only `LoadingBoom` is structurally + independent. +3. **`doc/EA-Listen-Analyse.md`** — analyzes the raw I/O list Excel exports + (`*_EA.xlsx`/`*_TIA.xlsx`/`*_WSCAD.xlsx`) and companion position/cabling JSON exports, + and what can vs. cannot be auto-derived from them (signal naming prefixes `BG/SF/DI/BP` + for inputs, `MB/MA/QA/DQ/FC/PF` for outputs; topology/timing/customCode cannot be + derived from I/O lists alone — those must come from the JSON model or CAD symbol). +4. **`doc/BricsCAD_TRO_Symbol.md`** — proposes a BricsCAD block symbol whose attributes + feed the JSON `tros[]` entries; documents which fields are captured on the symbol vs. + derived from drawing topology or type-based timing defaults. +5. **`doc/SCL_Analyse_Standardisierung.md`** — cross-controller duplication analysis; + identifies ~22 blocks duplicated identically across all 5 controllers (candidates for + a shared library) and flags "version chaos" areas (e.g. `FB_StockRemovalBLKModul*` + variants) that should NOT be naively merged. +6. **`doc/suggestion.md`** — a follow-up proposal to collapse the 7 `FB_ILS_MTRO_*` + variants into a single `FB_ILS_MTRO` block driven by an array/config descriptor + instead of hand-duplicated numbered members (`...1`, `...2`, `Dir1..Dir4`). References + a not-yet-written `lib/create_skel.py` (`guess_fbtype()`) as the intended generator + entry point — this is the planned shape of the generator, not existing code. + +### Used libraries (referenced but not vendored) + +Most `FB_ILS_MTRO_*` types exist in this repo **only as `.liblink`** references to an +external `ILSLib` library — the actual FB source is not in this Git repo. `data/*.scl` +contains the real **call-site/instantiation code** (parametrization in `FB_Main`) for +those types, not the FB body. Only a few types have local, fully-vendored SCL source +(`FB_ILS_MTRO_Vario_workStation`, `FB_EmptyCarrBuffer`, `FB_LoadingBoom_INBOUND`, +`FB_ILS_MTRO_2Sep1Swi` — the last one unused/orphaned). Treat `data/*.scl` as **read-only +reference material** for pattern extraction, not code to execute or modify. + +## Standard Programm Template + +This project follows the user's standard Python project scaffold convention: + +``` +sps_skel/ + bin/ environment scripts (see above) + cfg/ config files (INI/JSON) — empty for now + data/ input data, gitignored except the .scl reference templates + doc/ documentation + examples/ example files — empty for now + lib/ Python source — empty for now, this is where the generator belongs + log/ gitignored + results/ gitignored + tests/ unit tests — empty for now +``` + +When adding the generator, put it under `lib/` (importable via `SKEL_LIB` on +`PYTHONPATH`), keep `bin/*.bat`/`*.sh` scripts environment-only (do not add +project-specific script invocations to them per the user's convention), and add tests +under `tests/`. diff --git a/README.md b/README.md index 9d50821..3c2138e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # sps_skel -> Kurze Projektbeschreibung hier eintragen. +> Das Programm erhält ein mechanische Layout von der Projektierung oder +> Angebotswesen zusammen mit dem elektronischen Layout mit der Liste aller +> Sensoren, Stopper, etc. Daraus erstellt es dann ein Skelett für die SPS +> Programmierung, welches direkt ins TIA Portal importiert werden kann. ## Projektstruktur diff --git a/doc/HundM/BricsCAD_TRO_Symbol.md b/doc/HundM/BricsCAD_TRO_Symbol.md new file mode 100644 index 0000000..bad67d2 --- /dev/null +++ b/doc/HundM/BricsCAD_TRO_Symbol.md @@ -0,0 +1,105 @@ +# BricsCAD-Symboldefinition — TRO-Block + +## Zweck + +Dieses Dokument beschreibt ein BricsCAD-Blocksymbol ("TRO-Symbol"), das im Layoutplan der Förderanlage platziert wird und dessen Attribute per DXF/Skript-Export in ein TRO-Objekt der [JSON-Layout-Konfiguration](Json_Layout-Konzept.md) überführt werden können (Abschnitt "4. TROs"). + +Das Symbol bildet **nur die Daten ab, die sich pro physischer Instanz unterscheiden und nicht aus Nachbarschaft/Zeichnung oder aus dem Typ ableitbar sind**. Timing-Werte (`trailingTime`, `handlingTime`, `senFree`, `senWait`, `jamTime`, ...) werden bewusst **nicht** am Symbol gepflegt, sondern beim JSON-Export aus einer Default-Tabelle pro `TRO_TYPE` gezogen (siehe [Kapitel "Defaults je Typ"](#defaults-je-typ-timing)). Für Sonderfälle steht ein optionales Override-Attribut zur Verfügung. + +Ebenfalls nicht am Symbol gepflegt: **Position/Rotation** (kommt aus der Blockeinfügung) und **Connections/JamAreas** (`entry`/`exit`, kommen aus der grafischen Topologie — welche Verbindungslinie an welchem Anschlusspunkt des Symbols endet). + +--- + +## Attributliste (ATTDEF) + +### Gruppe 1 — Kern / Identifikation (Pflicht, bei jedem Typ) + +| Tag | Prompt (DE) | Beispielwert | Default | Typ | Bemerkung | +|---|---|---|---|---|---| +| `TRO_ID` | TRO-ID | `TRO107` | — | Text | Eindeutig; Basis für `mainTroNo` (`cMainTro107`), `separator.no` (`cSep107.1`), `hmi`-Pfad | +| `TRO_TYPE` | TRO-Typ | `1Sep1Swi` | — | Liste (Enum) | Steuert `fbType` + Timing-Defaults; siehe [TRO-Typen-Tabelle](TRO_Typen.md) | +| `CONTROL_UNIT` | Steuerkreis | `OF1` | `OF1` | Liste (Enum) | Sicherheitszone/Schaltschrank | +| `COMMENT` | Bezeichnung | `Weiche Boom 1` | — | Text | Klartext für Doku, HMI, SCL-Kommentar | + +### Gruppe 2 — Hardware-IO (Pflicht, nicht ableitbar) + +| Tag | Prompt (DE) | Beispielwert | Default | Typ | Bemerkung | +|---|---|---|---|---|---| +| `SENSOR_IN_SEP` | Sensor Separator | `BG3306` | — | Text | Hauptsensor, ergibt `sensorInSep` + `cIn`-Konstante | +| `SENSOR_JAM2` | Sensor Jam 2 | `BG3305` | *(leer)* | Text, optional | zweiter Stau-/Kontrollsensor | +| `SENSOR_JAM3` | Sensor Jam 3 | `BG3330` | *(leer)* | Text, optional | nur bei Switch-Typen mit 3. Sensor | +| `STOPPER_OUTPUT` | Ausgang Stopper | `MB3306` | — | Text | Stopper-/Vereinzelungs-Ausgang | +| `SWITCH_OUTPUT` | Ausgang Weiche | `MB3304` | *(leer)* | Text | nur bei `1Sep1Swi` / `1Sep2Swi` sichtbar/Pflicht | + +### Gruppe 3 — Scanner (optional, blendet sich nur bei Bedarf ein) + +| Tag | Prompt (DE) | Beispielwert | Default | Typ | Bemerkung | +|---|---|---|---|---|---| +| `SCANNER_ID` | Scanner-ID | `BX1104` | *(leer)* | Text, optional | Cognex-Barcodeleser-Kennung | +| `HAS_SSCC_SCANNER` | SSCC-Scanner? | `false` | `false` | Bool (Liste `true`/`false`) | schaltet `ssccScanner`- und `wcsTelegram`-Block im Export frei | + +### Gruppe 4 — Priorität / Verhalten + +| Tag | Prompt (DE) | Beispielwert | Default | Typ | Bemerkung | +|---|---|---|---|---|---| +| `PRIORITY_TYPE` | Prioritätsart | `releaseOk` | `releaseOk` | Liste (Enum: `releaseOk`, `Manager`, `Dir2Manager`) | steuert `priority`-Block im JSON | +| `IS_BORNER` | Einschleusepunkt? | `false` | `false` | Bool | markiert Borner-TROs (Direction-Zuweisung an dieser Stelle) | +| `N_TO_1_DESTINATIONS` | Anzahl Weichenziele | `3` | *(leer)* | Ganzzahl, optional | nur bei Switch-Typen | + +### Gruppe 5 — Override (Ausnahmefälle, i. d. R. leer) + +| Tag | Prompt (DE) | Beispielwert | Default | Typ | Bemerkung | +|---|---|---|---|---|---| +| `OVERRIDE_TIMING_JSON` | Timing-Override (JSON) | *(leer)* | *(leer)* | Text, optional | Freitext-JSON-Fragment, überschreibt einzelne Default-Timings dieser Instanz (z. B. `{"trailingTime":"T#100ms"}`) | +| `CUSTOM_CODE_REF` | Sonderlogik-Referenz | *(leer)* | *(leer)* | Text, optional | Verweis auf ein `customCode`-Snippet, das der Export separat einbindet (siehe Json-Konzept Abschnitt 10) | + +--- + +## Sichtbarkeits-/Pflichtregeln beim Attribut-Dialog + +| Regel | Bedingung | +|---|---| +| `SWITCH_OUTPUT`, `N_TO_1_DESTINATIONS` nur sichtbar/Pflicht | `TRO_TYPE` ∈ {`1Sep1Swi`, `1Sep2Swi`} | +| `SENSOR_JAM3` nur sichtbar | `TRO_TYPE` ∈ {`1Sep1Swi`, `1Sep2Swi`} | +| `SCANNER_ID` Pflicht | `TRO_TYPE` = `1Sep_SSCC` oder Scanner-Kommentar in `COMMENT` | +| `HAS_SSCC_SCANNER` nur `true` möglich | `TRO_TYPE` = `1Sep_SSCC` | +| `PRIORITY_TYPE` = `Dir2Manager` nur zulässig | `TRO_TYPE` = `1Sep1Swi` | + +Diese Regeln werden nicht durch BricsCAD selbst erzwungen (ATTDEF kennt keine bedingte Sichtbarkeit), sondern im Export-Skript (Validierung) und optional per Dynamic-Block-Sichtbarkeitszuständen je `TRO_TYPE`-Variante. + +--- + +## Empfohlener Blockaufbau + +- **1 Basis-Blockdefinition** `SYM_TRO` mit allen Attributen aus Gruppe 1–5 (leere Defaults für optionale Gruppen). +- **Anschlusspunkte** als benannte Punkte/Layer im Block (`PT_ENTRY`, `PT_EXIT`, `PT_EXIT2`, `PT_EXIT3`) — dienen dem Export-Skript zur automatischen Ableitung der `connections[]`-Einträge aus angeschlossenen Linien, ersetzen die früher diskutierten Attribute für `entry`/`exit`. +- **Grafik** je `TRO_TYPE` unterschiedlich einfärben/formen (z. B. über Dynamic-Block-Sichtbarkeitszustand), damit der Plan auf einen Blick den Typ zeigt — analog zu den `classDef`-Farben im Mermaid-Diagramm in Json_Layout-Konzept.md (`sep`, `swi`, `buf`, `vario`, `sscc`). + +--- + +## Defaults je Typ (Timing) + +Die Timing-Defaults werden **nicht** am Symbol gepflegt, sondern zentral im Export-Skript als Lookup-Tabelle `TRO_TYPE → Timing-Defaults` hinterlegt (z. B. aus den in Json_Layout-Konzept.md Abschnitt 4 beobachteten Werten: `1Sep` → `trailingTime=T#600ms, handlingTime=T#200ms`, `1Sep1Swi` → `trailingTime=T#100ms, handlingTime=T#50ms`, `Vario` → `trailingTime=T#800ms, handlingTime=T#300ms`, usw.). Die vollständige, typspezifische Default-Tabelle inkl. aller in dieser Anlage tatsächlich vorkommenden Typen steht in [TRO_Typen.md](TRO_Typen.md). + +## Beispiel: Attributsatz für TRO107 (Switch Boom 1) + +``` +TRO_ID = TRO107 +TRO_TYPE = 1Sep1Swi +CONTROL_UNIT = OF1 +COMMENT = Weiche Boom 1 (LS / Clearing) +SENSOR_IN_SEP = BG3306 +SENSOR_JAM2 = BG3305 +SENSOR_JAM3 = BG3330 +STOPPER_OUTPUT = MB3306 +SWITCH_OUTPUT = MB3304 +SCANNER_ID = (leer) +HAS_SSCC_SCANNER = false +PRIORITY_TYPE = Dir2Manager +IS_BORNER = false +N_TO_1_DESTINATIONS = 3 +OVERRIDE_TIMING_JSON = (leer) +CUSTOM_CODE_REF = (leer) +``` + +Der Export-Generator ergänzt daraus automatisch `mainTroNo=cMainTro107`, `separator.no=cSep107.1`, `hmi=DB_Interface_HMI.stTRO.TRO107`, die Timing-Werte aus der Default-Tabelle für `1Sep1Swi`, sowie `jamAreas.entry/exit2/exit3` aus den an `PT_ENTRY`/`PT_EXIT2`/`PT_EXIT3` angeschlossenen Verbindungslinien. diff --git a/doc/HundM/EA-Listen-Analyse.md b/doc/HundM/EA-Listen-Analyse.md new file mode 100644 index 0000000..aa50e2b --- /dev/null +++ b/doc/HundM/EA-Listen-Analyse.md @@ -0,0 +1,141 @@ +# Analyse der Ein-/Ausgabelisten (data/Eingaben) + +## Kontext + +In `data/Eingaben/` liegen je Steuerung (ILS-1 bis ILS-5, entspricht UH01-UH05) drei Excel-Dateien mit denselben E/A-Punkten in drei Sichten: + +| Datei | Inhalt | +| --- | --- | +| `..._EA.xlsx` | Rohliste: Adresse (`E000.0`), Kommentar, Zeilenreferenz (Schaltplan) | +| `..._TIA.xlsx` | Import-Liste fuers TIA Portal: Blatt "PLC Tags" (BMK-Name, `Data Type`, `%E`/`%A`-Logikadresse, Kommentar, HMI-Flags) + Blatt "Constants" (`cIn`-Indexkonstanten) | +| `..._WSCAD.xlsx` | Import-Liste fuers WSCAD (E-CAD): Anschluss, Kommentar, **Bezug** (Ortskennzeichen, z.B. `=A01+UC2101-KF1DI1`) | + +Alle Signale sind **Bool** (reine Digital-E/A-Listen). Analogwerte (Tilt-/Distanzsensoren), PROFINET-Geraete (Cognex-Scanner BX, RFID) und Antriebsparameter sind **nicht** enthalten — diese werden anderweitig projektiert. + +Umfang: ILS-1 (UH01) 443 Tags, ILS-2 (UH02) 1578 Tags, ILS-3 (UH03) 1608 Tags, ILS-4 (UH04) 203 Tags, ILS-5 (UH05) 243 Tags. + +## Namenspraefixe (BMK-Schema) + +| Praefix | Bedeutung | Beispiel | +| --- | --- | --- | +| `BG` | Sensor / Geber (Eingang) | `BG0280`: in Separator LS1 | +| `SF` | Schalter / Taster / Sicherheitssignal (Eingang) | `SF0025`: Schluesselschalter LS1 | +| `DI` | Diagnose-/Feedback-Eingang (Sicherung, Schuetz) | `DI0011`: Feedback Hauptschuetze aktiv | +| `BP` | Druckschalter | `BP0004`: Druckschalter Druckluft OK | +| `MB` | Ausgang Separator-/Stopper-Ventil | `MB0280`: Separator LS1 | +| `MA` | Ausgang Motor (Contactor) | `MA0060`: Motor (ILS-KR-M0101) | +| `QA` | Ausgang Motor / Hauptschuetz | `QA0071`: Motor 1 Ausfahren LS1 | +| `DQ` | Digitalausgang Sonderfunktion (Fuss, RFID-Handshake) | `DQ0322`: Stuetzfuss aufwaerts LS1 | +| `FC` | Motorschutz-Feedback | `FC0060`: MSS ausgeloest (ILS-KR-M0101) | +| `PF` | Leuchtmelder / Signalsaeule | `PF0022`: Signalsaeule gruen "Betriebsbereit" | + +## Was daraus automatisch fuers JSON gewinnbar ist + +### Vollstaendig generierbar + +| JSON-Abschnitt / Zielbaustein | Quelle | +| --- | --- | +| `sensors[]` -> `FB_CallSensors`, Dimensionierung `DB_Inputs` | TIA "PLC Tags" (alle BG-Tags: id, hwInput, Kommentar) + "Constants" (`cInBG...` ist exakt der Sensor-Array-Index) | +| Konstanten-Tabelle (TIA-Konstantenliste) | Constants-Blatt 1:1 | +| PLC-Variablentabellen (Ordner `PLC-Variablen/Mewa`) | "PLC Tags" — das ist der eigentliche Importzweck der Datei | +| `outputs`-Felder der TROs/Conveyors/LoadingBooms | MB (Stopper/Separatorventile), MA/QA/DQ (Motoren), FC (Motorschutz), PF (Leuchtmelder) | + +### Teilweise generierbar — ueber Kommentar-Parsing + +Die Kommentare folgen einem erstaunlich systematischen Muster: + +```text + [] () +``` + +Beispiele: `in Separator 1 (ILS-CV M5003) WS1.1`, `AE Abzweig Str.3 (Block 1.1.1)`, `Pin Abfrage (KR-M1101) Block 1.1.1`. + +Daraus laesst sich je Foerdertechnik-Einheit (M-Nummer) ein **TRO-/Conveyor-Geruest** ableiten: + +- `sensorInSep` aus "in Separator n", Stopper-Output aus "Separator n", `sensorJam*` aus "Stausensor"/"Staumelder Einfahrt" +- Der **FB-Typ** ist heuristisch bestimmbar: + - "AE Abzweig" -> Weiche (`1SepNSwi`) + - "Mitnehmerfinger in Position" / "Foerderer voll" / "MT in Position" -> `Vario` + - "Pin Abfrage" / "Pruefung MT Pos.x" -> `PinStore` + - mehrere "Str.1"..."Str.8" unter einem Block -> mehrzeiliger Puffer/Block + - Anzahl der "in Separator n" (1 vs. 2) -> 1Sep vs. 2Sep +- `conveyors[]`-Grundgeruest: FC/MA-Paare je `KR-M...`/`CV-M...` -> `motorProtectName` + `powerContactor` + +Die M-Nummern tauchen unveraendert auch im SCL-Code auf (Beleg: `REGION Carousel KR-M5002` in UH05/FB_Main.scl, `TRO208 : "FB_ILS_MTRO_PinStore_Auto"; // Block 1.1.1` in UH02/FB_Main.scl) — die Zuordnung Liste <-> Code ist also nicht nur Vermutung, sondern nachweisbar identisch. + +### Nicht gewinnbar + +- Timing-Parameter (`trailingTime`, `handlingTime`, `senFree`/`senWait` etc.) +- Priority-Manager-Verdrahtung, Release-Ausdruecke +- `customCode`-Bloecke +- Scanner-Zuordnung (Cognex BX-Geraete sind PROFINET-Teilnehmer, nicht in den Digital-E/A-Listen) +- Vor allem die **Topologie**: `connections[]`, `jamAreas[]`, `routing`/`destinations[]`. Die Reihenfolge der M-Nummern liefert nur einen schwachen Hinweis auf Nachbarschaft, keine belastbare Verkettung. + +## Hoehere Ebenen in den Listen + +Die Listen enthalten eine durchgaengige **Anlagenhierarchie**, die im aktuellen JSON-Konzept noch nicht abgebildet ist: + +1. **Signal** — BG/MB/MA/FC/PF/SF/QA/DQ (unterste Ebene) +2. **Foerdertechnik-Einheit = M-Nummer** — `KR-M5002` (Kreisel), `CV-M5003` (Foerderer), `KR-K1101` (Kreisel-Einfahrt). Entspricht 1:1 einem Conveyor bzw. einer TRO-Instanz. +3. **Bereichs-/Funktionsgruppen = Gruppen von TROs**: + - **Block x.y.z** — PinStore-Bloecke, z.B. UH02: Block 1.1.1 – 1.3.4 (3 Gassen x 4 Ebenen = 12 Bloecke), deckungsgleich mit den Datenbausteinen `DB_Storage1.1.1` ... `DB_Storage1.3.4`; darunter je Block bis zu 8 Gassen ("Str.1"..."Str.8") + - **LS 1 / LS 2** — Ladeschleifen in UH01 (Boom-, Fuss-, Rad-Signale) + - **WS x.y** — Work Stations in UH04/UH05 (manuelle Arbeitsplaetze) + - **UZ0x0y** — Umzaeunungs-/Sicherheitszonen (Reset-/Freigabe-Taster je Zone) -> entspricht den `controlUnits` im JSON-Konzept +4. **Elektro-Topologie** (nur in den WSCAD-Listen, ueber das Feld "Bezug") — UC-Feldstationen mit Klemmenkarten (`KF1DI1`, `KF1FDQ2` = fehlersichere Karte, 8 oder 16 Kanaele). Die UC-Nummerierung spiegelt die logischen Bereiche: UH02 nutzt z.B. `UC21xx`/`UC22xx`/`UC23xx` fuer die drei PinStore-Bloecke 2.1/2.2/2.3; F-Karten markieren zugleich die Safety-relevanten Signale. +5. **Steuerung UH0x** — je Dateitripel eine SPS-Konfiguration, entspricht dem `plc`-Abschnitt im JSON. + +## Verwendung von Positionen + +Zusaetzlich zu den Excel-Listen liegen in `data/Eingaben/` vier JSON-Dateien mit Positions- und Verkabelungsdaten, offenbar Exporte eines WSCAD/CAD-Auswertungstools: + +| Datei | Inhalt | +| --- | --- | +| `ST500592_10_5-9_ILS_positions.json` | Positionen (x/y in mm) aller Sensoren/Aktoren, Schaltschrankelemente und Verteiler des ILS-Systems (UH01–UH05) | +| `ST500592_10_5-9_ILS_todraw.json` | Kabelverbindungen (Verteiler ↔ Signal) mit Routing-Polylinie und -laenge, Kabeltrassen (`rack_geometry`), Fehlerprotokolle | +| `ST500592_Omniflo_positionsdraw.json` / `ST500592_10_5-10_Omniflo_todraw.json` | Gleiches Schema, aber fuer ein weiteres System ("Omniflo", `SPS` 6/7 = UH06/UH07) — **keine** SCL-Konfiguration dazu im Repository, also vermutlich eine benachbarte/zukuenftige Anlage ausserhalb des aktuellen Scopes | + +### Struktur + +- **`sensors`** / **`schaltschrank_elemente`**: Dict, Schluessel `@` (z.B. `BG3260@4`), da BMK-Namen ueber die SPSen hinweg wiederverwendet werden. Werte enthalten u.a. `pos` (x,y in mm), `BEZEICHNUNG` (Kommentartext, identisch zur TIA/EA-Liste), `KENNZEICHNUNG` (WSCAD-Ortskennzeichen), `SPS` und **`VERW`**. +- **`VERW`** ist ein kontrolliertes Vokabular fuer die Funktionsrolle des Signals, z.B. `Sep`, `In sep`, `Jam detector`, `ES branch` (Weichen-Abzweig!), `conveyor full`, `MT in Position`, `Finger in position`, `PIN query`, `Sync P1`–`P4`. Das ist eine **zuverlaessigere Quelle fuer die Rollenklassifikation** als das Parsen der freien Kommentartexte (siehe oben) — z.B. laesst sich eine Weiche (`ES branch`) oder ein Vario-Sync-Punkt (`Sync Px`) direkt am `VERW`-Wert erkennen statt ueber Text-Heuristik. +- **`mappings`**: Verteiler (`UC0401`, ...) -> Liste der daran angeschlossenen BMK — das ist die **belastbare** (aus der Verkabelung stammende) Zuordnung Signal -> Schaltschrank, nicht nur eine Namenskonvention wie in der WSCAD-Excelliste. +- **`distributors`**: Verteiler -> eigene Position (x,y). +- **`kabel`** (nur `_todraw.json`): je Verbindung `id` (`"-@"`), Routing-Polylinie (`coords`) und `length` (mm) — die tatsaechliche Kabelstrecke inkl. Verlegung ueber Kabeltrassen/Pritschen. +- **`rack_geometry`** / **`tunnels`**: Geometrie der Kabeltrassen bzw. Bodentunnel, auf denen die Kabel gefuehrt werden. +- **`not_found`** / `errors_*` / `warnings`: Validierungsprotokoll des Exporttools (fehlende Verteilerzuordnung, ungueltige Kennzeichnung, doppelte IDs, Attributsluecken) — kein Topologie-Input, aber wertvoll als **Datenqualitaets-Check** fuer einen Generator. + +### Lassen sich Topologie-Hinweise ableiten? + +Ein Abgleich der bekannten UH01-Kette (siehe [TRO_Graph_UH01-UH05.dot](TRO_Graph_UH01-UH05.dot)) gegen die Sensor-Positionen zeigt ein klares Muster: + +| TRO | Sensor | Position (x, y in mm) | Abstand zum vorherigen | +| --- | --- | --- | --- | +| TRO100 | BG3242@1 | (341906, 164862) | – | +| TRO103 | BG3271@1 | (331115, 163051) | ~10,9 m | +| TRO107 | BG3306@1 | (333164, 152428) | ~10,7 m (nach TRO105) | +| TRO104 | BG0280@1 | (370801, 187134) | ~46,4 m (Sprung!) | +| TRO105 | BG3280@1 | (334141, 159162) | ~46,1 m (Sprung zurueck!) | +| TRO109 | BG0340@1 | (376774, 187155) | liegt nahe bei TRO104 | + +Die TROs des Hauptkreislaufs (100, 103, 105, 107, ...) liegen raeumlich dicht beieinander (Abstaende im Bereich 5–15 m), waehrend TRO104/TRO109 (Vorstopper vor den Ladeschleifen LS1/LS2) einen grossen sprunghaften Abstand aufweisen — sie liegen physisch bei den Ladeschleifen, einem raeumlich getrennten Anlagenteil, zu dem die Carrier ausgeschleust und zurueckgefuehrt werden. Das deckt sich exakt mit der bereits aus dem SCL-Code extrahierten Topologie (TRO104 -> LoadingBoom1 -> TRO105). + +**Ergebnis:** Positionen liefern **keine eigenstaendige, vollstaendige Topologie** (dafuer fehlt die Information, in welcher Reihenfolge/Richtung Carrier durch nahe beieinanderliegende Elemente laufen — u.a. bei parallelen Foerderstrecken oder Bloecken mit identischen Abstaenden nicht eindeutig). Sie eignen sich aber sehr gut als: + +1. **Validierungswerkzeug** fuer die aus dem SCL-Code extrahierte `connections`-Topologie: kurze Abstaende zwischen verbundenen TROs bestaetigen Plausibilitaet, groessere Spruenge markieren bewusste Anlagenteile (Ladeschleifen, Storage-Gassen, AMR-Uebergabe) und lassen sich in der Analyse gezielt kommentieren. +2. **Raeumliche Clusterbildung**: TROs/Sensoren, die im selben Cluster von Koordinaten liegen, lassen sich automatisch zu den bereits identifizierten Bereichsgruppen (Block, LS, WS, UZ) buendeln oder solche Gruppen erst entdecken, falls die textuelle Kommentar-Zuordnung fehlt oder uneinheitlich ist. +3. **Massstabsgetreue Lageplan-Darstellung**: der bestehende TRO-Graph ([TRO_Graph_UH01-UH05.svg](TRO_Graph_UH01-UH05.svg)) nutzt eine automatische Graphviz-Anordnung ohne Bezug zur echten Anlage. Mit den `pos`-Koordinaten liesse sich zusaetzlich ein **massstabsgetreuer Lageplan** rendern (SVG/DXF mit echten x/y-Koordinaten je TRO/Sensor), der die abstrakte Topologie mit der realen Hallenlayout ueberlagert. +4. **Cabinet-/Verteilerzuordnung**: `mappings` + `distributors` liefern die **tatsaechliche** (aus der Verkabelung stammende) Zuordnung Sensor -> Schaltschrank/Verteiler samt dessen Position — praeziser als die Namenskonvention der WSCAD-Bezugsfelder, und direkt nutzbar fuer den `controlUnits`-Abschnitt im JSON. +5. **Kabel-/Trassendokumentation**: `kabel`, `rack_geometry` und `tunnels` erlauben es, Kabellaengen und -wege je Verbindung automatisch zu dokumentieren (z.B. fuer Stuecklisten/BOM oder Trassenauslastung) — fachlich getrennt von der SPS-Programmlogik, aber ein sinnvoller Zusatznutzen derselben Datenbasis. + +## Konsequenz fuer das JSON-Layout-Konzept + +Um Ebene 2–4 aus den Excel-Listen automatisch befuellen zu koennen, sollte das JSON-Schema (siehe [Json_Layout-Konzept.md](Json_Layout-Konzept.md)) um folgende Punkte erweitert werden: + +1. Ein Feld `unit` bzw. `mNumber` an jedem TRO/Conveyor als expliziter Schluessel zur E/A-Liste (z.B. `"unit": "M5003"`). +2. Eine neue Gruppierungsebene `areas`/`groups` (Block, LS, WS, UZ, UC-Station), die TROs/Conveyors buendelt und mit dem "Bezug"-Feld der WSCAD-Liste sowie der UZ-Nummerierung der TIA-Liste verknuepft. +3. Ein optionales Feld `pos: {x, y}` je Sensor/TRO/Conveyor (aus den `..._positions.json`), fuer massstabsgetreue Layout-Darstellung und als Validierungsdatum fuer die Topologie. +4. Ein Feld `controlUnit`/`cabinet` mit dem Verteiler-BMK (aus `mappings`), zusaetzlich zur bzw. anstelle der bisherigen Ableitung aus der WSCAD-Namenskonvention. +5. Nutzung des `VERW`-Vokabulars aus den Positions-JSONs als primaere Quelle fuer die Rollenklassifikation der BG/MB-Signale (statt bzw. ergaenzend zur Kommentar-Textheuristik) — reduziert Fehlklassifikationen bei uneindeutigen Kommentaren. + +Damit waeren die Ebenen Signal, Foerdertechnik-Einheit, Bereichsgruppe, Steuerung und — als Zusatznutzen — die raeumliche Lage vollstaendig aus den Eingabelisten ableitbar. Manuell zu pflegen blieben dann nur noch die eigentliche Verkettungsrichtung der Topologie (`connections`/`destinations`), Timings und projektspezifische Sonderlogik (`customCode`). diff --git a/doc/HundM/Json_Layout-Konzept.md b/doc/HundM/Json_Layout-Konzept.md new file mode 100644 index 0000000..53beb0f --- /dev/null +++ b/doc/HundM/Json_Layout-Konzept.md @@ -0,0 +1,1240 @@ +# JSON Layout-Konfiguration fuer HundM_Fortna SCL-Code-Generierung + +## Kontext + +Die 5 SPS-Konfigurationen (UH01-UH05) enthalten tausende Zeilen repetitiven SCL-Code in `FB_Main`, `FB_CallSensors`, `FC_Direction` und `FC_Call_Jams`. Dieser Code folgt festen Mustern pro Element-Typ und unterscheidet sich nur in den konkreten Parametern (Adressen, Sensor-IDs, TRO-Nummern, Timing-Werte). Eine JSON-Konfigurationsdatei koennte als **Single Source of Truth** dienen, aus der der gesamte topologie-spezifische SCL-Code generiert wird. + +## Identifizierte Element-Typen (aus FB_Main UH01) + +| Typ | FB-Typ | Anzahl UH01 | Kennzeichen | +|---|---|---|---| +| Conveyor/Carousel | `FB_Conveyor` | 13 | Motor, Grid-Sensor, Schaltschrank | +| TRO 1Sep | `FB_ILS_MTRO_1Sep` | ~15 | 1 Separator, Entry/Exit Jam | +| TRO 1Sep + Scanner | `FB_ILS_MTRO_1Sep` | 5 | + Cognex Barcode-Reader | +| TRO 1Sep1Swi | `FB_ILS_MTRO_1Sep1Swi` | 4 | + Switch mit Direction-Logik | +| TRO 1Sep SSCC | `FB_ILS_MTRO_1Sep_SSCC` | 2 | + SSCC-Scanner + DReqM Telegramm | +| TRO Vario | `FB_ILS_MTRO_Vario` | 9 | Ketten-/Variofuerderer | +| EmptyCarrBuffer | `FB_EmptyCarrBuffer` | 2 | Mehrzeiliger Puffer + Weichen | +| LoadingBoom | `FB_LoadingBoom_INBOUND` | 2 | Komplex: Boom, Fuss, Stopper, Tilt, Distance | +| Sensor | `FB_SensorInput` | ~200 | Pro physischem Sensor | + +--- + +## Vorschlag fuer eine standardisierte TRO-Liste + +### Uebersicht aller TROs nach Steuerung + +Insgesamt wurden **237 TROs** ueber alle 5 Steuerungen identifiziert. Die TRO-IDs folgen dem Schema `TRO` (z.B. TRO100-TRO134 fuer UH01). + +| Steuerung | TRO-Bereich | Anzahl TROs | Schwerpunkt | +|---|---|---|---| +| UH01 | TRO100-TRO134 | 21 | Inbound, Loading Booms, SSCC-Scanner, Empty Carrier Buffer | +| UH02 | TRO200-TRO275 | 76 | 3x PinStore-Bloecke (automatisiertes Lager) | +| UH03 | TRO301-TRO386 | 84 | 3x PinStore-Bloecke (2.1, 2.2, 2.3) + F2H | +| UH04 | TRO402-TRO424 | 24 | 3x Work Stations (manuelle Arbeitsplaetze) | +| UH05 | TRO500-TRO531 | 32 | Laengenmessung + Verteilsystem | + +### FB-Typ-Verteilung ueber alle Steuerungen + +| FB-Typ | Beschreibung | UH01 | UH02 | UH03 | UH04 | UH05 | Gesamt | +|---|---|---|---|---|---|---|---| +| `FB_ILS_MTRO_1Sep` | Standard-Separator | ~15 | ~20 | ~25 | ~8 | ~10 | ~78 | +| `FB_ILS_MTRO_Vario` | Kettenfoerderer (variabel) | 9 | ~15 | ~18 | 4 | ~12 | ~58 | +| `FB_ILS_MTRO_1Sep1Swi` | Separator + 1 Weiche | 4 | ~8 | ~12 | 3 | 5 | ~32 | +| `FB_ILS_MTRO_1Sep2Swi` | Separator + 2 Weichen | 0 | ~5 | ~6 | 0 | 0 | ~11 | +| `FB_ILS_MTRO_PinStore_Auto` | Automatisches Pin-Lager | 0 | ~20 | ~18 | 0 | 0 | ~38 | +| `FB_ILS_MTRO_1Sep_SSCC` | SSCC-Barcode-Scanner | 2 | 0 | 0 | 0 | 0 | 2 | +| `FB_ILS_MTRO_Vario_workStation` | Manueller Arbeitsplatz | 0 | 0 | 0 | 3 | 0 | 3 | +| `FB_EmptyCarrBuffer` | Leertablar-Puffer | 2 | 0 | 0 | 0 | 0 | 2 | + +### Detaillierte TRO-Liste UH01 + +| TRO | FB-Typ | Scanner | Switch | Prio | Besonderheit | +|---|---|---|---|---|---| +| TRO100 | 1Sep | - | - | releaseOk | Eingang Kreisel | +| TRO101_IN | 1Sep | - | - | releaseOk | Eingang Empty Buffer rechts | +| TRO101 | EmptyCarrBuffer | - | - | Manager | 5-Zeilen Leertablar-Puffer rechts | +| TRO102_IN | 1Sep | - | - | releaseOk | Eingang Empty Buffer links | +| TRO102 | EmptyCarrBuffer | - | - | Manager | 5-Zeilen Leertablar-Puffer links | +| TRO103 | 1Sep | - | - | releaseOk | Zufahrt Loading Boom 1 | +| TRO104 | 1Sep | BX1103 | - | releaseOk | Stopper vor Boom 1 + Barcode | +| TRO105 | 1Sep_SSCC | BX1104 + BX1107 | - | releaseOk | SSCC-Scanner Boom 1 + WCS DReqM | +| TRO106 | 1Sep | - | - | Manager | Abfahrt Boom 1 | +| TRO107 | 1Sep1Swi | - | cSwi107.1 | Dir2 Manager | Weiche Boom 1 (LS / Clearing) | +| TRO108 | 1Sep | - | - | releaseOk | Zufahrt Loading Boom 2 | +| TRO109 | 1Sep | BX1105 | - | releaseOk | Stopper vor Boom 2 + Barcode | +| TRO110 | 1Sep_SSCC | BX1106 + BX1108 | - | releaseOk | SSCC-Scanner Boom 2 + WCS DReqM | +| TRO111 | 1Sep | - | - | Manager | Abfahrt Boom 2 | +| TRO112 | 1Sep1Swi | - | cSwi112.1 | Dir2 Manager | Weiche Boom 2 (LS / Clearing) | +| TRO113 | 1Sep | BX1101 | - | releaseOk | RFID + Barcode vor Ausfahrt | +| TRO114 | 1Sep1Swi | - | cSwi114.1 | - | Weiche Inbound Out / Clearing | +| TRO115 | Vario | - | - | releaseOk | Loaded to Storage (Kette) | +| TRO116 | 1Sep | - | - | releaseOk | Separator vor Clearing | +| TRO117 | 1Sep | BX1100 | - | Manager | Clearing Station + Barcode | +| TRO120 | Vario | - | - | releaseOk | Highway Vario | +| TRO121 | Vario | - | - | releaseOk | Highway Vario | +| TRO122 | 1Sep | - | - | releaseOk | Highway Separator | +| TRO123 | Vario | - | - | releaseOk | Highway Vario | +| TRO124 | 1Sep1Swi | - | cSwi124.1 | Manager | Weiche Highway (Storage / Inbound) | +| TRO125 | 1Sep | - | - | Manager | Highway Separator | +| TRO126 | Vario | - | - | releaseOk | Empty to Storage (Kette) | +| TRO127 | Vario | - | - | releaseOk | Empty to Inbound (Kette) | +| TRO128 | Vario | - | - | releaseOk | Loaded to AMR (Kette) | +| TRO129 | 1Sep | - | - | Manager | Highway Separator | +| TRO130 | 1Sep | - | - | Manager | Highway Separator | +| TRO131 | Vario | - | - | releaseOk | Highway Vario | +| TRO132 | 1Sep | - | - | releaseOk | Highway Separator | +| TRO133 | Vario | - | - | releaseOk | Highway Vario | +| TRO134 | Vario | - | - | releaseOk | Highway Vario | + +### Spezial-Elemente je Steuerung + +| Feature | UH01 | UH02 | UH03 | UH04 | UH05 | +|---|---|---|---|---|---| +| SSCC-Scanner | TRO105, TRO110 | - | - | - | - | +| Cognex Barcode | BX1100-BX1108 | - | - | BX4103 | BX5101 | +| PinStore (autom. Lager) | - | 3 Bloecke | 3 Bloecke (2.1-2.3) | - | - | +| Work Station (manuell) | - | - | - | TRO421-423 | - | +| Laengenmessung | - | - | - | - | TRO500 | +| Empty Carrier Buffer | TRO101, TRO102 | - | - | - | - | +| Loading Boom | Boom1, Boom2 | - | - | - | - | +| Borner (Einschleusung) | TRO101, TRO102 | TRO200, 240, 270, 272 | - | - | TRO500, 502 | +| F2H (Floor-to-Hub) | - | - | TRO308, 383, 386 | - | - | + +### Namenskonvention fuer standardisierte JSON-Konfiguration + +Um eine einheitliche JSON pro Steuerung zu erzeugen, wird folgendes Schema empfohlen: + +``` +TRO-ID: TRO z.B. TRO115, TRO207, TRO315 +Separator-Nr: cSep.1 z.B. cSep115.1 +Switch-Nr: cSwi.1 z.B. cSwi107.1 +MainTroNo: cMainTro z.B. cMainTro115 +JamArea-DB: DB_JamArea<4-stellig> z.B. DB_JamArea0107 +Scanner-ID: cScannerBX<4-stellig> z.B. cScannerBX1104 +HMI-Pfad: DB_Interface_HMI.stTRO.TRO +``` + +--- + +## Vorgeschlagene JSON-Struktur + +### 1. Projekt-Header & SPS-Konfiguration + +```json +{ + "$schema": "hmf-layout-v1.schema.json", + "version": "1.0", + "project": "HundM_Fortna", + + "plc": { + "id": "UH01", + "configName": "=A01+UH01-KF00", + "plcId": "cPLCID", + "connectionIdWCSBL": 10 + }, + + "controlUnits": [ + { + "id": "OF1", + "safetySignal": "DB_InterfaceSafety.stFromSafety.EStopMainOF1.Q", + "mainContactors": [ + "DB_InterfaceSafety.stFromSafety.stMainContactorsUH01.Q", + "DB_InterfaceSafety.stFromSafety.stMainContactorsUC0110.Q", + "DB_InterfaceSafety.stFromSafety.stMainContactorsUC0111.Q" + ], + "machineState": "DB_MachineGlobal.stStateMainOF1" + }, + { + "id": "OF2", + "safetySignal": "DB_InterfaceSafety.stFromSafety.EStopMainOF2.Q", + "mainContactors": [ + "DB_InterfaceSafety.stFromSafety.stMainContactorsUC011.Q" + ], + "machineState": "DB_MachineGlobal.stStateMainOF2" + } + ] +} +``` + +### 2. Sensoren (erzeugt `FB_CallSensors`) + +```json +"sensors": [ + { + "id": "BG0280", + "constant": "cInBG0280", + "hwInput": "BG0280", + "controlUnit": "OF1", + "comment": "TRO104 Sep Sensor" + }, + { + "id": "BG0282", + "constant": "cInBG0282", + "hwInput": "BG0282", + "controlUnit": "OF1", + "comment": "LoadingBoom1 Stopper1" + } +] +``` + +### 3. Conveyors / Carousels (erzeugt REGION Conveyor in `FB_Main`) + +#### Standard-Conveyor (Carousel mit Grid-Sensor) + +```json +"conveyors": [ + { + "id": "Carousel0101", + "instanceName": "fbCarousel0101", + "comment": "Eingangskreisel", + "controlUnit": "OF1", + "settings": { + "energySafeTime": "cTimeEnergySafe", + "gridActive": true, + "motorProtectName": "FC0060", + "gridSenName": "BG3347" + }, + "io": { + "enabled": "cTodoTRUE", + "gridSensor": "cInBG3347", + "gridQuit": ["SF0031", "SF0002"], + "motorProtection": "FC0060", + "powerContactor": "MA0060", + "hmiPath": "DB_Interface_HMI.stConveyors.stCarousel.stCar0101" + }, + "requestRunSources": [ + { "type": "startupCounter", "value": 100 }, + { "type": "restart" }, + { "type": "troCarouselReq", "tro": "TRO100" }, + { "type": "troCarouselReq", "tro": "TRO101_IN" }, + { "type": "troCarouselReq", "tro": "TRO102_IN" } + ] + } +] +``` + +#### Buersten-Conveyor (Subtype brush) + +```json +{ + "id": "Conveyor4103_B", + "instanceName": "fbConveyor4103_B", + "comment": "Buersten Highway Loaded to Storage", + "controlUnit": "OF2", + "subtype": "brush", + "settings": { + "energySafeTime": "T#90s", + "gridActive": false, + "motorProtectName": "FC0152" + }, + "io": { + "motorProtection": "FC0152", + "powerContactor": "MA0152", + "hmiPath": "DB_Interface_HMI.stConveyors.stCarousel.stCar4103_B" + }, + "brushConfig": { + "triggerSensor": "cInBG3140", + "jamSensor": "cInBG3143", + "fullSensor": "cInBG3142", + "taktTime": "T#1s" + } +} +``` + +### 4. TROs (Transfer Route Objects) + +#### TRO 1Sep — Standard-Separator + +```json +"tros": [ + { + "id": "TRO100", + "type": "1Sep", + "fbType": "FB_ILS_MTRO_1Sep", + "mainTroNo": "cMainTro100", + "controlUnit": "OF1", + "comment": "Eingang Kreisel", + "separator": { + "no": "cSep100.1", + "delayToNextItem": "TimeForSepWaiting_Short", + "trailingTime": "T#600ms", + "handlingTime": "T#200ms", + "jamTime": "TimeForSepJam", + "senFree": "T#1500ms", + "senWait": "T#4000ms", + "plugged": { + "jam": true, + "part": false, + "scanner": false + }, + "sensorInSep": "cInBG3242" + }, + "sensorJam2": "cInBG3243", + "priority": { "releaseOk": true }, + "call": { + "carouselRun": "fbCarousel0101.xOutConveyorFullSpeed", + "release": "DB_TRO_TEST.TRO100" + }, + "jamAreas": { + "entry": "DB_JamArea0100.stJam0100_1", + "exit": "DB_JamArea0101.stJam0101_1" + }, + "outputs": { + "stopper1": "MB3242" + }, + "hmi": "DB_Interface_HMI.stTRO.TRO100" + } +] +``` + +#### TRO 1Sep1Swi — Separator + Switch mit Direction-Logik + +```json +{ + "id": "TRO107", + "type": "1Sep1Swi", + "fbType": "FB_ILS_MTRO_1Sep1Swi", + "mainTroNo": "cMainTro107", + "controlUnit": "OF1", + "comment": "Switch Boom 1", + "separator": { + "no": "cSep107.1", + "delayToNextItem": "TimeForSepWaiting_Short", + "trailingTime": "T#100ms", + "handlingTime": "T#50ms", + "jamTime": "TimeForSepJam", + "plugged": { "jam": true, "part": false, "scanner": false }, + "sensorInSep": "cInBG3306" + }, + "sensorJam2": "cInBG3305", + "sensorJam3": "cInBG3330", + "switch": { + "no": "cSwi107.1", + "pluggedExSen3": false, + "pluggedExSen4": false, + "nTo1Destinations": 3 + }, + "settings": { + "prioDir2": true + }, + "priority": { + "managerDir2In": "DB_Prozessdaten.stPriorityManager.udt_TRO107.TroIn", + "managerDir2Out": "DB_Prozessdaten.stPriorityManager.udt_TRO107.TroOut" + }, + "call": { + "carouselRun1": "fbCarousel0102.xOutConveyorFullSpeed", + "release": "true" + }, + "jamAreas": { + "entry": "DB_JamArea0102.stJam0102_1", + "exit2": "DB_JamArea0103.stJam0103_1", + "exit3": "DB_JamArea0102.stJam0102_2" + }, + "outputs": { + "stopper1": "MB3306", + "sw1ExTo3": "MB3304" + }, + "hmi": "DB_Interface_HMI.stTRO.TRO107", + "direction": { + "switchNo": "cSwi107.1", + "carrierSource": "DB_JamArea0102.stJam0102_1.arCarrier[1]" + } +} +``` + +#### TRO Vario — Kettenfoerderer + +```json +{ + "id": "TRO115", + "type": "Vario", + "fbType": "FB_ILS_MTRO_Vario", + "mainTroNo": "cMainTro115", + "controlUnit": "OF1", + "comment": "Loaded To Storage Vario", + "separator": { + "no": "cSep115.1", + "delayToNextItem": "TimeForSepWaiting_Short", + "trailingTime": "T#800ms", + "handlingTime": "T#300ms", + "jamTime": "TimeForSepJam", + "senFree": "T#2000ms", + "senWait": "T#5000ms", + "plugged": { "jam": false, "part": false, "scanner": false }, + "sensorInSep": "cInBG3025" + }, + "vario": { + "continousEmptying": false, + "waitForJog": "T#300ms", + "convEmpty": "T#45000ms", + "countCarrier": 1, + "waitForStop": "T#3s", + "carrierInPosDelay": "T#1200ms", + "carrierInPosEdgeDelay": "T#100ms", + "rasterHigh": "T#5s", + "rasterLow": "T#5s", + "jamSenDelayActive": true, + "jamSenDelay": "T#2s", + "sensors": { + "carrInPos": "cInBG3026", + "finger": "cInBG3027", + "lastPos": "cInBG3000", + "jam": "cInBG3001" + } + }, + "settings": { "isBorner": true }, + "priority": { "releaseOk": true }, + "call": { + "motorProtection": "FC0145", + "automatic": "#t_Automatik_OF1 AND SF0120", + "errorQuit": "SF0002", + "release": "DB_TRO_TEST.TRO115" + }, + "jamAreas": { + "entry": "DB_JamArea4104.stJam4104_1", + "finger": "DB_JamArea4103.stJam4103_1" + }, + "outputs": { + "stopper": "MB3025", + "varioMotor": "MA0145" + }, + "hmi": "DB_Interface_HMI.stTRO.TRO115" +} +``` + +#### TRO 1Sep_SSCC — SSCC-Scanner + WCS-Telegramm + +```json +{ + "id": "TRO105", + "type": "1Sep_SSCC", + "fbType": "FB_ILS_MTRO_1Sep_SSCC", + "mainTroNo": "cMainTro105", + "controlUnit": "OF1", + "comment": "SSCC Scanner Boom 1", + "separator": { + "no": "cSep105.1", + "delayToNextItem": "TimeForSepWaiting_Short", + "trailingTime": "T#600ms", + "handlingTime": "T#200ms", + "jamTime": "TimeForSepJam", + "senFree": "T#1500ms", + "senWait": "T#4000ms", + "plugged": { "jam": true, "part": false, "scanner": true }, + "sensorInSep": "cInBG3280" + }, + "sensorJam2": "cInBG3281", + "scanner": { + "id": "cScannerBX1104", + "prefix": "bx1104", + "hwResults": "BX1104~Ergebnisse_-_64_Bytes_1", + "checkASCII": true, + "timeout": "T#3000ms" + }, + "ssccScanner": { + "prefix": "bx1107", + "hwResults": "BX1107~Ergebnisse_-_64_Bytes_1", + "checkASCII": true, + "timeout": "T#3s", + "sensorEndMeasurement": "cInBG3281" + }, + "priority": { "releaseOk": true }, + "call": { + "carouselRun": "true", + "release": "FB_CommunicationWCSBL_DB.fbTeleHandler.xOutConnectionActive OR IBN.xFahrenOhneTcpPartner" + }, + "jamAreas": { + "entry": "DB_JamArea0104.stJam0104_3", + "exit": "DB_JamArea0106.stJam0106_2" + }, + "outputs": { "stopper1": "MB3280" }, + "hmi": "DB_Interface_HMI.stTRO.TRO105", + "correction": { + "station": 0, + "carrierExpect": "DB_JamArea0104.stJam0104_3.arCarrier[1]" + }, + "wcsTelegram": { + "type": "DReqM", + "decisionPoint": "cDP_DOCK_01", + "dockDoor": "1", + "ssccReq": true, + "lengthReq": false, + "dockDoorReq": true + } +} +``` + +### 5. Loading Booms + +```json +"loadingBooms": [ + { + "id": "LoadingBoom1", + "instanceName": "fbLoadingBoom1", + "controlUnit": "OF1", + "comment": "Ladeschleife 1", + "relatedTro": "TRO104", + "controls": { + "btnReleaseMT1": "SF0305", + "switchLoadingPos2": "SF0306", + "btnBack": null, + "btnForth": null, + "btnReleaseMT2": "SF0332", + "switchFootUp": null, + "switchFootDown": null, + "switchLightOnOff": "SF0041", + "btnBoomActive": "SF0044", + "btnReset": ["SF0043", "SF0002", "IBN.xQuit"], + "switchFootManual": "SF0025" + }, + "boom": { + "motorProtection": ["FC0070", "FC0072"], + "limitForth": "cInBG3343", + "limitForthEmergency": "SF0051", + "limitBack": "cInBG3344", + "limitBackEmergency": "SF0050", + "bumperOk": true + }, + "foot": { + "motorProtection": "FC0321", + "limitUp": "SF0322", + "limitDown": "SF0323" + }, + "timings": { + "boomInput": "T#5s", + "wheelInput": "T#5s", + "senWaitStopper1": "T#100ms", + "waitAfterReleaseStopper1": "T#1200ms", + "waitBeforeSwitchStopper2": "T#4000ms", + "trailingStopper2": "T#150ms" + }, + "tilt": { + "analogInput": "wTiltSensorLS1", + "hmiBasePath": "DB_Interface_HMI.stLoadingBoom.stDataBoom1" + }, + "distance": { + "analogInput": "wDistanceSensorLS1", + "startSlow": 2510, + "startFast": 2520, + "hmiBasePath": "DB_Interface_HMI.stLoadingBoom.stDataBoom1" + }, + "callSensors": { + "sen2mThreshold": "cInBG0287", + "senJamEntr": "cInBG0286", + "senJamExit1": "cInBG0285", + "senJamExit2": "cInBG3276", + "senStopper1": "cInBG0282", + "senStopper2": "cInBG0283" + }, + "jamAreas": { + "stopper": "DB_JamArea0104.stJam0104_2", + "exit": "DB_JamArea0104.stJam0104_3" + }, + "outputs": { + "light": "QA0012", + "boomActive": "PF0044", + "ledMovement": "PF0287", + "stopper1Clamp": "MB0282", + "stopper1Finger": "MB0284", + "stopper2": "MB0283", + "boomForth1": "QA0071", + "boomForth2": "QA0073", + "boomBack1": "MA0070", + "boomBack2": "MA0072", + "footUp": "DQ0322", + "footDown": "DQ0323", + "footSpeed1": "DQ0324" + }, + "hmi": "DB_Interface_HMI.stLoadingBoom.stDataBoom1" + } +] +``` + +### 6. Empty Carrier Buffers (mehrzeiliger Puffer) + +```json +"emptyCarrBuffers": [ + { + "id": "TRO101", + "instanceName": "TRO101", + "mainTroNo": "cMainTro101", + "controlUnit": "OF1", + "comment": "Empty Buffer rechts", + "numberOfLines": 5, + "storageDb": "DB_JamBuffer101", + "inTro": { + "id": "TRO101_IN", + "separator": { + "no": 999, + "delayToNextItem": "TimeForSepWaiting_Short", + "trailingTime": "T#100ms", + "handlingTime": "T#50ms", + "jamTime": "TimeForSepJam", + "sensorInSep": "cInBG3246" + }, + "isBorner": true, + "bornerDest": "cDestInboundLS", + "carouselRun": "fbCarousel0101.xOutConveyorFullSpeed", + "jamEntry": "DB_JamArea0101.stJam0101_1", + "stopper": "MB3246", + "hmi": "DB_Interface_HMI.stTRO.TRO101_In" + }, + "separatorLines": [ + { "line": 1, "jamLength": 5, "sensor": "cInBG3320", "handlingTime": "T#200ms", "trailingTime": "T#500ms", "senFree": "T#1500ms", "senWait": "T#3000ms" }, + { "line": 2, "jamLength": 7, "sensor": "cInBG3321", "handlingTime": "T#200ms", "trailingTime": "T#500ms", "senFree": "T#1500ms", "senWait": "T#3000ms" }, + { "line": 3, "jamLength": 10, "sensor": "cInBG3322", "handlingTime": "T#200ms", "trailingTime": "T#500ms", "senFree": "T#1500ms", "senWait": "T#3000ms" }, + { "line": 4, "jamLength": 10, "sensor": "cInBG3323", "handlingTime": "T#200ms", "trailingTime": "T#500ms", "senFree": "T#1500ms", "senWait": "T#3000ms" }, + { "line": 5, "jamLength": 10, "sensor": "cInBG3324", "handlingTime": "T#200ms", "trailingTime": "T#500ms", "senFree": "T#1500ms", "senWait": "T#3000ms" } + ], + "jamSensors": ["cInBG3250", "cInBG3251", "cInBG3252", "cInBG3253", "cInBG3254"], + "switchLineOutputs": ["MB3250", "MB3251", "MB3252", "MB3253", "MB3254"], + "separatorStoreOutputs": ["MB3320", "MB3321", "MB3322", "MB3323", "MB3324"], + "exitJam": "DB_JamArea0102.stJam0102_2", + "exitSensor": "cInBG3330", + "priority": { + "managerIn": "DB_Prozessdaten.stPriorityManager.udt_TRO101.TroIn", + "managerOut": "DB_Prozessdaten.stPriorityManager.udt_TRO101.TroOut" + }, + "hmi": "DB_Interface_HMI.stTRO.TRO101" + } +] +``` + +### 7. Routing / FC_Direction (erzeugt CASE-Statement) + +```json +"routing": { + "switches": [ + { + "switchNo": "cSwi107.1", + "comment": "Switch 107.1 Boom 1", + "rules": [ + { "destination": "cDestInboundLS", "direction": 1, "comment": "LINKS - zu Ladeschleife" }, + { "destinations": ["cDestClearing", "cDestInboundOut", "cDestInboundLS_Extra"], "direction": 2, "comment": "RECHTS - Clearing/Inbound verlassen" } + ], + "default": 2 + }, + { + "switchNo": "cSwi112.1", + "comment": "Switch 112.1 Boom 2", + "rules": [ + { "destinations": ["cDestInboundLS", "cDestInboundLS_Extra"], "direction": 1, "comment": "LINKS - zu Ladeschleife" }, + { "destinations": ["cDestClearing", "cDestInboundOut"], "direction": 2, "comment": "RECHTS - Clearing/Inbound verlassen" } + ], + "default": 2 + }, + { + "switchNo": "cSwi114.1", + "comment": "Switch 114.1", + "rules": [ + { "destination": "cDestInboundOut", "direction": 1, "comment": "LINKS - Inbound verlassen" }, + { "destination": "cDestClearing", "direction": 2, "comment": "RECHTS - Clearing-Station" } + ], + "default": 0 + }, + { + "switchNo": "cSwi124.1", + "comment": "Switch 124.1", + "rules": [ + { "destination": "cDestHighwayStorage", "direction": 1, "comment": "LINKS - zum Storage" }, + { "destination": 0, "direction": 2, "comment": "RECHTS - zum Inbound (Standard)" } + ], + "default": 2 + } + ] +} +``` + +### 8. Jam Areas + +```json +"jamAreas": [ + { + "id": "JamArea0100", + "db": "DB_JamArea0100", + "slots": [ + { "name": "stJam0100_1", "capacity": 5 } + ] + }, + { + "id": "JamArea0101", + "db": "DB_JamArea0101", + "slots": [ + { "name": "stJam0101_1", "capacity": 5 }, + { "name": "stJam0101_2", "capacity": 5 } + ] + }, + { + "id": "JamArea0102", + "db": "DB_JamArea0102", + "slots": [ + { "name": "stJam0102_1", "capacity": 5 }, + { "name": "stJam0102_2", "capacity": 5 }, + { "name": "stJam0102_3", "capacity": 5 }, + { "name": "stJam0102_4", "capacity": 5 }, + { "name": "stJam0102_5", "capacity": 5 }, + { "name": "stJam0102_6", "capacity": 5 } + ] + } +] +``` + +### 9. Scanners (Cognex Barcode-Reader) + +```json +"scanners": [ + { + "id": "BX1100", + "constant": "cScannerBX1100", + "prefix": "bx1100", + "hwResults": "BX1100~Ergebnisse_-_64_Bytes_1", + "usedByTro": "TRO117" + }, + { + "id": "BX1101", + "constant": "cScannerBX1101", + "prefix": "bx1101", + "hwResults": "BX1101~Ergebnisse_-_64_Bytes_1", + "usedByTro": "TRO113" + }, + { + "id": "BX1103", + "constant": "cScannerBX1103", + "prefix": "bx1103", + "hwResults": "BX1103~Ergebnisse_-_64_Bytes_1", + "usedByTro": "TRO104" + }, + { + "id": "BX1104", + "constant": "cScannerBX1104", + "prefix": "bx1104", + "hwResults": "BX1104~Ergebnisse_-_64_Bytes_1", + "usedByTro": "TRO105" + }, + { + "id": "BX1105", + "constant": "cScannerBX1105", + "prefix": "bx1105", + "hwResults": "BX1105~Ergebnisse_-_64_Bytes_1", + "usedByTro": "TRO109" + }, + { + "id": "BX1106", + "constant": "cScannerBX1106", + "prefix": "bx1106", + "hwResults": "BX1106~Ergebnisse_-_64_Bytes_1", + "usedByTro": "TRO110" + }, + { + "id": "BX1107", + "constant": "cScannerBX1107", + "prefix": "bx1107", + "hwResults": "BX1107~Ergebnisse_-_64_Bytes_1", + "comment": "SSCC Scanner Boom 1", + "usedByTro": "TRO105" + }, + { + "id": "BX1108", + "constant": "cScannerBX1108", + "prefix": "bx1108", + "hwResults": "BX1108~Ergebnisse_-_64_Bytes_1", + "comment": "SSCC Scanner Boom 2", + "usedByTro": "TRO110" + } +] +``` + +### 10. Sonderlogik — Hybrid-Ansatz (customCode fuer seltene Einzelfaelle) + +Haeufige Muster werden als eigene JSON-Felder modelliert (scanner, ssccScanner, wcsTelegram, brushConfig, correction). Seltene Einzelfaelle werden als `customCode`-Bloecke eingebettet: + +```json +{ + "id": "TRO117", + "type": "1Sep", + "fbType": "FB_ILS_MTRO_1Sep", + "mainTroNo": "cMainTro117", + "controlUnit": "OF1", + "comment": "Clearing Station", + "separator": { + "no": "cSep117.1", + "delayToNextItem": "TimeForSepWaiting_Short", + "trailingTime": "T#100ms", + "handlingTime": "T#50ms", + "jamTime": "TimeForSepJam", + "plugged": { "jam": true, "part": true, "scanner": true }, + "sensorInSep": "cInBG3300" + }, + "sensorJam2": "cInBG3304", + "scanner": { + "id": "cScannerBX1100", + "prefix": "bx1100", + "hwResults": "BX1100~Ergebnisse_-_64_Bytes_1", + "checkASCII": true, + "timeout": "T#5s" + }, + "correction": { + "station": 0, + "carrierExpect": "DB_JamArea0102.stJam0102_6.arCarrier[1]" + }, + "customCode": { + "beforeCall": [ + "#rTrig_ClarificationButton(CLK := \"SF0032\");" + ], + "releaseExpression": "#rTrig_ClarificationButton.Q", + "afterCall": [ + "// Clearing-Station: Trolley loeschen", + "IF NOT \"DB_Inputs\".Sensors[\"cInBG3300\"].xDirectSensor AND \"DB_Interface_HMI\".stClearingStation.xDeleteTrolley THEN", + " \"DB_JamArea0102\".stJam0102_6.arCarrier[1] := #stEmptyCarrier;", + " \"DB_Interface_HMI\".stClearingStation.xDeleteTrolley := FALSE;", + " #TRO117.nState := 100;", + "END_IF;", + "", + "// Clearing-Station: Ladung loeschen", + "IF NOT \"BG3301\" AND \"DB_Interface_HMI\".stClearingStation.xDeleteLoad THEN", + " \"DB_JamArea0102\".stJam0102_6.arCarrier[1].bStatus.%X1 := FALSE;", + " \"DB_Interface_HMI\".stClearingStation.xDeleteLoad := FALSE;", + "END_IF;", + "", + "// HMI-Anzeige aktualisieren", + "\"DB_Interface_HMI\".stClearingStation.stFirstCarrierInStation := \"DB_JamArea0102\".stJam0102_6.arCarrier[1];", + "\"DB_Interface_HMI\".stClearingStation.xTrolleyInStation := \"DB_Inputs\".Sensors[\"cInBG3300\"].xDbncdSensor;" + ] + } +} +``` + +--- + +### 11. Connections — Physische Topologie (TRO-Verkettung) + +Jede Verbindung beschreibt den Pfad: Quell-TRO + Exit-Slot → JamArea → Ziel-TRO + Entry-Slot. +Switch-Ausgaenge haben nummerierte Exit-Slots (`exit2`, `exit3`); normale TROs haben nur `exit`. + +```json +"connections": [ + { "from": "TRO100", "exitSlot": "exit", "jamArea": "DB_JamArea0101.stJam0101_1", "to": "TRO101_IN", "entrySlot": "entry", "comment": "Eingang → Entry Buffer" }, + { "from": "TRO100", "exitSlot": "exit", "jamArea": "DB_JamArea0101.stJam0101_1", "to": "TRO101", "entrySlot": "entry", "comment": "Parallel: direkt in EmptyBuffer" }, + { "from": "TRO101", "exitSlot": "exit", "jamArea": "DB_JamArea0102.stJam0102_2", "to": "TRO107", "entrySlot": "entry", "comment": "EmptyBuffer → Switch Boom1" }, + { "from": "TRO102", "exitSlot": "exit", "jamArea": "DB_JamArea0102.stJam0102_1", "to": "TRO107", "entrySlot": "entry" }, + { "from": "TRO107", "exitSlot": "exit2", "jamArea": "DB_JamArea0103.stJam0103_1", "to": "TRO103", "entrySlot": "entry", "direction": 1, "comment": "Dir1=LS1" }, + { "from": "TRO107", "exitSlot": "exit3", "jamArea": "DB_JamArea0102.stJam0102_2", "to": "TRO112", "entrySlot": "entry", "direction": 2, "comment": "Dir2=weiter" }, + { "from": "TRO103", "exitSlot": "exit", "jamArea": "DB_JamArea0104.stJam0104_1", "to": "TRO104", "entrySlot": "entry" }, + { "from": "TRO104", "exitSlot": "exit", "jamArea": "DB_JamArea0104.stJam0104_2", "to": "LoadingBoom1", "entrySlot": "stopper" }, + { "from": "TRO106", "exitSlot": "exit", "jamArea": "DB_JamArea0102.stJam0102_2", "to": "TRO112", "entrySlot": "entry", "comment": "LS1 Rueckleitung" }, + { "from": "TRO112", "exitSlot": "exit2", "jamArea": "DB_JamArea0107.stJam0107_1", "to": "TRO108", "entrySlot": "entry", "direction": 1, "comment": "Dir1=LS2" }, + { "from": "TRO112", "exitSlot": "exit3", "jamArea": "DB_JamArea0102.stJam0102_3", "to": "TRO113", "entrySlot": "entry", "direction": 2, "comment": "Dir2=Clearing" }, + { "from": "TRO111", "exitSlot": "exit", "jamArea": "DB_JamArea0102.stJam0102_3", "to": "TRO113", "entrySlot": "entry", "comment": "LS2 Rueckleitung" }, + { "from": "TRO113", "exitSlot": "exit", "jamArea": "DB_JamArea0102.stJam0102_4", "to": "TRO114", "entrySlot": "entry" }, + { "from": "TRO114", "exitSlot": "exit2", "jamArea": "DB_JamArea4104.stJam4104_1", "to": null, "entrySlot": null, "direction": 1, "comment": "Dir1=InboundOut→WCS" }, + { "from": "TRO114", "exitSlot": "exit3", "jamArea": "DB_JamArea0102.stJam0102_5", "to": "TRO116", "entrySlot": "entry", "direction": 2, "comment": "Dir2=Clearing" } +] +``` + +**Mehrwert `connections`**: + +- Topologie-Validierung: Generator prueft ob jede in `tros[].jamAreas` genannte JamArea auch in `connections` erscheint +- Topologie-Diagramme: Aus `connections` wird automatisch ein Mermaid-Flowchart erzeugt +- Cross-Config-Vergleich: `connections` von UH01 vs UH04 direkt vergleichbar + +--- + +### 12. Destinations — Abstrakte Routing-Tabelle + +Beschreibt pro Carrier-Ziel: welche Switches wie geschaltet werden, den vollstaendigen TRO-Pfad und die Endaktion. +Ermoeglicht automatische Generierung von `FC_Direction` ohne manuelles Pflegen von `routing.switches`. + +```json +"destinations": [ + { + "id": "cDestInboundLS", + "constant": 100, + "description": "Carrier in Ladeschleife beladen (Loading Station 1 oder 2)", + "routes": [ + { + "id": "route_LS1", + "description": "Weg zur Loading Station 1 (Boom 1)", + "switchDecisions": [ + { "tro": "TRO107", "switch": "cSwi107.1", "direction": 1 }, + { "tro": "TRO112", "switch": "cSwi112.1", "direction": 2 } + ], + "path": ["TRO107", "TRO103", "TRO104", "LoadingBoom1", "TRO105", "TRO106"], + "terminal": { "type": "loadingBoom", "element": "LoadingBoom1" } + }, + { + "id": "route_LS2", + "description": "Weg zur Loading Station 2 (Boom 2)", + "switchDecisions": [ + { "tro": "TRO107", "switch": "cSwi107.1", "direction": 2 }, + { "tro": "TRO112", "switch": "cSwi112.1", "direction": 1 } + ], + "path": ["TRO107", "TRO112", "TRO108", "TRO109", "LoadingBoom2", "TRO110", "TRO111"], + "terminal": { "type": "loadingBoom", "element": "LoadingBoom2" } + } + ], + "wcsTelegram": { "type": "DReqM", "decisionPoints": ["cDP_DOCK_01", "cDP_DOCK_02"] } + }, + { + "id": "cDestClearing", + "constant": 200, + "description": "Carrier zur Clearing-/Error-Station", + "routes": [ + { + "id": "route_clearing", + "switchDecisions": [ + { "tro": "TRO107", "switch": "cSwi107.1", "direction": 2 }, + { "tro": "TRO112", "switch": "cSwi112.1", "direction": 2 }, + { "tro": "TRO114", "switch": "cSwi114.1", "direction": 2 } + ], + "path": ["TRO107", "TRO112", "TRO113", "TRO114", "TRO116", "TRO117"], + "terminal": { "type": "clearingStation", "element": "TRO117" } + } + ] + }, + { + "id": "cDestInboundOut", + "constant": 300, + "description": "Carrier verlaesst das Inbound-System", + "routes": [ + { + "id": "route_exit", + "switchDecisions": [ + { "tro": "TRO114", "switch": "cSwi114.1", "direction": 1 } + ], + "path": ["TRO113", "TRO114"], + "terminal": { "type": "wcsTelegram", "action": "cSTRAIGHT", "decisionPoint": "cDP_INBOUND_OUT" } + } + ] + }, + { + "id": "cDestHighwayStorage", + "constant": 400, + "description": "Carrier faehrt zum Storage ueber Highway", + "routes": [ + { + "id": "route_storage", + "switchDecisions": [ + { "tro": "TRO124", "switch": "cSwi124.1", "direction": 1 } + ], + "path": ["TRO113", "TRO114", "TRO120", "TRO121", "TRO122", "TRO123", "TRO124"], + "terminal": { "type": "wcsTelegram", "action": "cSTORAGE", "decisionPoint": "cDP_HIGHWAY" } + } + ] + } +] +``` + +**Auswirkung auf bestehende Abschnitte**: + +| Abschnitt | Auswirkung | +|---|---| +| `routing.switches[].rules` | Kann aus `destinations[].routes[].switchDecisions` abgeleitet werden (Single Source of Truth) | +| `tros[].jamAreas` | Bleibt explizit fuer Debugging; Generator validiert Konsistenz gegen `connections[]` | +| `FC_Direction` (generiert) | Wird kuenftig aus `destinations` statt aus `routing.switches` generiert | + +**Mehrwert `destinations`**: + +- `FC_Direction` auto-generieren: Switch-Regeln kommen direkt aus `switchDecisions` +- Dokumentation: vollstaendiger Carrier-Pfad pro Ziel als Planungsgrundlage +- Simulation: Carrier-Fluss kann ohne SPS per Graph-Traversal simuliert werden + +--- + +### 13. Topologie-Graph UH01 — TRO-Ein- und Ausgänge + +Jede Verbindung wird über eine JamArea realisiert. Abkürzung `JAxxxx_y` steht für `"DB_JamAreaxxxx".stJamxxxx_y`. +Switch-TROs (Typ `1Sep1Swi`) besitzen zwei Ausgänge (Dir1 / Dir2); ihre Richtungsentscheidung kommt aus `FC_Direction`. + +#### Inbound-Hauptschleife (Mermaid-Diagramm) + +```mermaid +flowchart LR + classDef sep fill:#d4e8ff,stroke:#3388cc + classDef swi fill:#ffe4a0,stroke:#cc8800 + classDef buf fill:#d4f0d4,stroke:#338833 + classDef vario fill:#e8d4f0,stroke:#883388 + classDef sscc fill:#ffd4d4,stroke:#cc3333 + classDef ext fill:#f0f0f0,stroke:#888,stroke-dasharray:5 + + EXT_IN([Externer Eingang]):::ext + EXT_OUT([InboundOut to WCS]):::ext + + EXT_IN -->|JA0100_1| TRO100:::sep + TRO100 -->|JA0101_1| TRO101_IN:::sep + TRO101_IN -->|JamBuf101| TRO101[TRO101 EmptyBuf]:::buf + TRO101_IN -->|JA0101_2| TRO102_IN:::sep + TRO102_IN -->|JamBuf102| TRO102[TRO102 EmptyBuf]:::buf + TRO101 -->|JA0102_2| TRO112:::swi + TRO102 -->|JA0102_1| TRO107:::swi + + TRO107 -->|Dir1 JA0103_1| TRO103:::sep + TRO107 -->|Dir2 JA0102_2| TRO112 + TRO103 -->|JA0104_1| TRO104:::sep + TRO104 -->|JA0104_2| LB1([LoadingBoom 1]):::ext + LB1 -->|JA0104_3| TRO105:::sscc + TRO105 -->|JA0106_2| TRO106:::sep + TRO106 -->|JA0102_2| TRO112 + + TRO112 -->|Dir1 JA0107_1| TRO108:::sep + TRO112 -->|Dir2 JA0102_3| TRO113:::sep + TRO108 -->|JA0108_1| TRO109:::sep + TRO109 -->|JA0108_2| LB2([LoadingBoom 2]):::ext + LB2 -->|JA0108_3| TRO110:::sscc + TRO110 -->|JA0110_2| TRO111:::sep + TRO111 -->|JA0102_3| TRO113 + + TRO113 -->|JA0102_4| TRO114:::swi + TRO114 -->|Dir1 JA4104_1| TRO115:::vario + TRO115 --> EXT_OUT + TRO114 -->|Dir2 JA0102_5| TRO116:::sep + TRO116 -->|JA0102_6| TRO117:::sep + TRO117 -.->|JA0102_1 Clearing-Rückf.| TRO107 +``` + +#### Highway / Storage-Verbindungen (Mermaid-Diagramm) + +```mermaid +flowchart LR + classDef sep fill:#d4e8ff,stroke:#3388cc + classDef swi fill:#ffe4a0,stroke:#cc8800 + classDef vario fill:#e8d4f0,stroke:#883388 + classDef ext fill:#f0f0f0,stroke:#888,stroke-dasharray:5 + + HWY_IN([Highway Loaded In]):::ext -->|JA4103_1| TRO120:::vario + ST_IN1([Storage Empty In]):::ext -->|JA4503_1| TRO121:::vario + ST_IN1 -->|JA4503_2| TRO122:::sep + TRO122 -->|JA4502_1| TRO123:::vario + BORNER1([Borner Eingang 1]):::ext -->|JA4502_2| TRO124:::swi + TRO124 -->|Dir1 JA4204_2| TRO125:::sep + TRO125 -->|JA4203_1| TRO126:::vario + TRO126 --> STORAGE([Storage]):::ext + TRO124 -->|Dir2 JA4501_1| TRO127:::vario + EMPTY_IN([Leere Carrier von Highway]):::ext -->|JA4501_2| TRO128:::vario + BORNER2([Borner Eingang 2]):::ext -->|JA4302_2| TRO129:::sep + TRO129 -->|JA4204_1| TRO130:::sep + TRO130 -->|JA4501_1| TRO127 + AMR_IN([Loaded to AMR]):::ext -->|JA4403_1| TRO131:::vario + TRO131 --> AMR([AMR-System]):::ext + HWY_IN2([Highway Eingang 2]):::ext -->|JA4302_1| TRO133:::vario + AMR_HWY([AMR Highway]):::ext -->|JA4402_1| TRO134:::vario +``` + +#### TRO-Tabelle: Zone A — Eingang / Leere-Carrier-Puffer + +| TRO | Typ | Beschreibung | Eingang JamArea | Eingang von | Ausgang JamArea | Ausgang zu | +|---|---|---|---|---|---|---| +| TRO100 | 1Sep | Anlageneingang | JA0100.stJam0100_1 | Externer Eingang | JA0101.stJam0101_1 | TRO101_IN | +| TRO101_IN | 1Sep | Separator Empty Buffer rechts | JA0101.stJam0101_1 | TRO100 | DB_JamBuffer101 / JA0101.stJam0101_2 | TRO101 / TRO102_IN | +| TRO101 | EmptyCarrBuffer | Leere-Carrier-Puffer rechts | DB_JamBuffer101 | TRO101_IN | JA0102.stJam0102_2 | TRO112 | +| TRO102_IN | 1Sep | Separator Empty Buffer links | JA0101.stJam0101_2 | TRO101_IN | DB_JamBuffer102 | TRO102 | +| TRO102 | EmptyCarrBuffer | Leere-Carrier-Puffer links | DB_JamBuffer102 | TRO102_IN | JA0102.stJam0102_1 | TRO107 | + +#### TRO-Tabelle: Zone B — Loading Station 1 + +| TRO | Typ | Beschreibung | Eingang JamArea | Eingang von | Ausgang JamArea | Ausgang zu | +|---|---|---|---|---|---|---| +| TRO103 | 1Sep | Zufahrt Loading Station 1 | JA0103.stJam0103_1 | TRO107 (Dir1) | JA0104.stJam0104_1 | TRO104 | +| TRO104 | 1Sep | Vorstopper LS1 + Barcode-Scanner | JA0104.stJam0104_1 | TRO103 | JA0104.stJam0104_2 | LoadingBoom1 (Stopper) | +| TRO105 | 1Sep_SSCC | SSCC-Scanner nach LS1 | JA0104.stJam0104_3 | LoadingBoom1 (nach Beladung) | JA0106.stJam0106_2 | TRO106 | +| TRO106 | 1Sep | Abfuhr Loading Station 1 | JA0106.stJam0106_2 | TRO105 | JA0102.stJam0102_2 | TRO112 | + +#### TRO-Tabelle: Zone C — Loading Station 2 + +| TRO | Typ | Beschreibung | Eingang JamArea | Eingang von | Ausgang JamArea | Ausgang zu | +|---|---|---|---|---|---|---| +| TRO108 | 1Sep | Zufahrt Loading Station 2 | JA0107.stJam0107_1 | TRO112 (Dir1) | JA0108.stJam0108_1 | TRO109 | +| TRO109 | 1Sep | Vorstopper LS2 + Barcode-Scanner | JA0108.stJam0108_1 | TRO108 | JA0108.stJam0108_2 | LoadingBoom2 (Stopper) | +| TRO110 | 1Sep_SSCC | SSCC-Scanner nach LS2 | JA0108.stJam0108_3 | LoadingBoom2 (nach Beladung) | JA0110.stJam0110_2 | TRO111 | +| TRO111 | 1Sep | Abfuhr Loading Station 2 | JA0110.stJam0110_2 | TRO110 | JA0102.stJam0102_3 | TRO113 | + +#### TRO-Tabelle: Zone D — Switches / Hauptrouting + +| TRO | Typ | Beschreibung | Eingang JamArea | Eingang von | Ausgang Dir1 | Ausgang Dir2 | +|---|---|---|---|---|---|---| +| TRO107 | 1Sep1Swi | Switch: LS1 / LS2+Clearing | JA0102.stJam0102_1 | TRO102, TRO117 (Rückf.) | JA0103.stJam0103_1 → TRO103 | JA0102.stJam0102_2 → TRO112 | +| TRO112 | 1Sep1Swi | Switch: LS2 / Clearing+Ausgang | JA0102.stJam0102_2 | TRO101, TRO106, TRO107(D2) | JA0107.stJam0107_1 → TRO108 | JA0102.stJam0102_3 → TRO113 | +| TRO113 | 1Sep | Zufahrt Clearing + Barcode-Scanner | JA0102.stJam0102_3 | TRO111, TRO112 (Dir2) | JA0102.stJam0102_4 → TRO114 | — | +| TRO114 | 1Sep1Swi | Switch: InboundOut / Clearing + Scanner | JA0102.stJam0102_4 | TRO113 | JA4104.stJam4104_1 → TRO115 | JA0102.stJam0102_5 → TRO116 | + +#### TRO-Tabelle: Zone E — Clearing-Station + +| TRO | Typ | Beschreibung | Eingang JamArea | Eingang von | Ausgang JamArea | Ausgang zu | +|---|---|---|---|---|---|---| +| TRO116 | 1Sep | Zufahrt Clearing-Station | JA0102.stJam0102_5 | TRO114 (Dir2) | JA0102.stJam0102_6 | TRO117 | +| TRO117 | 1Sep | Clearing-Station (HMI + customCode) | JA0102.stJam0102_6 | TRO116 | JA0102.stJam0102_1 | TRO107 (Clearing-Rückführung) | + +#### TRO-Tabelle: Zone F — InboundOut + +| TRO | Typ | Beschreibung | Eingang JamArea | Eingang von | Ausgang | Ausgang zu | +|---|---|---|---|---|---|---| +| TRO115 | Vario | Übergabe InboundOut | JA4104.stJam4104_1 | TRO114 (Dir1) | WCS-Telegramm | Externes System (WCS/UH04) | + +#### TRO-Tabelle: Zone G — Highway / Storage (Cross-UH-Verbindungen) + +| TRO | Typ | Beschreibung | Eingang JamArea | Eingang von | Ausgang JamArea | Ausgang zu | +|---|---|---|---|---|---|---| +| TRO120 | Vario | Loaded Carrier von Highway eingehend | JA4103.stJam4103_1 | Highway-Extern | — | Borner-Einspeisung | +| TRO121 | Vario | Eingang Speicher-Kreislauf 1 | JA4503.stJam4503_1 | Extern | — | — | +| TRO122 | 1Sep | Speicher-Transition | JA4503.stJam4503_2 | Extern | JA4502.stJam4502_1 | TRO123 | +| TRO123 | Vario | Speicher-Übergabe | JA4502.stJam4502_1 | TRO122 | — | — | +| TRO124 | 1Sep1Swi | Switch: Carousel / Highway-Storage | JA4502.stJam4502_2 | Extern | Dir1: JA4204.stJam4204_2 → TRO125 | Dir2: JA4501.stJam4501_1 → TRO127 | +| TRO125 | 1Sep | Highway-Exit Richtung Carousel | JA4204.stJam4204_2 | TRO124 (Dir1) | JA4203.stJam4203_1 | TRO126 | +| TRO126 | Vario | Leere Carrier → Storage | JA4203.stJam4203_1 | TRO125 | — | Storage | +| TRO127 | Vario | Highway-Ausgang | JA4501.stJam4501_1 | TRO124(D2), TRO130 | — | — | +| TRO128 | Vario | Leere Carrier → Inbound (von Highway) | JA4501.stJam4501_2 | Extern | — | — | +| TRO129 | 1Sep | Borner-Eingang Seite 2 | JA4302.stJam4302_2 | Extern | JA4204.stJam4204_1 | TRO130 | +| TRO130 | 1Sep | Transition zu Highway | JA4204.stJam4204_1 | TRO129 | JA4501.stJam4501_1 | TRO127 | +| TRO131 | Vario | Loaded Carrier → AMR | JA4403.stJam4403_1 | Extern | — | AMR-System | +| TRO132 | 1Sep | (auskommentiert — nicht aktiv) | — | — | — | — | +| TRO133 | Vario | Highway-Eingang 2 | JA4302.stJam4302_1 | Extern | — | — | +| TRO134 | Vario | AMR Highway | JA4402.stJam4402_1 | Extern | — | — | + +--- + +### 14. Erweiterungen aus der E/A-Listen- und Positionsdaten-Analyse + +Die Analyse der Eingabelisten in `data/Eingaben/` (siehe [EA-Listen-Analyse.md](EA-Listen-Analyse.md)) hat gezeigt, dass grosse Teile des JSON automatisch aus den Projektierungsdaten befuellbar sind. Dafuer werden folgende Schema-Erweiterungen eingefuehrt: + +#### 14.1 Feld `unit` je TRO/Conveyor (Schluessel zur E/A-Liste) + +Jede TRO-/Conveyor-Instanz erhaelt die Foerdertechnik-Einheit (M-Nummer) als expliziten Schluessel. Die M-Nummern stehen in den Kommentaren der E/A-Listen und identisch in den REGION-Namen des SCL-Codes: + +```json +{ + "id": "TRO115", + "unit": "M4104", + "unitKind": "CV", + "type": "Vario", + "pos": { "x": 341906, "y": 164862 }, + "cabinet": "UC1101" +} +``` + +| Feld | Quelle | Bedeutung | +|---|---|---| +| `unit` | Kommentar E/A-Liste (`(ILS-CV M4104)`) | M-Nummer der mechanischen Einheit | +| `unitKind` | dito | `KR` = Kreisel/Carousel, `CV` = Conveyor, `K` = Kreisel-Einfahrt | +| `pos` | `..._positions.json` -> `sensors[@].pos` | x/y-Lage in mm (Referenzsensor der Einheit) | +| `cabinet` | `..._positions.json` -> `mappings` | Verteiler/Schaltschrank aus der realen Verkabelung | + +#### 14.2 Gruppierungsebene `areas` + +Neue Top-Level-Ebene, die TROs/Conveyors zu den in den Listen gefundenen Bereichsgruppen buendelt: + +```json +"areas": [ + { + "id": "Block 1.1.1", + "kind": "pinStoreBlock", + "members": ["TRO208", "TRO209", "TRO210"], + "ucStations": ["UC2101"], + "safetyZone": "UZ0201", + "storageDb": "DB_Storage1.1.1", + "lines": 8 + }, + { + "id": "LS1", + "kind": "loadingStation", + "members": ["TRO103", "TRO104", "TRO105", "TRO106", "LoadingBoom1"], + "safetyZone": "UZ0110" + }, + { + "id": "WS1.1", + "kind": "workStation", + "members": ["TRO421"] + } +] +``` + +Gefundene `kind`-Werte: `pinStoreBlock` (Block x.y.z, UH02/UH03), `loadingStation` (LS 1/2, UH01), `workStation` (WS x.y, UH04/UH05), `safetyZone` (UZ0x0y), `ucStation` (Feldstation/Verteiler). + +#### 14.3 Rollenklassifikation ueber das `VERW`-Vokabular + +Die Positions-JSONs (`..._positions.json`) enthalten je Signal das Feld `VERW` — ein kontrolliertes Vokabular, das zuverlaessiger ist als das Parsen der freien Kommentartexte: + +| `VERW`-Wert | Rolle im JSON | Hinweis auf FB-Typ | +|---|---|---| +| `In sep` | `separator.sensorInSep` | — | +| `Sep` | `outputs.stopper*` (MB-Ausgang) | — | +| `Jam detector` / `Jam detector (LP)` | `sensorJam*` | — | +| `ES branch` | `outputs.sw*ExTo*` (Weichenausgang) | `1SepNSwi` | +| `conveyor full` | `vario.sensors.jam` / Puffer voll | `Vario` | +| `MT in Position` | `vario.sensors.carrInPos` | `Vario` | +| `Finger in position` | `vario.sensors.finger` | `Vario` | +| `PIN query` | PinStore-Abfrage | `PinStore_Auto` | +| `Sync P1`..`P4` | Synchronisationspunkte | PinStore/Vario-Sonderform | +| `Rad dreht` | LoadingBoom Rad-Sensor | LoadingBoom | + +Heuristik fuer den FB-Typ je Einheit: `ES branch` vorhanden -> Weiche; `Finger`/`MT in Position`/`conveyor full` -> `Vario`; `PIN query` -> `PinStore_Auto`; Anzahl `In sep` (1/2) -> `1Sep`/`2Sep`; nur FC/MA-Paar ohne Separator -> `FB_Conveyor`. + +#### 14.4 Quellen-Uebersicht + +| Datenquelle | Liefert | +|---|---| +| `..._TIA.xlsx` "PLC Tags" | BMK-Name, Datentyp, `%E/%A`-Adresse, Kommentar -> `sensors[]`, `outputs` | +| `..._TIA.xlsx` "Constants" | `cIn...`-Indexkonstanten -> Konstanten-Tabelle, `sensors[].constant` | +| `..._WSCAD.xlsx` "Bezug" | Ortskennzeichen `=A01+UCxxxx-KF1DIx` -> Karten-/Stationszuordnung | +| `..._positions.json` | `pos` (x/y), `VERW` (Rolle), `mappings` (Signal->Verteiler), `distributors` (Verteiler-Position) | +| `..._todraw.json` | Kabelwege und -laengen (Doku/BOM, nicht SPS-relevant) | + +Nicht aus den Listen ableitbar bleiben: Timings, Priority-Manager, Release-Ausdruecke, Scanner-Zuordnung (BX = PROFINET), `customCode` und die Verkettungsrichtung der Topologie (`connections`/`destinations`). Die Positionen dienen dabei als Plausibilitaets-Check der Topologie (kurze Abstaende = wahrscheinliche Nachbarn) und fuer massstabsgetreue Lageplaene. + +#### 14.5 Skeleton-Generator + +Das Skript [lib/create_skel.py](../lib/create_skel.py) (Aufruf ueber `bin\create_skel.bat`) liest die Eingabelisten und erzeugt je Steuerung ein Skeleton der JSON-Zwischendatei (`results/skeleton_UH0x.json`) sowie ein SCL-Grundgeruest. Die globalen Definitionen werden beim Programmstart aus `PV_CFG` geladen: [cfg/skel.cfg](../cfg/skel.cfg) (JSON: Dateinamen, `VERW`-Vokabular, FB-Typ-Regeln) und [cfg/skel_scl.cfg](../cfg/skel_scl.cfg) (INI-Style: die SCL-Aufruf-Templates, zeilenweise lesbar — jede `[sektion]` ist ein Template, der Inhalt wird verbatim inkl. Einrueckung und Leerzeilen uebernommen). Fehlende Konfigurationsdateien fallen auf die im Skript eingebauten Defaults zurueck (Cold-Start-faehig). + +Mit `--con-ini` bzw. `--con-json` liest der Generator zusaetzlich die TRO-Topologie aus [data/connect.ini](../data/connect.ini) bzw. [data/connect.json](../data/connect.json) (Format `hmf-connect-v1`, extrahiert aus [TRO_Graph_UH01-UH05.dot](TRO_Graph_UH01-UH05.dot)) und ergaenzt jedes Skeleton um einen `topology`-Abschnitt: je TRO die aufgeloeste JamArea-Verdrahtung (`entries`/`exits` inkl. `dbRef` auf `"DB_JamAreaxxxx".stJamxxxx_y`), dazu die rohen `connections`/`externals`-Listen. Beide Eingabewege liefern identische Ergebnisse. + +--- + +## Welche SCL-Bausteine werden daraus generiert? + +| Ziel-Baustein | Generiert aus JSON-Abschnitt | +|---|---| +| `FB_Main` VAR-Deklaration | `conveyors[]`, `tros[]`, `loadingBooms[]`, `emptyCarrBuffers[]` | +| `FB_Main` REGION Conveyor | `conveyors[]` — Settings + Call-Pattern je Subtype | +| `FB_Main` REGION TRO | `tros[]` — Separator-Settings + Call je fbType | +| `FB_Main` REGION LoadingBoom | `loadingBooms[]` — Controls/Boom/Foot/Call/Outputs | +| `FB_Main` REGION EmptyCarrBuffer | `emptyCarrBuffers[]` — Lines/Jams/Call | +| `FB_Main` REGION Reinitialisieren | alle `tros[].mainTroNo` + `emptyCarrBuffers[].mainTroNo` | +| `FB_CallSensors` | `sensors[]` — repetitiver Call-Block pro Sensor | +| `FC_Direction` | `routing.switches[]` — CASE-Statement | +| `FC_Call_Jams` | `jamAreas[]` — Jam-Aufrufe | +| `FC_CARR_GLOB_CORRECTION` | TROs mit `correction`-Feld | +| Konstanten-Tabelle | Alle `constant`-Felder — TIA-Konstantenliste | + +--- + +## Vorteile + +1. **Single Source of Truth**: Aenderung an einem Ort (JSON) statt in 5 verschiedenen 3000-9000 Zeilen SCL-Dateien +2. **Fehlerreduktion**: Kein Copy-Paste mehr zwischen UH01-UH05 +3. **Review**: Topologie-Aenderungen sind als JSON-Diff lesbar +4. **Neues Projekt**: Nur neue JSON-Datei anlegen, Code wird generiert +5. **Validierung**: JSON-Schema kann Pflichtfelder, gueltige Typen etc. pruefen + +--- + +## Sonderlogik-Behandlung (Hybrid-Ansatz) + +| Muster | Haeufigkeit | Behandlung | +|---|---|---| +| Scanner + Correction | 5x pro UH | Eigene JSON-Felder (`scanner`, `correction`) | +| SSCC-Scanner + WCS-Telegramm | 2x pro UH | Eigene JSON-Felder (`ssccScanner`, `wcsTelegram`) | +| Buersten-Taktlogik | 4x in UH01 | Eigenes JSON-Feld (`brushConfig`) | +| Priority Manager | ~10x pro UH | Eigenes JSON-Feld (`priority`) | +| Clearing-Station (Delete-Buttons) | 1x in UH01 | `customCode.afterCall` | +| Laengenmessung DReqM | 1x in UH01/UH05 | `customCode.afterCall` | + +--- + +## Offene Designentscheidungen + +1. **Ausdruck-Sprache**: Felder wie `release` enthalten SCL-Ausdruecke (`#fbLoadingBoom1.xOutReady AND ...`). Diese werden als Strings durchgereicht. + +2. **Generator**: Falls gewuenscht, Python + Jinja2-Templates als `bin/generate_scl.py` im Repository. + +3. **JamArea-Kapazitaeten**: Koennten vollstaendig in die JSON aufgenommen werden, um auch die JamArea-DBs zu generieren. + +4. **Topologie-Verbindungen**: Die JSON beschreibt aktuell jedes Element isoliert. Optional koennte ein `connections`-Abschnitt die Verkettung (TRO100 -> JamArea0101 -> TRO101_IN -> Buffer -> TRO101 -> JamArea0102 -> ...) explizit machen. \ No newline at end of file diff --git a/doc/HundM/SCL_Analyse_Standardisierung.md b/doc/HundM/SCL_Analyse_Standardisierung.md new file mode 100644 index 0000000..45687d4 --- /dev/null +++ b/doc/HundM/SCL_Analyse_Standardisierung.md @@ -0,0 +1,240 @@ +# SCL-Bausteinanalyse: Standardisierungspotenzial +**Projekt:** HundM_Fortna +**Datum:** 2026-06-23 +**Analysierte Konfigurationen:** UH01, UH02, UH03, UH04, UH05 +**Gesamt SCL-Dateien:** ~224 Baustein-Deklarationen gefunden + +--- + +## Methodik + +- **Eingeschlossen:** Alle `.scl`-Dateien in projektspezifischen Verzeichnissen +- **Ausgeschlossen (bereits bibliothekarisiert):** + - `*/1_BaseSystemLib/**` (UH01, UH04, UH05) + - `*/2_ILSLib/**` (UH01, UH04, UH05) + - `*/BaseSystemLib/**` (UH02, UH03) + - `*/ILSLib/**` (UH02, UH03) + - `LGF_DTLtoString_ISO` (Siemens LGF-Standardbibliothek) +- **Kriterium:** Baustein erscheint identisch (gleicher Name) in mehreren Konfigurationen → Duplikationspflege notwendig + +--- + +## Priorität 1 — In ALLEN 5 Konfigurationen vorhanden + +> Diese 22 Bausteine werden in jedem SPS-Projekt kopiert und separat gepflegt. +> **Empfehlung:** Sofort in eine gemeinsame Projektbibliothek auslagern. + +| Baustein | Typ | Kategorie | Pfad | +|---|---|---|---| +| `FB_CallSensors` | FB | Sensoren | `050_Sensors/` | +| `FB_PreMain` | FB | Programmstruktur | `075_PreMain/` | +| `FB_Main` | FB | Programmstruktur | `100_Main/` | +| `FC_CARR_GLOB_CORRECTION` | FC | MFR | `200_MFR/` | +| `FC_Direction` | FC | MFR | `200_MFR/` | +| `FC_Int2String` | FC (→ String) | Hilfsfunktionen | `400_BasicFunctions/FC/` | +| `FC_Jam` | FC | Stau | `400_BasicFunctions/FC/` ¹ | +| `FC_StorageLines` | FC | Puffer | `400_BasicFunctions/FC/` ² | +| `FC_Call_Jams` | FC | Stau | `700_Jams/` | +| `FB_CommunicationWCSBL` | FB | Kommunikation | `900_Communications/` ³ | +| `FB_FortnaTele_Placeholder` | FB | Kommunikation | `900_Communications/` ⁴ | +| `FB_CommunicationLogger` | FB | Kommunikation | `900_Communications/TCP-Logger/` | +| `FB_Visu` | FB | Visualisierung | `970_Visu/` | +| `FB_Visu_Jam` | FB | Visualisierung | `970_Visu/` | +| `FB_Visu_Jams` | FB | Visualisierung | `970_Visu/` | +| `FC_CarrierManipulator` | FC | Visualisierung | `970_Visu/` | +| `FC_BARCODE_SEARCH` | FC | Barcode | `Programmbausteine/` (Root) | +| `FC_GET_PROFINET_DEVICE_STATES` | FC | PROFINET | `PROFINET/` | +| `Programming error` | OB | Fehlerbehandlung | `Programmbausteine/` (Root) | +| `FB-OPC_UA_System-Stat` | FB | SCADA | `SCADA/` | +| `FB_PerfTest` | FB | Performance | `_PerformanceMeasurement_/` | +| `FC_S7` | FC | IBN/Test | `_IBN/` | + +**Anmerkungen:** +- ¹ UH03: Datei liegt in `700_Jams/FC_Jam.scl` statt `400_BasicFunctions/FC/` +- ² UH03: Datei liegt in `800_Storage/FC_StorageLines.scl` statt `400_BasicFunctions/FC/` +- ³ UH03/UH04/UH05: Unterordner `Fortna-WES-WCS/` +- ⁴ UH04/UH05: Unterordner `Fortna-WES-WCS/Misc/` + +--- + +## Priorität 2 — In 4 von 5 Konfigurationen vorhanden + +| Baustein | Typ | Vorhanden in | Fehlt in | Bemerkung | +|---|---|---|---|---| +| `FB_EventLog_StepChange` | FB | UH02, UH03, UH04, UH05 | UH01 | Neu, fehlt noch in UH01 | +| `FB_PriorityLogic` | FB | UH01, UH03, UH04, UH05 | UH02 | UH02 hat `FB_PriorityManagement` (abweichende Logik) | +| `FC_Get_LaneStatus` | FC (→ String) | UH01, UH03, UH04, UH05 | UH02 | UH02 verwendet andere Lane-Logik | + +--- + +## Priorität 3 — In 3 Konfigurationen vorhanden + +| Baustein | Typ | Vorhanden in | Bemerkung | +|---|---|---|---| +| `FB_Visu_JamStorage` | FB | UH01, UH02, UH03 | UH04/UH05 benötigen kein Jam-Puffer-Visu? | + +--- + +## Priorität 4 — In 2 Konfigurationen vorhanden + +### 4a) AI/Storage-Gruppe (UH02 + UH03) + +Diese Gruppe enthält die Lagerungs- und Umstapelintelligenz. Beide Konfigurationen pflegen identische Kopien. + +| Baustein | Typ | +|---|---| +| `FB_LineEmptyAnalyze` | FB | +| `FB_LineLvlAnalyze` | FB | +| `FB_RearrangeSequencer` | FB | +| `FB_RearrangeStartCoordination` | FB | +| `FB_StockRemovalBLKModul` | FB | +| `FB_StockRemovalSequencerUDT` | FB | +| `FB_StorageManagement` | FB | +| `FB_StorageManagementCall` | FB | +| `FB_UpdateMessage` | FB | + +> **Hinweis:** UH02 hat zusätzliche Varianten `_New`, `_New_EY`, `Lvl1` — diese sollten konsolidiert werden (siehe Sonderanalyse unten). + +### 4b) CPU-CPU-Exchange (UH02 + UH03) + +| Baustein | Typ | Pfad | +|---|---|---| +| `FB_I-Device_ReceiveCarrier` | FB | `_CPU-CPU-Exchange/` | +| `FB_I-Device_SendCarrier` | FB | `_CPU-CPU-Exchange/` | + +### 4c) Visu-Erweiterungen (UH02 + UH03) + +| Baustein | Typ | +|---|---| +| `FB_Visu_AuslagernAI` | FB | +| `FB_Visu_AuslagernList` | FB | +| `FB_Visu_ListPinband` | FB | + +### 4d) Kommunikation (paarweise) + +| Baustein | Typ | Vorhanden in | +|---|---|---| +| `FB_CommunicationWES_ASRS` | FB | UH02 + UH03 | +| `FC_Call_StorageLines` | FC | UH02 + UH03 | +| `FB_CommunicationWES_DeviceHub` | FB | UH04 + UH05 | + +### 4e) Längenmessung (UH01 + UH05) + +| Baustein | Typ | Pfad | +|---|---|---| +| `FB_Längenmessung` | FB | `Längenmessung/` | +| `FB_LaengenmessungAI` | FB | `970_Visu/` | + +### 4f) String-Konvertierung (UH01 + UH04) + +| Baustein | Typ | Rückgabetyp | +|---|---|---| +| `FC_usint2String` | FC | String | +| `FC_Uint2TroString` | FC | String | + +> **Zusatzempfehlung:** Zusammen mit `FC_Int2String` (5x vorhanden) prüfen, ob alle drei durch Siemens-Standardfunktionen (`INT_TO_STRING`, `USINT_TO_STRING`) ersetzt werden können. Falls eigene Formatierung nötig: zu einer parametrierbaren FC zusammenfassen. + +### 4g) AMR/F2H-Verwandtschaft (UH04 + UH05) + +| Baustein | Typ | Vorhanden in | +|---|---|---| +| `FB_ScanMonitor` | FB | UH04 + UH05 | +| `FB_TROHandshakeAMR` | FB | UH04 + UH05 | + +### 4h) Test-Bausteine (UH02 + UH03) + +| Baustein | Typ | Pfad | +|---|---|---| +| `FB_Test_RotierenMT` | FB | `_IBN/` | + +--- + +## Sonderanalyse: Versionschaos — StockRemoval (UH02) + +In UH02 existieren 4 Varianten desselben Kernbausteins nebeneinander: + +| Baustein | Pfad | Status | +|---|---|---| +| `FB_StockRemovalBLKModul` | `200_MFR/_AutomatedIntelligence/` | Original | +| `FB_StockRemovalBLKModul_New` | `200_MFR/_AutomatedIntelligence/` | Neuversion | +| `FB_StockRemovalBLKModul_New_EY` | `200_MFR/_AutomatedIntelligence/Embi/` | Sonderabzweig | +| `Fb_StockRemovalManagementLvl1` | `200_MFR/_AutomatedIntelligence/` | Lvl1-Erweiterung | + +**UH03** hat daneben noch: +- `FB_StockRemovalManagementLvl2` +- `FB_StockRemovalSequencer` +- `FB_StorageManagement_Rework` +- `FB_StorageTaskScheduler` + +**Empfehlung:** Auf eine versionierte Hauptvariante reduzieren. Unterschiede als konfigurierbare Parameter lösen. `old/`-Verzeichnisse aufräumen. + +--- + +## Sonderanalyse: "old/"-Verzeichnisse (technische Schulden) + +Folgende Bausteine liegen in `old/`-Unterordnern und sollten entfernt werden: + +| Baustein | Konfiguration | Pfad | +|---|---|---| +| `FB_AMR_Management` | UH04 | `200_MFR/_AutomatedIntelligence/old/` | +| `FB_F2H_Management` | UH05 | `200_MFR/_AutomatedIntelligence/old/` | + +--- + +## Nicht standardisierbar (anlagenspezifisch) + +Diese Bausteine sind inhärent projektspezifisch und sollten **nicht** zusammengelegt werden: + +| Baustein | Konfiguration | Begründung | +|---|---|---| +| `FB_PriorityManagement` | UH02 | Abweichende Priorisierungslogik vs. `FB_PriorityLogic` | +| `FB_OffsetCorrection` | UH02 | Anlagenspezifische Korrektur | +| `FC_ClearJam`, `FC_PutToHj` | UH01 | Spezifische MFR-Logik UH01 | +| `FB_EmptyCarrBuffer`, `FB_Pin_EmptyBuffer` | UH01 | Pin-Puffer spezifisch UH01 | +| `FB_SSCCAI` | UH01 | SSCC-Scan spezifisch | +| `ReadServerDiagnostics` | UH01 | OPC-UA Diagnose | +| `ReadSessionDiagnostics` | UH01 | OPC-UA Diagnose | +| `CheckForTimeOut` | UH01 | OPC-UA Session-Timeout | +| `LCom_Example` (OB) | UH01 | Beispiel/IBN | +| `TestBaustein`, `FB_TestMain` | UH01 | IBN/Test | +| `FB_BoomWorkStation` | UH01 | Ladeschleife spezifisch | +| `FB_ButtonAck` | UH01 | Ladeschleife spezifisch | +| `FB_DistanceFoot` | UH01 | Ladeschleife spezifisch | +| `FB_LoadingBoom_INBOUND` | UH01 | Ladeschleife spezifisch | +| `FB_MotorSimple_INBOUND` | UH01 | Ladeschleife spezifisch | +| `FB_StopperSimple` / `FB_StopperSpecial` | UH01 | Ladeschleife — könnten aber zusammengefasst werden | +| `FB_Tilt_TEST` | UH01 | Test | +| `FB_LV1BlockStorageManagement` | UH02 | Spezifisch UH02 | +| `FB_Lvl1AdditionalRouting` | UH02 | Spezifisch UH02 | +| `Fb_StockRemovalManagementLvl1` | UH02 | Spezifisch UH02 | +| `FB_StockRemovalManagementLvl2` | UH03 | Spezifisch UH03 | +| `FB_StockRemovalSequencer` | UH03 | Spezifisch UH03 | +| `FB_StorageManagement_Rework` | UH03 | Rework-Branch | +| `FB_StorageTaskScheduler` | UH03 | Spezifisch UH03 | +| `FB_AMR_Management_V2` | UH04 | AMR-Verwaltung UH04 | +| `FB_CallAMRManagement` | UH04 | AMR-Aufruflogik UH04 | +| `FB_F2H_Management_Rework` | UH05 | F2H Rework-Branch | +| `FB_CallF2HManagement` | UH05 | F2H-Aufruflogik UH05 | +| `FC_GetStationIndex` | UH05 | Stationsindex UH05 | +| `FB_PhasenTest` | UH02 | Phasenüberwachungs-Test | +| `FB_Test_RotierenMT` | UH02, UH03 | IBN-Test | + +--- + +## Zusammenfassung: Standardisierungspotenzial + +| Priorität | Anzahl Bausteine | Konfigurationsbreite | Aufwand | +|---|---|---|---| +| **P1** — Alle 5 UH | 22 | 5x | Hoch, aber höchster Nutzen | +| **P2** — 4 von 5 UH | 3 | 4x | Mittel | +| **P3** — 3 von 5 UH | 1 | 3x | Niedrig | +| **P4** — 2 von 5 UH | 23 | 2x | Nach Gruppen priorisieren | +| **Gesamt** | **49** | — | — | + +### Top-5 Quick Wins + +1. **`FC_GET_PROFINET_DEVICE_STATES`** — Reine Diagnose-FC, kein anlagenspezifischer Inhalt. Sofort in BaseSystemLib. +2. **`FB-OPC_UA_System-Stat`** — OPC-UA-Standard-Handling, identisch in allen 5 UH. Sofort in BaseSystemLib. +3. **`Programming error` (OB)** — Standard-Fehlerbehandlungs-OB, keine Anlagenlogik. +4. **`FC_Int2String` / `FC_usint2String` / `FC_Uint2TroString`** — String-Konvertierungen; prüfen ob `INT_TO_STRING` (STEP 7) ausreicht, sonst eine gemeinsame FC. +5. **`FB_CommunicationLogger`** — TCP-Logger-Logik ohne anlagenspezifische Abhängigkeiten, in allen 5 UH identisch. diff --git a/doc/HundM/suggestion.md b/doc/HundM/suggestion.md new file mode 100644 index 0000000..522e3ae --- /dev/null +++ b/doc/HundM/suggestion.md @@ -0,0 +1,235 @@ +# Vorschlag: Vereinheitlichung der MainTRO-Bausteine (`FB_ILS_MTRO`) + +Stand: 2026-07-13 + +## Ausgangslage + +Die Anlage verwendet derzeit **sieben verschiedene MainTRO-Bausteine**, die aus dem +SPS-Code extrahiert wurden: + +| Typ | Separatoren | Weichen | Eingänge | Ausgänge (Richtungen) | Prio-Manager | Scanner | Besonderheit | +|---|---|---|---|---|---|---|---| +| `FB_ILS_MTRO_1Sep` | 1 | 0 | 1 | 1 (Exit2) | 1 | 1 | Borner/Dummy-Handling | +| `FB_ILS_MTRO_1Sep_SSCC` | 1 | 0 | 1 | 1 | 1 | 2 (+SSCC) | Endmess-Sensor | +| `FB_ILS_MTRO_1Sep1Swi` | 1 | 1 | 1 | 2 (Exit2/3) | 2 (Dir1/2) | 1 | 2. Kreisel | +| `FB_ILS_MTRO_1Sep2Swi` | 1 | 2 | 1 | 3 (Exit2/3/4) | 1 | 1 | 2. Kreisel | +| `FB_ILS_MTRO_2Sep1Swi` | 2 | 1 | 2 | 2 | 4 (Dir1-4) | 2 | 2 Eingänge, 2 Kreisel | +| `FB_ILS_MTRO_Vario` | 1 | 0 (Vario) | 1 | 1 (+Finger-Jam) | 1 | 1 | Kettenförderer, Finger-/Pos-Sensoren, Motorschutz | +| `FB_ILS_MTRO_PinStore_Auto` | 1 + 21 | n | 1 | n Stationen | 1 | 1 | **Ausreißer** — Lagerblock, Encoder, Lagerlinien | + +## Kernerkenntnis + +Alle MainTRO-Varianten basieren auf **demselben Grundgerüst**: ein `FB_StateManager` +mit identischer Schrittkette +(`WaitForTrolley → Scan → CheckLoad → CheckSep → GetDirection → CheckJam → CheckSwitch → ReleaseSep → Buchen`), +plus zusammengesetzte Sub-TRO-Bausteine (`FB_ILS_STRO_Sep`, `FB_ILS_STRO_Switch`, +`FB_ILS_STRO_Vario`, `FB_BarcodeReaderCognex`). + +Was sich zwischen den Typen unterscheidet, ist fast ausschließlich die **Anzahl** +einiger Sub-Module und die entsprechende Zahl an Staubereichen/Richtungen. Das +Namensschema `SepSwi` bringt es auf den Punkt: Es sind keine 7 Verhaltensweisen, +sondern **ein Verhalten**, instanziiert mit 1–2 Separatoren, 0–2 Weichen, 1–4 Richtungen. + +Der skalare Teil der Schnittstelle ist **überall identisch**: `stInSettings` (Borner, +Jam-Src/Dest, `bSepType`, Timings), `nInMainTroNo`, `xInSftyOk`, `xInAllRdyToStart`, +`xInTestMode`, `xInCancel`, `xInAreaStopActive`, `xInRelease`, dazu die Ausgänge +`xOutCorrection / nOutStateLast / nOutScanResult / xOutNewScan` und die In-Outs +`stInOutMachineState / stInOutCognexInterface / stInOutHMI`. Lediglich die +*wiederholten* Elemente werden von Hand vervielfältigt und durchnummeriert +(`...1`, `...2`, `Dir1..Dir4`, `Exit2..Exit4`). + +## Vorschlag: ein einziger Baustein `FB_ILS_MTRO` + +Die von Hand nummerierten Member werden durch **Arrays von zusammengesetzten UDTs** +ersetzt, plus einen **Konfigurations-/Routing-Deskriptor**, der angibt, wie viele +Elemente jeder Art existieren und wie jede Richtung verdrahtet ist. Der skalare Kern +bleibt unverändert. + +### 1. Vereinheitlichte TRO-Typdefinition (ersetzt die 7 `fbType`-Namen) + +```json +{ + "$def": "FB_ILS_MTRO", + "description": "Single MainTRO block, shaped by config instead of by type name", + "config": { + "nNoOfSeparators": { "type": "USInt", "range": [1, 2] }, + "nNoOfSwitches": { "type": "USInt", "range": [0, 2] }, + "nNoOfCarousels": { "type": "USInt", "range": [1, 2] }, + "nNoOfDirections": { "type": "USInt", "range": [1, 4] }, + "xScannerPlugged": { "type": "Bool" }, + "xSsccPlugged": { "type": "Bool" }, + "xVarioMode": { "type": "Bool" } + }, + "arrays": { + "arInSeparator": "Array[1..2] of UDT_MTRO_SeparatorIf", + "arInSwitch": "Array[1..2] of UDT_MTRO_SwitchIf", + "arInDirection": "Array[1..4] of UDT_MTRO_DirectionIf", + "arInPriorityManager": "Array[1..4] of UDT_Response", + "arInCarouselRun": "Array[1..2] of Bool", + "arInOutJamEntr": "Array[1..2] of UDT_JamArea", + "arInOutJamExit": "Array[1..4] of UDT_JamArea" + }, + "scalarCore": [ + "stInSettings", "nInMainTroNo", "xInSftyOk", "xInAllRdyToStart", + "xInTestMode", "xInCancel", "xInAreaStopActive", "xInRelease", + "stInOutMachineState", "stInOutHMI" + ] +} +``` + +### 2. Die zusammengesetzten UDTs, die als Array geführt werden + +```json +{ + "UDT_MTRO_SeparatorIf": { + "stSenInSep": "UDT_Sensor", "stSenSepLeft": "UDT_Sensor", + "stSenPart": "UDT_Sensor", "stSenStartScan": "UDT_Sensor", + "stSenJamExit": "UDT_Sensor", + "Settings": "SettingsSeparator", + "bSepType": "Byte", "xIsBorner": "Bool", "nBornerDest": "Int" + }, + "UDT_MTRO_SwitchIf": { + "stSenExit3": "UDT_Sensor", "stSenExit4": "UDT_Sensor", + "Settings": "SettingsSwitch" + }, + "UDT_MTRO_DirectionIf": { + "xPrioRelevant": "Bool", + "nSepIndex": "USInt", "nSwitchIndex": "USInt", "nSwitchPos": "USInt" + }, + "UDT_JamArea": { + "arCarrier": "Array[*] of stCarrier", "stData": "stJamData" + } +} +``` + +### 3. Per-Instanz-Konfiguration, die jeden alten Typ reproduziert (die "Anreicherung") + +```json +{ + "instances": [ + { + "name": "TRO101", "replaces": "FB_ILS_MTRO_1Sep", + "config": { "nNoOfSeparators": 1, "nNoOfSwitches": 0, + "nNoOfCarousels": 1, "nNoOfDirections": 1, + "xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false }, + "direction": [ { "nSepIndex": 1, "nSwitchIndex": 0, "nSwitchPos": 0, "xPrioRelevant": false } ] + }, + { + "name": "TRO102", "replaces": "FB_ILS_MTRO_1Sep_SSCC", + "config": { "nNoOfSeparators": 1, "nNoOfSwitches": 0, + "nNoOfCarousels": 1, "nNoOfDirections": 1, + "xScannerPlugged": true, "xSsccPlugged": true, "xVarioMode": false } + }, + { + "name": "TRO103", "replaces": "FB_ILS_MTRO_1Sep1Swi", + "config": { "nNoOfSeparators": 1, "nNoOfSwitches": 1, + "nNoOfCarousels": 2, "nNoOfDirections": 2, + "xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false }, + "direction": [ + { "nSepIndex": 1, "nSwitchIndex": 1, "nSwitchPos": 3, "xPrioRelevant": true }, + { "nSepIndex": 1, "nSwitchIndex": 1, "nSwitchPos": 4, "xPrioRelevant": true } + ] + }, + { + "name": "TRO104", "replaces": "FB_ILS_MTRO_1Sep2Swi", + "config": { "nNoOfSeparators": 1, "nNoOfSwitches": 2, + "nNoOfCarousels": 2, "nNoOfDirections": 3, + "xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false } + }, + { + "name": "TRO105", "replaces": "FB_ILS_MTRO_2Sep1Swi", + "config": { "nNoOfSeparators": 2, "nNoOfSwitches": 1, + "nNoOfCarousels": 2, "nNoOfDirections": 4, + "xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false } + }, + { + "name": "TRO106", "replaces": "FB_ILS_MTRO_Vario", + "config": { "nNoOfSeparators": 1, "nNoOfSwitches": 0, + "nNoOfCarousels": 1, "nNoOfDirections": 1, + "xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": true } + } + ] +} +``` + +### 4. Einbindung in die bestehende `units[]`-Skeleton-Struktur + +Heute schreibt `create_skel.py` einen `fbType`-String pro Einheit. Im Vorschlag wird +dieses eine Feld zu `fbType: "FB_ILS_MTRO"` plus ein `config`-Objekt, das der Generator +aus den gezählten Rollen füllt: + +```json +{ + "unit": "M0101", + "fbType": "FB_ILS_MTRO", + "config": { + "nNoOfSeparators": 1, "nNoOfSwitches": 1, + "nNoOfCarousels": 2, "nNoOfDirections": 2, + "xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false + }, + "io": { + "sensorInSep": ["BG0101"], + "switchOutput": ["MB0102"], + "stopperOutput": ["MB0101"], + "sensorJam": ["BG0103"] + } +} +``` + +`guess_fbtype()` (liefert heute einen der 7 Namen, siehe `lib/create_skel.py:558-563`) +würde stattdessen `"FB_ILS_MTRO"` zurückgeben plus einen zählenden Regelsatz: + +```json +{ + "configRules": { + "nNoOfSeparators": "count(roles == 'sensorInSep')", + "nNoOfSwitches": "count(roles == 'switchOutput')", + "nNoOfDirections": "count(roles == 'switchOutput') + 1", + "xScannerPlugged": "any(role == 'sensorStartScan')", + "xVarioMode": "has(roles, 'sensorFinger') or has(roles, 'sensorCarrInPos')" + } +} +``` + +## Abbildung der alten Typen auf den neuen Baustein (Übersicht) + +| Alter Typ | Konfiguration, die ihn reproduziert | +|---|---| +| `1Sep` | Sep=1, Swi=0, Car=1, Dir=1 | +| `1Sep_SSCC` | Sep=1, Swi=0, Dir=1, `xSsccPlugged=TRUE` | +| `1Sep1Swi` | Sep=1, Swi=1, Car=2, Dir=2 | +| `1Sep2Swi` | Sep=1, Swi=2, Car=2, Dir=3 | +| `2Sep1Swi` | Sep=2, Swi=1, Car=2, Dir=4 | +| `Vario` | Sep=1, Swi=0, Dir=1, `xVarioMode=TRUE` | + +Sieben Bausteine → **ein Baustein + ein Konfigurationsdatensatz pro Instanz**. + +## Was separat bleibt + +- **`FB_ILS_MTRO_PinStore_Auto`** ist ein echter Ausreißer — 21 Linien-Separatoren, + Encoder-Positionserfassung, Lagerlinien-Daten (`arInOutStorageLines`), + Auslager-Stationen. Es ist ein *Lager*-Controller, kein Routing-TRO. Die übrigen + sechs werden in `FB_ILS_MTRO` zusammengeführt; PinStore bleibt eigenständig + (oder wird zu `FB_ILS_STORE`). +- **Vario** ist ein Grenzfall: Es tauscht die Weiche gegen einen Kettenförderer mit + Finger-/Positionssensoren. Es passt als `xVarioMode` (ein Sub-Modul-Schalter), weil + es weiterhin denselben Separator + State-Manager nutzt. Falls die Finger-Schrittkette + zu stark abweicht, ist ein dünner Wrapper über den gemeinsamen Kern der Mode-Flag + vorzuziehen. + +## Abwägung + +- **Pro:** ein Baustein zum Testen/Versionieren/Dokumentieren; `create_skel.py` wird + deutlich einfacher (kein `FBTYPE_TEMPLATE`-Mapping, ein Aufruf-Template); das in der + Standardisierungsanalyse markierte "Versionschaos" entfällt. +- **Contra:** Arrays mit `nNoOf...`-Guards sind weniger selbsterklärend als ein + benannter `1Sep1Swi`; ungenutzte Array-Elemente kosten pro Instanz weiterhin + DB-Speicher. Multi-Instanz-Sub-FB-Arrays und `Array[*]`-In-Outs werden auf dem + Zielsystem (CPU 1518F) gut unterstützt — es gibt keinen Plattform-Blocker. + +## Nächste Schritte (offen) + +1. `FB_ILS_MTRO.scl`-Skelett prototypisieren (mit `FOR`-Schleifen-Aufrufen der Sub-TROs + und einer datengetriebenen Richtungs-Tabelle). +2. `create_skel.py` anpassen, sodass es den einzelnen Baustein mit `config`-Block + ausgibt statt der sieben Templates. \ No newline at end of file diff --git a/doc/TRO_Typen.md b/doc/TRO_Typen.md new file mode 100644 index 0000000..c334b7e --- /dev/null +++ b/doc/TRO_Typen.md @@ -0,0 +1,662 @@ +# Vollständige TRO-Typen-Übersicht — HundM_Fortna (UH01–UH05) + +## Zweck + +Dieses Dokument listet **alle** im Code tatsächlich vorkommenden TRO-Funktionsbaustein-Typen über alle 5 Steuerungen (UH01–UH05) auf — als Ergänzung/Verifikation zur ersten Aufstellung in [Json_Layout-Konzept.md](Json_Layout-Konzept.md) Abschnitt "Identifizierte Element-Typen". Für jeden Typ folgt in diesem Dokument ein eigenes Kapitel mit einem JSON-Vorschlag; die zugehörigen SCL-Template-Dateien liegen in [scl_templates/](scl_templates/). + +**Wichtiger Befund:** Die meisten `FB_ILS_MTRO_*`-Typen sind ausschliesslich als `.liblink` (externe ILSLib-Bibliothek) im Repository vorhanden — der FB-Quellcode selbst liegt **nicht** im Git-Repo (siehe [CLAUDE.md](../CLAUDE.md), Abschnitt "Verwendete Bibliotheken"). Für diese Typen enthalten die Templates den **realen Instanziierungs-/Aufrufcode** aus `FB_Main.scl` (Parametrierung), nicht den FB-Körper. Nur 4 Typen haben lokalen SCL-Quellcode im Repository. + +--- + +## Übersichtstabelle aller TRO-Typen + +| # | TRO-Typ (`type`) | FB-Name | Quelle im Repo | Verwendung (UH) | Beschreibung | +|---|---|---|---|---|---| +| 1 | `1Sep` | `FB_ILS_MTRO_1Sep` | nur `.liblink` | UH01–UH05 (alle) | Standard-Einzelseparator, kein Weichenausgang | +| 2 | `1Sep1Swi` | `FB_ILS_MTRO_1Sep1Swi` | nur `.liblink` | UH01–UH05 (alle) | Separator + 1 Weiche (2 Ausgänge) | +| 3 | `1Sep2Swi` | `FB_ILS_MTRO_1Sep2Swi` | nur `.liblink` | UH02 (TRO267, TRO268) | Separator + 2 Weichen (bis zu 4 Ausgänge/Slots) | +| 4 | `1Sep_SSCC` | `FB_ILS_MTRO_1Sep_SSCC` | nur `.liblink` | UH01 (TRO105, TRO110) | Separator + Barcode-Scanner + SSCC-Scanner + WCS-DReqM-Telegramm | +| 5 | `Vario` | `FB_ILS_MTRO_Vario` | nur `.liblink` | UH01–UH05 (alle); in UH03 zusätzlich für F2H-Streckenabschnitte wiederverwendet (Kommentar „Vario von F2H", z. B. TRO308, TRO383) | Kettenförderer/Vario-Streckenabschnitt | +| 6 | `PinStore_Auto` | `FB_ILS_MTRO_PinStore_Auto` | nur `.liblink` | UH02, UH03 | Automatisches Pin-Lager mit bis zu 19 Speicherlinien je Block, inkl. Scanner + Storage-Removal-Schnittstelle | +| 7 | `Vario_workStation` | `FB_ILS_MTRO_Vario_workStation` | **lokal vorhanden** (`2_ILSLib/FB/MTRO/Special/`) | UH04 (TRO421–423) | Vario-Variante für manuellen Arbeitsplatz (Work Station); nutzt intern `FB_ILS_STRO_Vario_WorkStation` | +| 8 | `EmptyCarrBuffer` | `FB_EmptyCarrBuffer` | **lokal vorhanden** (`800_Storage/`) | UH01 (TRO101, TRO102) | Mehrzeiliger Leertablar-Puffer mit Verteilweiche | +| 9 | `LoadingBoom` | `FB_LoadingBoom_INBOUND` | **lokal vorhanden** (`_Ladeschleife/400_Modules/`) | UH01 (LoadingBoom1, LoadingBoom2) | Ladeschleife: Boom, Fuss, Stopper, Tilt/Distance-Sensorik — kein `TROnnn`-Instanzname, sondern eigenständiges Element mit TRO-Anbindung | +| 10 | `2Sep1Swi` | `FB_ILS_MTRO_2Sep1Swi` | **lokal vorhanden** (`2_ILSLib/FB/MTRO/`) | UH01 — **im Code vorhanden, aber in keiner FB_Main.scl instanziiert** (verwaist/unbenutzt, Schrittkette größtenteils auskommentiert) | Doppel-Separator + 1 Weiche (Konzeptbaustein, nicht produktiv) | + +Nicht als eigener TRO-Typ modelliert, aber verwandt und in [Json_Layout-Konzept.md](Json_Layout-Konzept.md) bereits behandelt: **Conveyor/Carousel** (`FB_Conveyor`, kein MainTRO, sondern Antriebseinheit) und **Sensor** (`FB_SensorInput`, kein TRO). + +--- + +## Basistyp und Baukasten-Analyse + +### Fragestellung + +Lassen sich die 10 TRO-Typen auf einen gemeinsamen **Basistyp** zurückführen, aus dem die übrigen Typen durch reine **Ergänzung einzelner Bausteine** entstehen — oder gibt es Typen, die strukturell wirklich eigenständig sind? + +### Methode + +Die Antwort steckt im Code selbst: Jede `FB_ILS_MTRO_*`-Instanz (bzw. `FB_EmptyCarrBuffer`/`FB_LoadingBoom_INBOUND`) instanziiert in ihrem `VAR`-Abschnitt eigene **Sub-TRO-Bausteine (STRO)**. Diese Sub-Bausteine sind der eigentliche Baukasten: + +| Sub-Baustein | Rolle | +|---|---| +| `FB_ILS_STRO_Sep` | Separator/Stopper — vereinzelt Carrier, meldet Belegung/Freigabe | +| `FB_ILS_STRO_Switch` | Weiche — lenkt auf 2 Ausgänge | +| `FB_BarcodeReaderCognex` | Cognex-Scanner-Anbindung | +| `FB_ILS_STRO_Vario` / `FB_ILS_STRO_Vario_WorkStation` | Kettenförderer-Antrieb (Standard bzw. Arbeitsplatz-Variante) | +| `FB_CarrAccumulate1Sep` | Wartepuffer-/Rückstau-Logik vor einem Separator | +| `FB_StateManager` | generische Schrittketten-Unterstützung (in allen Typen) | + +Für die lokal vorliegenden FB-Quellen lässt sich das direkt nachweisen (Auszug `VAR`-Sektion): + +``` +FB_ILS_MTRO_2Sep1Swi: fbSeparator1, fbSeparator2 : "FB_ILS_STRO_Sep"; fbSwitch1 : "FB_ILS_STRO_Switch" +FB_ILS_MTRO_Vario_workStation: fbSeparator1 : "FB_ILS_STRO_Sep"; fbConvVario : "FB_ILS_STRO_Vario_WorkStation" +FB_EmptyCarrBuffer: arfbSeparatorStorage : Array[1..5] of "FB_ILS_STRO_Sep" // 5x derselbe Sub-Baustein! +FB_LoadingBoom_INBOUND: fbTiltSensor : "FB_Tilt_TEST"; fbDistanceFoot : "FB_DistanceFoot"; fbWorkSation : "FB_BoomWorkStation" + // KEIN FB_ILS_STRO_Sep, KEIN FB_ILS_STRO_Switch! +``` + +### Basistyp: `1Sep` + +Der Basistyp ist **1x `FB_ILS_STRO_Sep`** (Separator/Stopper) plus das gemeinsame Rahmenwerk, das jeder Typ ausnahmslos besitzt: PriorityManager-Schnittstelle, JamArea Entry/Exit, HMI-Struktur, Safety/Release/AllReadyToStart, MachineState, CognexInterface-Durchreichung (auch wenn ungenutzt). Das entspricht exakt dem in [Kapitel 1](#1-tro-typ-1sep) dokumentierten JSON-Schema. + +### Baukasten-Module (additive Bausteine) + +| Modul | Sub-Baustein | Taucht auf in | +|---|---|---| +| **Switch** | `FB_ILS_STRO_Switch` | `1Sep1Swi` (1x), `1Sep2Swi` (2x), `2Sep1Swi` (1x) | +| **2. Separator** | `FB_ILS_STRO_Sep` (zusätzliche Instanz) | `2Sep1Swi` | +| **Scanner** | `FB_BarcodeReaderCognex` | `1Sep_SSCC`, `1Sep2Swi`, `Vario_workStation`, `PinStore_Auto` | +| **SSCC/Messmodul** | Scanner-Variante + Messsensor + WCS-Feld | `1Sep_SSCC` | +| **Vario-Antrieb** | `FB_ILS_STRO_Vario` / `_WorkStation` | `Vario`, `Vario_workStation` | +| **WorkStation-Schnittstelle** | Stationssensor + Freigabetaster + `FB_CarrAccumulate1Sep` | `Vario_workStation` (immer in Kombination mit Vario-Antrieb beobachtet) | +| **Storage-Line-Array** | `FB_ILS_STRO_Sep` als `Array[1..N]` + Verteillogik | `EmptyCarrBuffer` (N=5, manuell), `PinStore_Auto` (N=19, automatisiert + Encoder + StorageRemoval-Handshake) | +| **WCS-Telegramm** | DReqM/GOHDReqM-Schnittstelle | `1Sep_SSCC`, `1Sep2Swi` | + +### Mapping-Tabelle: Typ = Basis + Module? + +| Typ | Additiv aus Basis `1Sep` + Module? | Zusammensetzung | +|---|---|---| +| `1Sep` | **= Basis selbst** | — | +| `1Sep1Swi` | ✅ additiv | Basis + 1x Switch-Modul | +| `1Sep2Swi` | ✅ additiv | Basis + 2x Switch-Modul + Scanner-Modul | +| `1Sep_SSCC` | ✅ additiv | Basis + Scanner-Modul + SSCC-Modul + WCS-Telegramm | +| `Vario` | ✅ additiv | Basis + Vario-Antriebsmodul (ersetzt einfachen `xInCarouselRun`-Eingang) | +| `Vario_workStation` | ✅ additiv | Basis + Vario-Antriebsmodul + WorkStation-Schnittstelle | +| `EmptyCarrBuffer` | ✅ additiv | Basis (als `inTro`) + 5x Storage-Line-Modul + einfache Verteilausgänge | +| `PinStore_Auto` | ✅ additiv (grösster Baukasten) | Basis (als Pin-Separator) + 19x Storage-Line-Modul + Scanner-Modul + Encoder + StorageRemoval-Schnittstelle | +| `2Sep1Swi` (unbenutzt) | ✅ additiv | Basis + 2. Separator-Modul + 1x Switch-Modul | +| `LoadingBoom` | ❌ **nicht additiv** | Eigene Achs-/Bewegungslogik (`FB_Tilt_TEST`, `FB_DistanceFoot`, `FB_BoomWorkStation`) — **kein** `FB_ILS_STRO_Sep`, **kein** `FB_ILS_STRO_Switch` im Baustein | + +### Fazit + +**9 von 10 Typen sind strukturell additive Kombinationen desselben Baukastens** rund um den Basistyp `1Sep`. Das ist keine Vermutung, sondern direkt aus den `VAR`-Deklarationen der Bausteine ablesbar: `EmptyCarrBuffer` und `PinStore_Auto` instanzieren beide Arrays von `FB_ILS_STRO_Sep`, `Vario` und `Vario_workStation` nutzen beide dieselbe `FB_ILS_STRO_Sep` als Eingangsseparator kombiniert mit einem Vario-Antriebsmodul, `1Sep1Swi`/`1Sep2Swi`/`2Sep1Swi` unterscheiden sich nur in der Anzahl der Switch- bzw. Separator-Module. + +**Nur `LoadingBoom` ist ein wirklich eigenständiger Elementtyp.** Er hat keinen Separator/Switch-Kern, sondern eine komplett andere Achs-/Bewegungslogik (Boom vor/zurück, Fuss hoch/runter, Tilt-/Distanzsensorik) und verwendet dafür einen völlig anderen Satz an Sub-Bausteinen. Er sollte weiterhin als eigenständiger `type` (bzw. eigenständiges Symbol) geführt werden, nicht als Modul-Kombination des Basistyps. + +### Konsequenz für BricsCAD-Symbol und JSON-Schema + +Das rechtfertigt, **ein Basis-Symbol mit Baukasten-Modul-Flags** zu bauen statt neun separater Symbolvarianten zu pflegen. Siehe die entsprechende Ergänzung in [BricsCAD_TRO_Symbol.md](BricsCAD_TRO_Symbol.md#baukasten-erweiterung-modul-flags-statt-symbolvarianten). + +--- + +## Ergänzung zur Standardisierungsanalyse: StockRemoval/PinStore-Umfeld + +Die `PinStore_Auto`-TROs sind über `stMFRStorageRemovalInterface` an die Lager-/Umstapelintelligenz gekoppelt. Dort herrscht laut [SCL_Analyse_Standardisierung.md](SCL_Analyse_Standardisierung.md) "Versionschaos": + +| Baustein | Pfad | UH02 | UH03 | +|---|---|---|---| +| `FB_StockRemovalBLKModul` | `200_MFR/_AutomatedIntelligence/` | ✓ (Original) | ✓ | +| `FB_StockRemovalBLKModul_New` | `200_MFR/_AutomatedIntelligence/` | ✓ | — | +| `FB_StockRemovalBLKModul_New_EY` | `200_MFR/_AutomatedIntelligence/Embi/` | ✓ | — | +| `Fb_StockRemovalManagementLvl1` | `200_MFR/_AutomatedIntelligence/` | ✓ | — | +| `FB_StockRemovalManagementLvl2` | `200_MFR/_AutomatedIntelligence/` | — | ✓ | +| `FB_StockRemovalSequencer` | `200_MFR/_AutomatedIntelligence/` | — | ✓ | +| `FB_StockRemovalSequencerUDT` | `200_MFR/_AutomatedIntelligence/` | ✓ | ✓ | +| `FB_StorageManagement_Rework` | `200_MFR/_AutomatedIntelligence/` | — | ✓ | +| `FB_StorageTaskScheduler` | `200_MFR/_AutomatedIntelligence/` | — | ✓ | + +Diese Bausteine sind **nicht** Teil des TRO-JSON-Modells selbst (kein `type` im Sinne dieses Dokuments), sondern die dahinterliegende Lagerlogik, die über `stMFRStorageRemovalInterface` am `PinStore_Auto`-TRO andockt. + +## Ergänzung: F2H (Floor-to-Hub) + +Es existiert **kein eigener F2H-TRO-Typ**. In UH03 werden F2H-Streckenabschnitte mit dem normalen `FB_ILS_MTRO_Vario` realisiert (nur per Kommentar als F2H gekennzeichnet, z. B. TRO308, TRO383, TRO386). Die eigentliche F2H-*Verwaltungslogik* (kein TRO, sondern Koordinationsbaustein) liegt in UH05: `FB_CallF2HManagement.scl`, `FB_F2H_Management_Rework.scl` (aktiv) sowie `old/FB_F2H_Management.scl` (Altversion, siehe „old/"-Technikschulden in SCL_Analyse_Standardisierung.md). + +--- + +## Kapitel je TRO-Typ + +Die folgenden Kapitel enthalten je TRO-Typ einen JSON-Vorschlag für das Attribut-Set aus `tros[]` (bzw. dem jeweils passenden Top-Level-Array) in der [Json_Layout-Konzept.md](Json_Layout-Konzept.md)-Struktur, abgeleitet aus dem zugehörigen SCL-Template in [scl_templates/](scl_templates/). + +1. [1Sep](#1-tro-typ-1sep) +2. [1Sep1Swi](#2-tro-typ-1sep1swi) +3. [1Sep2Swi](#3-tro-typ-1sep2swi) +4. [1Sep_SSCC](#4-tro-typ-1sep_sscc) +5. [Vario](#5-tro-typ-vario) +6. [PinStore_Auto](#6-tro-typ-pinstore_auto) +7. [Vario_workStation](#7-tro-typ-vario_workstation) +8. [EmptyCarrBuffer](#8-tro-typ-emptycarrbuffer) +9. [LoadingBoom](#9-tro-typ-loadingboom) +10. [2Sep1Swi (unbenutzt)](#10-tro-typ-2sep1swi-unbenutzt) + +--- + +### 1. TRO-Typ `1Sep` + +**FB:** `FB_ILS_MTRO_1Sep` · **Quelle:** `.liblink` (kein lokaler Code) · **Template:** [scl_templates/FB_ILS_MTRO_1Sep.scl](scl_templates/FB_ILS_MTRO_1Sep.scl) · **Beispiel:** TRO100 (UH01) + +```json +{ + "id": "TRO100", + "type": "1Sep", + "fbType": "FB_ILS_MTRO_1Sep", + "mainTroNo": "cMainTro100", + "controlUnit": "OF1", + "comment": "Eingang Kreisel", + "separator": { + "no": "cSep100.1", + "delayToNextItem": "TimeForSepWaiting_Short", + "trailingTime": "T#600ms", + "handlingTime": "T#200ms", + "jamTime": "TimeForSepJam", + "senFree": "T#1500ms", + "senWait": "T#4000ms", + "plugged": { "jam": true, "part": false, "scanner": false }, + "sensorInSep": "cInBG3242" + }, + "sensorJam2": "cInBG3243", + "priority": { "releaseOk": true }, + "call": { + "carouselRun": "fbCarousel0101.xOutConveyorFullSpeed", + "release": "DB_TRO_TEST.TRO100" + }, + "jamAreas": { + "entry": "DB_JamArea0100.stJam0100_1", + "exit": "DB_JamArea0101.stJam0101_1" + }, + "outputs": { "stopper1": "MB3242" }, + "hmi": "DB_Interface_HMI.stTRO.TRO100" +} +``` + +--- + +### 2. TRO-Typ `1Sep1Swi` + +**FB:** `FB_ILS_MTRO_1Sep1Swi` · **Quelle:** `.liblink` (kein lokaler Code) · **Template:** [scl_templates/FB_ILS_MTRO_1Sep1Swi.scl](scl_templates/FB_ILS_MTRO_1Sep1Swi.scl) · **Beispiel:** TRO107 (UH01) + +```json +{ + "id": "TRO107", + "type": "1Sep1Swi", + "fbType": "FB_ILS_MTRO_1Sep1Swi", + "mainTroNo": "cMainTro107", + "controlUnit": "OF1", + "comment": "Switch Boom 1", + "separator": { + "no": "cSep107.1", + "delayToNextItem": "TimeForSepWaiting_Short", + "trailingTime": "T#100ms", + "handlingTime": "T#50ms", + "jamTime": "TimeForSepJam", + "plugged": { "jam": true, "part": false, "scanner": false }, + "sensorInSep": "cInBG3306" + }, + "sensorJam2": "cInBG3305", + "sensorJam3": "cInBG3330", + "switch": { + "no": "cSwi107.1", + "pluggedExSen3": false, + "pluggedExSen4": false, + "nTo1Destinations": 3 + }, + "settings": { "prioDir2": true }, + "priority": { + "managerDir2In": "DB_Prozessdaten.stPriorityManager.udt_TRO107.TroIn", + "managerDir2Out": "DB_Prozessdaten.stPriorityManager.udt_TRO107.TroOut" + }, + "call": { + "carouselRun1": "fbCarousel0102.xOutConveyorFullSpeed", + "release": "true" + }, + "jamAreas": { + "entry": "DB_JamArea0102.stJam0102_1", + "exit2": "DB_JamArea0103.stJam0103_1", + "exit3": "DB_JamArea0102.stJam0102_2" + }, + "outputs": { "stopper1": "MB3306", "sw1ExTo3": "MB3304" }, + "hmi": "DB_Interface_HMI.stTRO.TRO107", + "direction": { + "switchNo": "cSwi107.1", + "carrierSource": "DB_JamArea0102.stJam0102_1.arCarrier[1]" + } +} +``` + +--- + +### 3. TRO-Typ `1Sep2Swi` + +**FB:** `FB_ILS_MTRO_1Sep2Swi` · **Quelle:** `.liblink` (kein lokaler Code) · **Template:** [scl_templates/FB_ILS_MTRO_1Sep2Swi.scl](scl_templates/FB_ILS_MTRO_1Sep2Swi.scl) · **Beispiel:** TRO267 (UH02) + +Separator mit **zwei** Weichen (`switch1`, `switch2`) und bis zu 4 Ausgängen (`exit2`–`exit4`); zusätzlich Barcode-Scanner am Eingang. + +```json +{ + "id": "TRO267", + "type": "1Sep2Swi", + "fbType": "FB_ILS_MTRO_1Sep2Swi", + "mainTroNo": "cMainTro267", + "controlUnit": "OF1", + "comment": "1Sep2Switch + Scanner(BX2100)", + "separator": { + "no": "cSep267.1", + "delayToNextItem": "TimeForSepWaiting_Medium", + "plugged": { "jam": true, "part": true, "scanner": true }, + "sensorInSep": "cInBG4440", + "sensorPart": "cInBG4465" + }, + "sensorJam2": "cInBG4444", + "sensorJam3": "cInBG4455", + "sensorJam4": "cInBG4454", + "switch1": { + "no": "cSwi267.1", + "pluggedExSen3": false, + "pluggedExSen4": false, + "newSwitch": true, + "nTo1Destinations": 3 + }, + "switch2": { + "pluggedExSen3": false, + "pluggedExSen4": false, + "newSwitch": true, + "nTo1Destinations": 3 + }, + "scanner": { + "id": "cScannerBX2100", + "prefix": "bx2100", + "hwResults": "=A01+UC021-BX2100~Ergebnisse_-_64_Bytes_1", + "checkASCII": true, + "timeout": "T#5s" + }, + "settings": { "sepType_x2": true }, + "priority": { "releaseOk": true }, + "call": { + "carouselRun1": "fbCarousel1110.xOutConveyorFullSpeed", + "carouselRun2": "fbCarousel1110.xOutConveyorFullSpeed", + "release": "DB_TRO_Test.TRO267" + }, + "jamAreas": { + "entry": "DB_JamArea1110.stJam1110_4", + "exit2": "handoverJam5001", + "exit3": "handoverJam5000", + "exit4": "DB_JamArea1110.stJam1110_5" + }, + "outputs": { + "stopper1": "MB4440", + "sw1ExTo3": "MB4444", + "sw2ExTo3": "MB4455" + }, + "hmi": "DB_Interface_HMI.stTRO.TRO267" +} +``` + +--- + +### 4. TRO-Typ `1Sep_SSCC` + +**FB:** `FB_ILS_MTRO_1Sep_SSCC` · **Quelle:** `.liblink` (kein lokaler Code) · **Template:** [scl_templates/FB_ILS_MTRO_1Sep_SSCC.scl](scl_templates/FB_ILS_MTRO_1Sep_SSCC.scl) · **Beispiel:** TRO105 (UH01) + +Bereits vollständig in [Json_Layout-Konzept.md](Json_Layout-Konzept.md#tro-1sep_sscc--sscc-scanner--wcs-telegramm) Abschnitt 4 spezifiziert (siehe dort für das komplette Beispiel inkl. `wcsTelegram`). Kurzfassung: + +```json +{ + "id": "TRO105", + "type": "1Sep_SSCC", + "fbType": "FB_ILS_MTRO_1Sep_SSCC", + "mainTroNo": "cMainTro105", + "controlUnit": "OF1", + "comment": "SSCC Scanner Boom 1", + "separator": { + "no": "cSep105.1", + "trailingTime": "T#600ms", + "handlingTime": "T#200ms", + "senFree": "T#1500ms", + "senWait": "T#4000ms", + "plugged": { "jam": true, "part": false, "scanner": true }, + "sensorInSep": "cInBG3280" + }, + "sensorJam2": "cInBG3281", + "scanner": { + "id": "cScannerBX1104", + "hwResults": "BX1104~Ergebnisse_-_64_Bytes_1", + "checkASCII": true, + "timeout": "T#3000ms" + }, + "ssccScanner": { + "hwResults": "BX1107~Ergebnisse_-_64_Bytes_1", + "checkASCII": true, + "timeout": "T#3s", + "sensorEndMeasurement": "cInBG3281" + }, + "priority": { "releaseOk": true }, + "call": { + "carouselRun": "true", + "release": "FB_CommunicationWCSBL_DB.fbTeleHandler.xOutConnectionActive OR IBN.xFahrenOhneTcpPartner" + }, + "jamAreas": { + "entry": "DB_JamArea0104.stJam0104_3", + "exit": "DB_JamArea0106.stJam0106_2" + }, + "outputs": { "stopper1": "MB3280" }, + "hmi": "DB_Interface_HMI.stTRO.TRO105" +} +``` + +--- + +### 5. TRO-Typ `Vario` + +**FB:** `FB_ILS_MTRO_Vario` · **Quelle:** `.liblink` (kein lokaler Code) · **Template:** [scl_templates/FB_ILS_MTRO_Vario.scl](scl_templates/FB_ILS_MTRO_Vario.scl) · **Beispiel:** TRO115 (UH01) + +```json +{ + "id": "TRO115", + "type": "Vario", + "fbType": "FB_ILS_MTRO_Vario", + "mainTroNo": "cMainTro115", + "controlUnit": "OF1", + "comment": "Loaded To Storage Vario", + "separator": { + "no": "cSep115.1", + "trailingTime": "T#800ms", + "handlingTime": "T#300ms", + "senFree": "T#2000ms", + "senWait": "T#5000ms", + "plugged": { "jam": false, "part": false, "scanner": false }, + "sensorInSep": "cInBG3025" + }, + "vario": { + "continousEmptying": false, + "waitForJog": "T#300ms", + "convEmpty": "T#45000ms", + "countCarrier": 1, + "waitForStop": "T#3s", + "carrierInPosDelay": "T#1200ms", + "carrierInPosEdgeDelay": "T#100ms", + "rasterHigh": "T#5s", + "rasterLow": "T#5s", + "jamSenDelayActive": true, + "jamSenDelay": "T#2s", + "sensors": { + "carrInPos": "cInBG3026", + "finger": "cInBG3027", + "lastPos": "cInBG3000", + "jam": "cInBG3001" + } + }, + "settings": { "isBorner": true }, + "priority": { "releaseOk": true }, + "call": { + "motorProtection": "FC0145", + "automatic": "#t_Automatik_OF1 AND SF0120", + "errorQuit": "SF0002", + "release": "DB_TRO_TEST.TRO115" + }, + "jamAreas": { + "entry": "DB_JamArea4104.stJam4104_1", + "finger": "DB_JamArea4103.stJam4103_1" + }, + "outputs": { "stopper": "MB3025", "varioMotor": "MA0145" }, + "hmi": "DB_Interface_HMI.stTRO.TRO115" +} +``` + +> **Hinweis F2H (UH03):** Für F2H-Streckenabschnitte wird derselbe JSON-Typ `Vario` verwendet; lediglich `comment` trägt den Hinweis "F2H" (z. B. `"comment": "Vario von F2H"`). Kein eigener `type`-Wert nötig. + +--- + +### 6. TRO-Typ `PinStore_Auto` + +**FB:** `FB_ILS_MTRO_PinStore_Auto` · **Quelle:** `.liblink` (kein lokaler Code) · **Template:** [scl_templates/FB_ILS_MTRO_PinStore_Auto.scl](scl_templates/FB_ILS_MTRO_PinStore_Auto.scl) · **Beispiel:** TRO208, Block 1.1.1 (UH02) + +Deutlich komplexer als die übrigen Typen: bis zu 19 Speicherlinien (`storageLines[]`) je Block, Encoder-Kopplung, Pin-Separator, Barcode-Scanner am Eingang und Schnittstelle zur Storage-Removal-/Umstapellogik (`FB_StockRemovalBLKModul` u. a., siehe [SCL_Analyse_Standardisierung.md](SCL_Analyse_Standardisierung.md)). + +```json +{ + "id": "TRO208", + "type": "PinStore_Auto", + "fbType": "FB_ILS_MTRO_PinStore_Auto", + "mainTroNo": "cMainTro208", + "controlUnit": "OF2", + "comment": "Block 1.1.1", + "encoder": { + "posActDif": "fbEncoderGF2200.nOutPosActDif", + "posPitchPart": "fbEncoderGF2200.nOutPosPitchPart" + }, + "settings": { + "destGeneral": "cDest11100", + "convStations": "cHooksSorterMaxPin111", + "stationsMax": "cStationsMax111", + "storageThreshold": "cNoPositionsBlock1", + "noOfLines": 19 + }, + "sensorReference": "cInBG3001", + "separatorPin": { + "sensorTrolley": "cInBG3000", + "handlingTime": "T#0ms", + "trailingTime": "T#50ms", + "pluggedScanner": true + }, + "scanner": { + "id": "cScannerBX2104", + "station": 111, + "scannerPurpose": 0, + "timeout": "T#5s", + "checkASCII": true, + "hwResults": "=A01+UH02-BX2104~Ergebnisse_-_64_Bytes_1" + }, + "storageLines": [ + { "line": 1, "jamLength": 4, "sensorTrolley": "cInBG3270", "handlingTime": "cTimeSepHandlingStorageLine", "trailingTime": "cTimeSepTrailingStorageLine", "outSeparatorStore": "MB3270" }, + { "line": 2, "jamLength": "cStorage111ExitJam2", "sensorTrolley": "cInBG3271", "handlingTime": "cTimeSepHandlingStorageLine", "trailingTime": "cTimeSepTrailingStorageLine" } + // ... Zeilen 3-19 analog, jamLength als Konstante "cStorage111ExitJamN"; + // Zeilen 7-19 zusätzlich mit "simu": { "active": "DB_SIM_PARAM.xSimuActive", ... } + ], + "unloadingJamSensors": ["cInBG3030", "cInBG3031", "cInBG3032" /* ... bis 19 */], + "quitLocal": ["SF0121", "SF0117"], + "priority": { "releaseOk": true }, + "call": { + "conveyorRunIn": "fbSortConv1101.xOutConveyorFullSpeed", + "conveyorRunOut": "fbExitConv1103.xOutConveyorFullSpeed", + "release": "DB_TRO_Test.TRO208", + "testTarget": "IBN.nTestTarget111" + }, + "jamAreas": { + "entry": "DB_JamArea1101.stJam1101_2", + "exit": "DB_JamArea1103.stJam1103_1" + }, + "storage": { + "db": "DB_Storage1.1.1" + }, + "storageRemovalInterface": "DB_HandshakeStorage.Str_StorageRemoval.arrudt_StorageRemovalHandshakeTROsLvl1[1]", + "conveyorStations": "DB_ConveyorStations.stConveyorStations111", + "outputs": { "separatorPin": "MB3000" }, + "hmi": "DB_Interface_HMI.stTRO.TRO208" +} +``` + +--- + +### 7. TRO-Typ `Vario_workStation` + +**FB:** `FB_ILS_MTRO_Vario_workStation` · **Quelle:** lokal vorhanden, [scl_templates/FB_ILS_MTRO_Vario_workStation.scl](scl_templates/FB_ILS_MTRO_Vario_workStation.scl) (vollständige FB-Implementierung, UH04) + [scl_templates/FB_ILS_MTRO_Vario_workStation_CallSite.scl](scl_templates/FB_ILS_MTRO_Vario_workStation_CallSite.scl) (reale Aufrufstelle) · **Beispiel:** TRO421 (UH04) + +```json +{ + "id": "TRO421", + "type": "Vario_workStation", + "fbType": "FB_ILS_MTRO_Vario_workStation", + "mainTroNo": "cMainTro421", + "controlUnit": "OF1", + "comment": "Manueller Arbeitsplatz 1", + "separator": { + "no": "cSep421.1", + "trailingTime": "cTimeSepTrailing", + "handlingTime": "T#200ms", + "delayToNextItem": "TimeForSepWaiting_Short", + "jamTime": "TimeForSepJam", + "senFree": "T#1200ms", + "senWait": "T#4300ms", + "plugged": { "jam": false, "part": false, "scanner": false }, + "sensorInSep": "cInBG3326" + }, + "vario": { + "continousEmptying": false, + "waitForJog": "T#400ms", + "convEmpty": "T#30000ms", + "countCarrier": 1, + "waitForStop": "T#3s", + "jamSenDelayActive": true, + "jamSenDelay": "T#2s", + "carrierInPosDelay": "T#1200ms", + "carrierInPosEdgeDelay": "T#100ms", + "sensors": { + "finger": "cInBG3315", + "lastPos": "cInBG3317", + "carrInPos": "cInBG3324", + "jam": "cInBG3320" + } + }, + "station": { + "sensor": "cInBG3314", + "releaseStation": "rTrig_Workstation 1.CLK", + "loadErrorSensor": "cInBG3325" + }, + "priority": { "releaseOk": true }, + "call": { + "motorProtection": "FC0062", + "automatic": "t_automatik", + "release": "DB_TRO_Test.TRO421" + }, + "jamAreas": { + "entry": "DB_JamArea4004.stJam4004_2", + "finger": "DB_JamArea4005.stJam4005_1" + }, + "outputs": { "stopper": "MB3326", "varioMotor": "MA0062" }, + "hmi": "DB_Interface_HMI.stTRO.TRO421" +} +``` + +--- + +### 8. TRO-Typ `EmptyCarrBuffer` + +**FB:** `FB_EmptyCarrBuffer` · **Quelle:** lokal vorhanden, [scl_templates/FB_EmptyCarrBuffer.scl](scl_templates/FB_EmptyCarrBuffer.scl) (Vollständige FB-Implementierung, UH01) · **Beispiel:** TRO101 (UH01) + +Bereits vollständig in [Json_Layout-Konzept.md](Json_Layout-Konzept.md) Abschnitt 6 spezifiziert (mehrzeiliger mit `separatorLines[]`, `inTro` als Vor-TRO). Kurzfassung: + +```json +{ + "id": "TRO101", + "type": "EmptyCarrBuffer", + "fbType": "FB_EmptyCarrBuffer", + "mainTroNo": "cMainTro101", + "controlUnit": "OF1", + "comment": "Empty Buffer rechts", + "numberOfLines": 5, + "storageDb": "DB_JamBuffer101", + "inTro": { + "id": "TRO101_IN", + "separator": { "no": 999, "sensorInSep": "cInBG3246" }, + "isBorner": true, + "bornerDest": "cDestInboundLS", + "jamEntry": "DB_JamArea0101.stJam0101_1", + "stopper": "MB3246" + }, + "separatorLines": [ + { "line": 1, "jamLength": 5, "sensor": "cInBG3320" }, + { "line": 2, "jamLength": 7, "sensor": "cInBG3321" } + ], + "jamSensors": ["cInBG3250", "cInBG3251", "cInBG3252", "cInBG3253", "cInBG3254"], + "switchLineOutputs": ["MB3250", "MB3251", "MB3252", "MB3253", "MB3254"], + "exitJam": "DB_JamArea0102.stJam0102_2", + "exitSensor": "cInBG3330", + "priority": { + "managerIn": "DB_Prozessdaten.stPriorityManager.udt_TRO101.TroIn", + "managerOut": "DB_Prozessdaten.stPriorityManager.udt_TRO101.TroOut" + }, + "hmi": "DB_Interface_HMI.stTRO.TRO101" +} +``` + +(Vollständiges Beispiel inkl. aller 5 Zeilen: siehe Json_Layout-Konzept.md Abschnitt 6.) + +--- + +### 9. TRO-Typ `LoadingBoom` + +**FB:** `FB_LoadingBoom_INBOUND` · **Quelle:** lokal vorhanden, [scl_templates/FB_LoadingBoom_INBOUND.scl](scl_templates/FB_LoadingBoom_INBOUND.scl) (Vollständige FB-Implementierung, UH01) · **Beispiel:** LoadingBoom1 (UH01) + +Kein `TROnnn`-Instanzname (Instanz heisst `fbLoadingBoom1`), aber funktional ein eigenständiges Anlagenelement mit direkter TRO-Anbindung (`relatedTro`). Bereits vollständig in [Json_Layout-Konzept.md](Json_Layout-Konzept.md) Abschnitt 5 spezifiziert. Kurzfassung: + +```json +{ + "id": "LoadingBoom1", + "type": "LoadingBoom", + "fbType": "FB_LoadingBoom_INBOUND", + "controlUnit": "OF1", + "comment": "Ladeschleife 1", + "relatedTro": "TRO104", + "boom": { + "motorProtection": ["FC0070", "FC0072"], + "limitForth": "cInBG3343", + "limitBack": "cInBG3344" + }, + "foot": { + "motorProtection": "FC0321", + "limitUp": "SF0322", + "limitDown": "SF0323" + }, + "tilt": { "analogInput": "wTiltSensorLS1" }, + "distance": { "analogInput": "wDistanceSensorLS1", "startSlow": 2510, "startFast": 2520 }, + "jamAreas": { + "stopper": "DB_JamArea0104.stJam0104_2", + "exit": "DB_JamArea0104.stJam0104_3" + }, + "hmi": "DB_Interface_HMI.stLoadingBoom.stDataBoom1" +} +``` + +(Vollständiges Beispiel inkl. aller Controls/Outputs: siehe Json_Layout-Konzept.md Abschnitt 5.) + +--- + +### 10. TRO-Typ `2Sep1Swi` (unbenutzt) + +**FB:** `FB_ILS_MTRO_2Sep1Swi` · **Quelle:** lokal vorhanden, [scl_templates/FB_ILS_MTRO_2Sep1Swi.scl](scl_templates/FB_ILS_MTRO_2Sep1Swi.scl) (UH01) · **Verwendung:** **keine** — in keiner `FB_Main.scl` instanziiert, Schrittkette ist im Quellcode fast vollständig auskommentiert (`(* ... *)`-Block "IN ARBEIT - NUR VORBEREITET"). + +Dieser Typ ist ein **Konzeptbaustein für zwei Separatoren + 1 Weiche** (analog `1Sep1Swi`, aber mit zwei unabhängigen Eingangs-Separatoren `stInSeparator1`/`stInSeparator2`), der offenbar für einen Anwendungsfall vorbereitet, aber nie fertiggestellt/produktiv verdrahtet wurde. + +**Empfehlung:** Kein JSON-`type` vorsehen, solange der Baustein nicht produktiv genutzt wird. Falls künftig benötigt, wäre folgendes Skelett der Ausgangspunkt (Struktur analog `1Sep1Swi`, verdoppelt für Separator 2): + +```json +{ + "id": "TROxxx", + "type": "2Sep1Swi", + "fbType": "FB_ILS_MTRO_2Sep1Swi", + "comment": "UNBENUTZT - Konzeptbaustein, Schrittkette nicht fertiggestellt", + "separator1": { "no": "cSepXXX.1", "sensorInSep": "" }, + "separator2": { "no": "cSepXXX.2", "sensorInSep": "" }, + "switch1": { "no": "cSwiXXX.1" }, + "sensorJam2": "", + "sensorJam3": "", + "settings": { + "car2NecRight": false, + "car2NecLeft": false, + "prioDir1": false, + "prioDir2": false, + "prioDir3": false, + "prioDir4": false + } +} +```