Layout Konzept enthält Vorschlag für die Erstellung eines Skeletts für ein SPS PRogramm. Routing hinzu

This commit is contained in:
2026-06-29 14:04:51 +02:00
parent 3bf291fdf8
commit a51a0c6fd1
3 changed files with 993 additions and 0 deletions
View File
+993
View File
@@ -0,0 +1,993 @@
# 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<UH-Nr><lfd>` (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<UH-Nr * 100 + lfd> z.B. TRO115, TRO207, TRO315
Separator-Nr: cSep<TRO-ID>.1 z.B. cSep115.1
Switch-Nr: cSwi<TRO-ID>.1 z.B. cSwi107.1
MainTroNo: cMainTro<TRO-ID> 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<ID>
```
---
## 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
---
## 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.