SCL aus parametrisierten Templates: Golden-Files, Render-Kontext, Pilot 1Sep1Swi

Schritte 1-3 aus doc/SCL_Templates.md (neu: Konzept, Wertklassen je Zeile,
Namensregeln, Tests, Migrationsplan, Vertrag fuer den CSV->SCL-Workflow).

- Golden-Files (tests/test_scl_skeleton_golden.py, tests/fixtures/scl/):
  komplette FB_Main-Ausgabe von mubea und HundM05 byte-genau festgeschrieben,
  Zeitstempel maskiert; gewollte Aenderung per SKEL_UPDATE_GOLDEN=1
- lib/scl_context.py (neu): alles, was scl_skeleton aus der TRO-JSON ableitet
  (Reihenfolge, Separator-/Weichen-/Scanner-Bloecke, Staubereiche, Ziellisten,
  Namen) als pydantic-Kontext SclFile/SclTro; Namen als SclName (Wert +
  todo-Merker) als Andockstelle fuer die Namensregeln (Schritt 4).
  scl_skeleton schreibt nur noch Text; Ausgabe byte-identisch (Golden-Files,
  zusaetzlich dematic/showroom mit und ohne --start alt/neu verglichen)
- lib/scl_templates/ (neu, Jinja2): _macros.scl.j2 + Pilot
  FB_ILS_MTRO_1Sep1Swi.scl.j2 nach der realen Aufrufstelle TRO107
  (PriorityManagerDir2, stInSenJam<n>, xInCarouselRun1, xInRelease TRUE,
  Separatorzeiten 100/50 ms). Ortsgebundene Zeilen als Vorschlag umgesetzt,
  jede offene Stelle mit TODO(E-Planung) - Bestaetigung durch SPS steht aus
- scl_skeleton: --templates [DIR] (opt-in, ohne Schalter Ausgabe unveraendert),
  --strict (Exit 1 ohne SCL, wenn ein FB-Typ kein Template hat); Kopf und
  Zusammenfassung nennen Template-/generische Typen; Templatefehler
  (StrictUndefined) -> Exit 1 ohne SCL
- tests/test_scl_templates.py: Rundlauf Template mit Referenzwerten ==
  Referenz-REGION (normalisiert); jede Platzhalterzeile traegt den TODO-Marker
- requirements.txt: jinja2 >= 3.1 (bestehende .venv: pip install -r requirements.txt)
- Doku: SCL_Templates.md, Python_Scripts.md §5b, Commandlines.md §2.5, CLAUDE.md

Befunde: xInCarouselRun1 laesst sich nicht aus der TRO-JSON ableiten (Kanten-
art "umlauf" kommt praktisch nicht vor) -> immer als TODO; nTo1Destinations
ist in der Referenz 3 bei 2 Abgaengen (zaehlt evtl. Ziele) -> "pruefen".
Mit --templates nur die 1Sep1Swi-REGIONs (+ Kopf) anders als generisch;
32 Tests gruen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Samer Ayadi
2026-10-09 18:06:18 +02:00
co-authored by Claude Opus 5.5
parent 97a0db6707
commit 4895ebf5ed
18 changed files with 7276 additions and 212 deletions
+8
View File
@@ -155,6 +155,14 @@ Since 2026-10-09 the main path is **CSV → `tro_flow.py --json` → TRO-JSON
`OpenPoint`, `Analysis`, `TroDocument`) ← derivation (`material_flow.py`, `tro_flow.py`) ←
outputs (`scl_skeleton.py`, `tro_annotate.py`, reports). `items`/`fbType` are always read
from the catalog via the TRO type, never stored. See `doc/Python_Scripts.md` §6b.
Inside the SCL output, `lib/scl_context.py` (TRO-JSON → render context, all derivations)
sits between `model.py` and `scl_skeleton.py` (context → text only). With `--templates`
(opt-in) REGIONs come from Jinja2 templates in `lib/scl_templates/<fbType>.scl.j2`
(pilot: `FB_ILS_MTRO_1Sep1Swi`), each round-trip tested against its reference call site
in `doc/TRO_Katalog/scl_templates/` (`tests/test_scl_templates.py`); every line holding a
placeholder must carry `TODO(E-Planung)`. Migration steps, decisions per template line
and status: `doc/SCL_Templates.md`. Golden files in `tests/fixtures/scl/` pin the SCL output byte for
byte — rewrite them (`SKEL_UPDATE_GOLDEN=1`) only for a reviewed, intended change.
1. **`lib/tro_flow.py --json`** (implemented) — writes `<csv>_tro.json` (schema
`sps_skel-tro-v2`, `model.TroDocument`): TROs, system boundaries `SYSn`, connections with
+6 -1
View File
@@ -155,12 +155,17 @@ Details: [`Python_Scripts.md` §5b](Python_Scripts.md#5b-scl_skeletonpy--generat
| `--json` | `NAME` | `export_tro.json` | TRO-JSON input (looked up in `%SKEL_RESULTS%`). |
| `--out` | `NAME` | `<source>_FB_Main.scl` | Output SCL filename. |
| `--start` | `TRO` | — | TRO where the REGION order begins. Only needed while the flow is a closed loop without a loading/unloading station (`SYSn`). |
| `--templates` | `[DIR]` | off | Build REGIONs from the FB templates (`lib/scl_templates` if `DIR` is omitted); FB types without a template stay generic. Without it: the previous output, unchanged. See [`SCL_Templates.md`](SCL_Templates.md). |
| `--strict` | — | off | With `--templates`: exit `1` and write nothing if any FB type of the plant has no template. |
Exit codes: `0` ok · `1` input/CLI error or JSON does not match the model.
Exit codes: `0` ok (also when TROs without a template were built generically) · `1`
input/CLI error, JSON does not match the model, template error, or a missing template
with `--strict`.
```bat
bin\scl_skeleton.bat --json mubea_tro.json
bin\scl_skeleton.bat --json mubea_tro.json --start TRO01
bin\scl_skeleton.bat --json mubea_tro.json --templates
```
## 3. End-to-end example
+27
View File
@@ -473,6 +473,33 @@ so `--start` is no longer needed once the export contains a station. In the
jam-area comments they are marked "(Station, kein TRO)", and an exit station
shows up as a destination in the per-switch lists.
**Internal structure.** `scl_skeleton.py` works in two stages:
`lib/scl_context.py` derives everything from the TRO-JSON into a render context
(`build_context` → `SclFile` / `SclTro`: flow order, separator/switch/scanner
blocks, jam entries/exits, destination lists, names), and `scl_skeleton.py` only
turns that context into text (`render_context`). Every name or address is an
`SclName` (value + `todo` flag); today all of them are placeholders with
`todo=True`. This split prepares the move to parameterised templates and
per-project naming rules described in [`SCL_Templates.md`](SCL_Templates.md).
**Templates (opt-in, `--templates [DIR]`).** With this switch every TRO whose FB
has a template in `lib/scl_templates/<fbType>.scl.j2` (Jinja2) is rendered from
it; the others keep the generic text above. The header and the console summary
name which FB types came from a template. Today only the pilot
`FB_ILS_MTRO_1Sep1Swi` exists — it follows the real call site of TRO107 line for
line (priority manager `Dir2`, `stInSenJam<n>`, `xInCarouselRun1`, reference
times 100/50 ms), and every value that is still open carries
`TODO(E-Planung)`. `--strict` stops (exit `1`, no SCL) if any FB type has no
template. Without `--templates` the output is unchanged.
Tests: `tests/test_scl_context.py` (the derivations one by one),
`tests/test_scl_templates.py` (each template rendered with the real values of
its reference call site must equal that call site, comments and whitespace
ignored) and `tests/test_scl_skeleton_golden.py` (the whole output of mubea and
HundM05 byte for byte against `tests/fixtures/scl/*_FB_Main.scl` and
`*_FB_Main_templates.scl`, timestamp masked; an intended change is written
back with `SKEL_UPDATE_GOLDEN=1`).
## 6. `tro_catalog.py` — TRO type catalog (library, no CLI)
The single source of truth for everything needed to generate or draw a TRO
+492
View File
@@ -0,0 +1,492 @@
# SCL Generation from Parameterised Templates — Concept
**Status:** steps 1–3 of §11 done — pilot template `FB_ILS_MTRO_1Sep1Swi` usable with
`--templates`, default output unchanged · **As of:** 2026-10-09
This is the plan for moving `scl_skeleton.py` from hard-coded SCL (Python f-strings in
the `emit_*` functions) to **parameterised templates**: the SCL structure for each FB
lives in a template file, and Python only supplies the data.
It is written so that it fits the existing main path unchanged:
```
export.csv ─► tro_flow --json ─► <name>_tro.json ─► scl_skeleton ─► <name>_FB_Main.scl
(dxfmakros (derive) (TroDocument, (render) (skeleton with
EXPORTCSV) sps_skel-tro-v2) TODO(E-Planung))
```
Nothing upstream of `scl_skeleton` changes. The TRO-JSON stays the only input, and the
CLI, output file name, `TODO(E-Planung)` marker and exit codes stay compatible. A
workflow that calls the chain today keeps working, and gets the new behaviour only by
passing the new optional switches.
---
## 1. Why
Today the knowledge about each FB call site is copied into Python by hand. That has
two problems:
1. **It drifts.** Compared with the real call site of `FB_ILS_MTRO_1Sep1Swi` (TRO107),
the generated code already differs: the priority-manager call parameters
(`stInPriorityManagerDir2`/`stOutPriorityManagerDir2`, `stInSettings.xPrioDir2`),
`xInCarouselRun1` and the jam sensors `stInSenJam2/3` are missing; the separator times
differ (600/200 ms instead of 100/50 ms); the parameter order differs.
2. **It is in the wrong place for the people who own it.** A PLC engineer can correct
an SCL file; they will not edit Python f-strings.
With templates, the SCL structure is SCL again, the reference call sites become testable,
and the project-specific names can be plugged in through a config (§7).
---
## 2. Reference material that exists today
`doc/TRO_Katalog/scl_templates/` holds two **different kinds** of files. Both stay
**read-only** (see `CLAUDE.md`); they are the reference, not the templates we render.
| Kind | What it is | Use in this concept |
|---|---|---|
| **Call site** (43–138 lines) | A real `REGION` from an `FB_Main`: parameter lines plus the instance call, with real values (`TRO107`, `cSep107.1`, `MB3306`) | Source for the parameterised template **and** the expected output of its round-trip test (§8.1) |
| **FB source** (800–1550 lines) | The full `FUNCTION_BLOCK` with `VAR_INPUT`/`VAR_OUTPUT`/`VAR_IN_OUT` | The FB **interface**; every parameter a template writes must exist there (§8.2) |
Coverage per catalog type (`lib/tro_catalog.py`):
| Catalog type | FB | Call site | FB source | Template possible |
|---|---|---|---|---|
| `1Sep` | `FB_ILS_MTRO_1Sep` | yes (TRO 100) | — | yes |
| `1Sep1Swi` | `FB_ILS_MTRO_1Sep1Swi` | yes (TRO 107) | — | yes — **first pilot** |
| `1Sep2Swi` | `FB_ILS_MTRO_1Sep2Swi` | yes (TRO 267) | — | yes |
| `1Sep_SSCC` | `FB_ILS_MTRO_1Sep_SSCC` | yes (TRO 105) | — | yes |
| `Vario` | `FB_ILS_MTRO_Vario` | yes (TRO 115) | — | yes |
| `PinStore_Auto` | `FB_ILS_MTRO_PinStore_Auto` | yes (TRO 208) | — | yes (outlier, largest) |
| `Vario_workStation` | `FB_ILS_MTRO_Vario_workStation` | yes (TRO 421, `_CallSite.scl`) | yes | yes, with interface check |
| `2Sep1Swi` | `FB_ILS_MTRO_2Sep1Swi` | **no** | yes | from interface only — needs a real call site |
| `EmptyCarrBuffer` | `FB_EmptyCarrBuffer` | **no** | yes | from interface only — needs a real call site |
| `LoadingBoom` | `FB_LoadingBoom_INBOUND` | **no** | yes | from interface only — needs a real call site |
| `2Sep2Swi` | `FB_ILS_MTRO_2Sep2Swi` | **no** | **no** | no — FB does not exist yet (Mubea needs it) |
So 7 types can be done with a test against real code. 3 can only be checked against the
interface until someone supplies a real call site. `2Sep2Swi` stays on the fallback (§9).
---
## 3. Design principles
1. **Templates hold structure, Python holds data.** No SCL text in Python except the
file header and the fallback.
2. **Keep the item-based composition.** `doc/HundM/suggestion.md` shows that all
`FB_ILS_MTRO_*` share one skeleton and differ only in how many separators, switches,
directions and jam areas they repeat. The templates mirror that: shared macros for the
repeated blocks, one thin template per FB that arranges them in that FB's order.
3. **Never invent a value.** Anything without a source stays `TODO(E-Planung)`, as it
does today. A plausible-looking wrong address is worse than an obvious gap.
4. **Every value has exactly one origin**, visible in the template (§6): layout, naming
rule, reference default, E-Planung, or condition.
5. **The TRO-JSON is the contract.** The render context is built only from
`model.TroDocument`; templates never read the CSV, the DXF or the catalog directly.
6. **Fail loudly in templates.** An undefined variable is an error (Jinja2
`StrictUndefined`), not an empty string in the SCL.
7. **Additive migration.** The existing `emit_*` code stays as the fallback until every
type has a template; with no new switch the output is byte-identical to today.
---
## 4. Files and folders
```
sps_skel/
├── doc/TRO_Katalog/scl_templates/*.scl reference, read-only (unchanged)
├── lib/
│ ├── scl_skeleton.py CLI + order + context + render (changed)
│ ├── scl_context.py NEW: TroDocument -> render context (pydantic)
│ ├── scl_naming.py NEW: reads the naming config, resolves names
│ └── scl_templates/ NEW: the parameterised templates
│ ├── _macros.scl.j2 shared blocks (separator, switch, jam, call, direction)
│ ├── FB_ILS_MTRO_1Sep1Swi.scl.j2 pilot ✅
│ └── ... one per FB, named exactly like fbType
├── cfg/
│ ├── scl_naming.ini NEW: default naming rules (from the reference plant)
│ └── <project>_scl_naming.ini NEW, optional: per-project override
└── tests/
├── test_scl_templates.py round trip against the reference call sites ✅
├── test_scl_skeleton_golden.py whole-file regression on mubea/HundM05 ✅
├── test_scl_context.py the derivations one by one ✅
└── fixtures/scl/
├── <name>_tro.json fixed inputs (mubea, HundM05)
├── <name>_FB_Main.scl expected output, generic
└── <name>_FB_Main_templates.scl expected output, with --templates
```
The file frame (header, `VAR` list, REGION loop) stays in Python (`render_context`) for
now; only the REGIONs come from templates. A `_file.scl.j2` is only worth it once every
REGION does. The reference values of a round trip are set in the test itself
(`tests/test_scl_templates.py`) instead of a JSON fixture, so new context fields need no
fixture update.
**Lookup:** the template file name is the TRO's `fbType` from the catalog
(`FB_ILS_MTRO_1Sep1Swi` → `FB_ILS_MTRO_1Sep1Swi.scl.j2`). No second mapping table, so the
catalog stays the only place that links a type to its FB.
**Dependency:** `jinja2 >= 3.1` is added to `requirements.txt`.
---
## 5. Template structure
### 5.1 Jinja2 settings
| Setting | Value | Reason |
|---|---|---|
| `undefined` | `StrictUndefined` | A misspelled variable stops the run instead of writing empty SCL |
| `trim_blocks`, `lstrip_blocks` | `True` | `{% for %}` lines leave no blank lines/indent in the SCL |
| `keep_trailing_newline` | `True` | Stable files, clean diffs |
| `autoescape` | `False` | SCL, not HTML |
SCL syntax does not clash with Jinja2: SCL uses `#name`, `{ S7_... }` and `//`, never
`{{`, `{%` or `{#`. The one thing to avoid is writing `{#` directly (e.g. `{#TRO…`).
### 5.2 Shared macros (`_macros.scl.j2`)
One macro per repeated block. Each takes the TRO context and the block's own data:
```jinja
{% macro separator(t, s) %}
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.nSeparatorNo := "{{ s.no }}";{{ s.no_note }}
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.tTrailingTime := {{ d.sep_trailing }}; // {{ TODO }}: pruefen
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.tHandlingTime := {{ d.sep_handling }}; // {{ TODO }}: pruefen
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.tJam := "TimeForSepJam";
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.xPluggedJam := TRUE;
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.xPluggedPart := FALSE;
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.xPluggedScanner := {{ 'TRUE' if t.has_scanner else 'FALSE' }};
#{{ t.id }}.stInSeparator{{ s.n }}.stSenInSep := "DB_Inputs".Sensors["{{ s.sensor }}"];{{ s.sensor_note }}
{% endmacro %}
{% macro jam(kind, j) %}
arInOutJam{{ kind }}{{ j.n }} := {{ j.db }}.arCarrier, // {{ j.note }}
stInOutJam{{ kind }}{{ j.n }} := {{ j.db }}.stData,
{% endmacro %}
```
`s.no` is either a resolved name (`cSep107.1`) or the placeholder `cSep_____`, and
`s.no_note` is then ` // TODO(E-Planung)` or empty. Python decides both (§7.3); the
template only places them.
### 5.3 One template per FB
Each FB template is the reference call site with values replaced by variables and
repeated parts replaced by loops. Sketch for `FB_ILS_MTRO_1Sep1Swi.scl.j2`:
```jinja
{% import "_macros.scl.j2" as m %}
REGION {{ t.region_title }}
{{ m.comments(t) }}
{% for s in t.separators %}{{ m.separator(t, s) }}{% endfor %}
{% for w in t.switches %}{{ m.switch(t, w) }}{% endfor %}
#{{ t.id }}.stInSettings.xPrioDir2 := {{ t.prio_dir2 }};{{ t.prio_dir2_note }}
#{{ t.id }}(stInPriorityManagerDir2 := "DB_Prozessdaten".stPriorityManager.udt_{{ t.id }}.TroIn,
stOutPriorityManagerDir2 => "DB_Prozessdaten".stPriorityManager.udt_{{ t.id }}.TroOut,
nInMainTroNo := "{{ t.main_tro }}",{{ t.main_tro_note }}
xInSftyOk := {{ t.safety }},{{ t.safety_note }}
xInAllRdyToStart := TRUE,
{% if t.carousel_run %}
xInCarouselRun1 := {{ t.carousel_run }},
{% endif %}
xInRelease := {{ t.release }},
...
{% for j in t.jam_entries %}{{ m.jam("Entr", j) }}{% endfor %}
{% for j in t.jam_exits %}{{ m.jam("Exit", j) }}{% endfor %}
stInOutHMI := "DB_Interface_HMI".stTRO.{{ t.id }},
nOutStateLast => "DB_GLOB_TroState".arTroState["{{ t.main_tro }}"],
{% for s in t.separators %}
xOutStopper{{ s.n }} => "{{ s.stopper }}"{{ "," if not loop.last or t.switches else ");" }}{{ s.stopper_note }}
{% endfor %}
...);
{{ m.direction(t) }}
END_REGION
```
The order of the lines in the template **is** the parameter order of the reference call
site. That replaces the order that is hard-coded in `emit_call` today.
### 5.4 File frame and whitespace
The file header (source, timestamp, start reason, open-TODO note), `FUNCTION_BLOCK
"FB_Main"`, the `VAR` list of all instances and the REGION loop are written by
`render_context` in Python. Each REGION is rendered from the TRO's own template and
inserted there; TROs without a template get the generic text (§9). With `--templates`
the header names which FB types came from a template and which did not.
Templates do **not** use Jinja whitespace control (`{%- … -%}`) except inside the
one-line macros `todo`/`note`. Instead the renderer drops trailing blanks and collapses
runs of blank lines (`SclTemplates.render`). That keeps the templates readable as SCL and
the indentation intact.
Rule for every template: **each line that contains a placeholder carries the
`TODO(E-Planung)` marker** — also the second line of a pair such as
`stInOutJamExit<n> … .stData`. `tests/test_scl_templates.py` checks this.
---
## 6. Where each value comes from
Every line in a template belongs to exactly one of these classes. The class decides who
supplies the value and what happens when it is missing.
| Class | Source | Example | If missing |
|---|---|---|---|
| **L — layout** | TRO-JSON (`TroDocument`) | `#TRO107`, number of separators/switches, jam entries/exits per neighbour, destination list per switch exit, `nTo1Destinations` (single switch) | cannot be missing — the JSON is validated |
| **N — naming rule** | naming config (§7) | `cSep107.1`, `cSwi107.1`, `cMainTro107`, `udt_TRO107` | `TODO(E-Planung)` placeholder |
| **R — reference default** | the reference call site, written in the template or in `[defaults]` | `tTrailingTime t#100ms`, `tJam "TimeForSepJam"`, `xPluggedJam TRUE` | always present; marked `pruefen` where plant-specific |
| **E — E-Planung** | I/O list (not available yet) | `cInBG3306`, `MB3306`, `MA…`, safety zone, `DB_JamArea0102.stJam0102_1` | `TODO(E-Planung)` placeholder |
| **C — condition** | topology flag in the context | `xInCarouselRun1` only next to a carousel; `stInSenJam2/3` only with extra jam sensors | line left out, or written as a TODO |
Class **C** is the real design work, not the conversion. Each reference call site is one
concrete location and contains lines that only exist because of that location. They have
to be decided once per template, together with a PLC engineer, and recorded in the
template as a comment. For the pilot `1Sep1Swi` (TRO107):
| Line in reference | Implemented in the pilot | Context field | Status |
|---|---|---|---|
| `stInSenJam2`, `stInSenJam3` | one per jam exit, sensor `TODO(E-Planung)` | `jam_exits[].sensor` | to confirm |
| `stInSettings.xPrioDir2 := TRUE` | written as `TRUE`, marked `TODO(E-Planung)` (priority is a planning decision) | `prio_dir2` | to confirm |
| `stIn/OutPriorityManagerDir2` | always; UDT `udt_____` + TODO until the naming rule `udt_{id}` (step 4) | `priority_udt` | to confirm |
| `xInCarouselRun1 := #fbCarousel0102.xOutConveyorFullSpeed` | **always written, marked TODO "nur am Kreisel, sonst Zeile loeschen"**. The proposed condition (a connection of kind `umlauf`) does not work: `tro_flow` emits `bahn`/`normal`/`weiche`/`transfer` in practice, `umlauf` never occurs in mubea or HundM05, so the TRO-JSON cannot tell whether a TRO sits at a carousel. Needs either a carousel flag from `tro_flow` or a manual decision. | `carousel_run` | to confirm |
| `xInRelease := TRUE` (generic: `"DB_TRO_TEST".<id>`) | reference value `TRUE` | — (literal) | to confirm |
| `stInOutMachineState := #stInOutControlUnitCabinetOF1` | placeholder `#stInOutControlUnitCabinet` + TODO (cabinet is plant-specific) | `machine_state` | to confirm |
| separator times `t#100ms` / `t#50ms` | reference values, marked `pruefen`; `tSenFree`/`tSenWait` of the generic path are **not** written (not in the reference) | — (literal) | to confirm |
| `nTo1Destinations := 3` (TRO107 has **2** exits) | number of exits, marked `pruefen` — the reference suggests it counts destinations, not exits (§13) | `switches[].to1_destinations` | open |
| `stInPriorityManager.xReleaseOk` (generic only) | not written — not in the reference | — | to confirm |
The same table is filled in for every template before it is switched on (§11, step 3).
Effect on the open-value count with `--templates`: mubea 282 → 302, HundM05 323 → 377
`TODO(E-Planung)`. More reference lines are written and every open value is now marked;
it drops again with the naming rules (step 4).
---
## 7. Naming config
### 7.1 Purpose
Some names follow a rule in a given plant (`cSep107.1` = separator 1 of TRO 107). Others
do not (`cInBG3306` is whatever E-Planung assigned). The naming config holds the rules,
so that:
- rule-based names are generated instead of left as TODOs,
- a project with a different naming scheme changes a file, not code,
- anything without a rule stays `TODO(E-Planung)`, exactly as today.
### 7.2 File and lookup
INI, like `connect.ini` and the other files in `%SKEL_CFG%`. Lookup order (later wins):
1. `%SKEL_CFG%/scl_naming.ini` — defaults taken from the reference plant
2. `%SKEL_CFG%/<name>_scl_naming.ini` — per project, `<name>` = stem of the TRO-JSON
(`mubea_tro.json` → `mubea_scl_naming.ini`)
3. `--naming FILE` — explicit file
A key that is **absent or empty** in all of them means "no rule" → placeholder +
`TODO(E-Planung)`.
### 7.3 Syntax
```ini
; scl_naming.ini - Namensregeln fuer das FB_Main-Geruest
; Platzhalter: {id} TRO-ID (TRO107), {nr} Nummernteil (107), {n} laufende Nummer
; des Bauteils im TRO (1, 2 ...), {sep} Separatornummer aus dem Layout
[names]
separator_no = cSep{nr}.{n}
switch_no = cSwi{nr}.{n}
main_tro = cMainTro{nr}
priority_udt = udt_{id}
; ohne Regel -> TODO(E-Planung)
sensor_sep =
stopper =
switch_valve =
safety =
jam_area =
[defaults]
sep_trailing = t#100ms
sep_handling = t#50ms
release = TRUE
```
- `{nr}` is the numeric part of the ID **as written** in the JSON (`TRO01` → `01`,
`TRO107` → `107`); padding is not changed.
- `{sep}` is the separator's layout number from `separators[]` (`0040`) — useful if a
project names separators after the layout instead of the TRO.
- An unknown placeholder in a rule is an error (exit 1), not a silent literal.
### 7.4 Later: E-Planung data
When an I/O list exists in machine-readable form, a further section can point to it
(e.g. `[eplanung] file = …csv`) and fill class **E** values per separator/switch. That is
a separate step; the config format leaves room for it but this concept does not build it.
---
## 8. Tests
All under `tests/`, run with `python -m pytest tests/` like the existing ones.
### 8.1 Round trip per template (the main safety net)
For each template that has a reference call site (`tests/test_scl_templates.py`):
1. The test builds the context for a TRO with the reference topology and sets the
**real** values of the reference (ID `TRO107`, `cSep107.1`, `cInBG3306`, `MB3306`, the
real jam DBs, `carousel_run` …).
2. The test renders the template with that context.
3. It compares the result with the `REGION … END_REGION` part of the reference file,
**normalised**: whitespace collapsed, comments removed, case kept.
If they match, the parameterisation lost nothing: same lines, same order, same values.
When someone later replaces a reference file with a newer call site, this test shows
exactly where the template must follow.
### 8.2 Interface check (for FBs with source)
For `Vario_workStation`, `2Sep1Swi`, `EmptyCarrBuffer`, `LoadingBoom`: parse
`VAR_INPUT`/`VAR_OUTPUT`/`VAR_IN_OUT` of the FB source and check that every parameter
name the template writes exists there, with the right direction (`:=` for in/in-out,
`=>` for out). This covers the types that have no call site.
### 8.3 Golden files for the whole output
`tests/test_scl_skeleton_golden.py` renders `mubea_tro.json` and `HundM05_tro.json`
(copied into `tests/fixtures/`) and compares with checked-in expected SCL, with the
timestamp line masked.
- **During migration:** the golden files are today's output, so switching the
generator internals without enabling templates must give byte-identical files.
- **When a template is switched on:** the diff in the golden file is reviewed once
(it is the intended change) and then committed as the new golden file.
### 8.4 Naming and context
Unit tests for `scl_naming.py` (placeholders, lookup order, empty = TODO, unknown
placeholder = error) and `scl_context.py` (jam numbering, destination lists, flags such
as `carousel_run` from connection kinds).
---
## 9. Fallback and errors
| Situation | Behaviour | Exit |
|---|---|---|
| Template exists for the TRO's `fbType` | render template | 0 |
| No template (e.g. `2Sep2Swi`) | render with the current `emit_*` code; header lines `// Aus Template : …` / `// Generisch : … (kein Template - von Hand pruefen)` and an entry in the console summary | 0 |
| No template **and** `--strict` | stop, write nothing | 1 |
| Template uses an undefined variable / syntax error | stop, write nothing, show template file and line | 1 |
| Naming rule with unknown placeholder | stop, write nothing | 1 |
| Invalid TRO-JSON | unchanged from today | 1 |
With `--templates` the console summary gets a `Templates` line (implemented); the
`Namensregeln` line follows with step 4. Real output for mubea today:
```
Templates = 1 von 5 Typen (generisch: FB_ILS_MTRO_1Sep, FB_ILS_MTRO_2Sep2Swi, FB_ILS_MTRO_PinStore_Auto, FB_ILS_MTRO_Vario)
Offene Stellen = 302 (Marker 'TODO(E-Planung)')
```
---
## 10. CLI — additive only
Existing switches (`--json`, `--out`, `--start`) and defaults are unchanged.
| New switch | Argument | Default | Effect | Status |
|---|---|---|---|---|
| `--templates` | `[DIR]` (optional) | off; without `DIR`: `lib/scl_templates` | Render REGIONs from the FB templates; types without template stay generic | ✅ |
| `--strict` | — | off | With `--templates`: exit 1, write nothing, if any FB type of the plant has no template | ✅ |
| `--naming` | `FILE` | lookup per §7.2 | Explicit naming config | step 4 |
Templates are **opt-in** (`--templates`) until step 6. Without the switch the output is
byte-identical to before (golden files). When templates become the default in step 6, a
`--no-templates` switch keeps the old path for one release.
---
## 11. Migration plan
Each step ends with all tests green and is usable on its own.
| Step | Work | Done when |
|---|---|---|
| 1 ✅ | Golden-file tests on today's output (mubea, HundM05) — `tests/test_scl_skeleton_golden.py` | today's SCL is pinned |
| 2 ✅ | `scl_context.py`: build the render context from `TroDocument`; `emit_*` read from it — `tests/test_scl_context.py` | golden files byte-identical (also checked on dematic and showroom, with and without `--start`) |
| 3 ✅ | Pilot `FB_ILS_MTRO_1Sep1Swi.scl.j2` + `_macros`; switches `--templates`, `--strict`; class-C table (§6) filled with proposals — **still to be confirmed by a PLC engineer**; round-trip test | round trip against TRO107 passes; only the 1Sep1Swi REGIONs (+ header) differ from the generic golden files |
| 4 | `scl_naming.py` + `cfg/scl_naming.ini`; switch `--naming` | naming tests pass; Mubea renders with names instead of TODOs where a rule exists |
| 5 | Remaining call-site templates one by one (`1Sep`, `Vario`, `1Sep2Swi`, `1Sep_SSCC`, `Vario_workStation`, `PinStore_Auto`), each with round trip; interface check for the FB-source types | each type moved off the fallback |
| 6 | Templates on by default; new `--no-templates` keeps the old path for one release | golden files updated and reviewed; one import into TIA Portal (as for Mubea) |
| 7 | Remove `emit_*` once every type in use has a template (`2Sep2Swi` needs a call site first) | fallback only for types without FB |
Docs touched along the way: `doc/Python_Scripts.md` §5b, `doc/Commandlines.md` §2.5,
`CLAUDE.md` (roadmap), this file.
---
## 12. What your workflow can rely on
For a workflow that runs **export CSV → SCL**:
**Calls (unchanged):**
```bat
bin\tro_flow.bat --file <name>.csv --json
bin\scl_skeleton.bat --json <name>_tro.json [--templates [DIR]] [--strict] [--naming <file>]
```
`--templates` and `--strict` exist today; `--naming` follows with step 4.
**Inputs:**
| File | Where | Who writes it |
|---|---|---|
| `<name>.csv` | `%SKEL_DATA%` | dxfmakros `EXPORTCSV` |
| `<name>_tro.json` | `%SKEL_RESULTS%` | `tro_flow --json` (schema `sps_skel-tro-v2`) |
| `scl_naming.ini`, `<name>_scl_naming.ini` | `%SKEL_CFG%` | you, once per project (optional) |
| `lib/scl_templates/*.scl.j2` | repo | maintained with the PLC engineers |
**Outputs:** `%SKEL_RESULTS%/<name>_FB_Main.scl` (same name as today).
**Exit codes:** `0` ok (also when some TROs used the fallback) · `1` input, template or
naming error, or a missing template with `--strict`. `tro_flow` keeps its own codes (`3`
= TRO validation errors → stop the workflow before `scl_skeleton`).
**Quality gates a workflow can check:**
- exit code of each step;
- `Offene Stellen` in the summary (count of `TODO(E-Planung)`), e.g. track it per run;
- `Templates = x von y` — any TRO on the fallback needs a manual look;
- `grep "TODO(E-Planung)"` in the SCL lists every open value with its line.
**What stays manual:** class **E** values (sensor/actuator addresses, safety signals,
jam-area DBs) until an E-Planung export exists, and the `pruefen` timings.
---
## 13. Open questions (to clarify with the PLC engineers)
1. The class-C decisions per template (§6) — starting with `1Sep1Swi`.
2. Is the reference naming (`cSep{nr}.{n}`, `cMainTro{nr}`, `udt_{id}`) the standard for
new projects, or plant-specific?
3. Separator timings: reference values (100/50 ms) or the current skeleton values
(600/200 ms) as the default?
4. `xInRelease`: `TRUE` as in the reference, or the `"DB_TRO_TEST"` test release used today?
5. Real call sites for `2Sep1Swi`, `EmptyCarrBuffer`, `LoadingBoom` — available from
another plant?
6. `FB_ILS_MTRO_2Sep2Swi` (Mubea): will it be created in the ILSLib, or should the two
transfer points be modelled with existing types?
7. `nTo1Destinations`: TRO107 has 2 exits but the value 3 ("Info noetig fuer HMI"). Does
it count the destinations behind the switch rather than its exits? If so, which
destinations — the per-exit target lists in the skeleton could supply them.
8. `xInCarouselRun1`: how do we know a TRO sits at a carousel? `tro_flow` would need to
mark it (e.g. a carousel neighbour per TRO); today the line is always written as TODO.
+383
View File
@@ -0,0 +1,383 @@
# -*- coding: utf-8 -*-
"""
scl_context.py - Render-Kontext fuer das FB_Main-Geruest.
Schritt 2 aus doc/SCL_Templates.md: alles, was scl_skeleton aus der TRO-JSON
*ableitet*, steht hier - Reihenfolge, Bauteilbloecke, Staubereiche,
Weichenziele, Namen. Die Ausgabe (heute die emit_*-Funktionen, spaeter die
Templates in lib/scl_templates/) liest nur noch diesen Kontext und rechnet
nichts mehr selbst.
Schichten:
model.py TroDocument (die TRO-JSON)
scl_context.py TroDocument -> SclFile <- hier
scl_skeleton.py SclFile -> SCL-Text
Namen (Separator-, Weichen-, MainTro-Nummer, Adressen ...) sind ein
:class:`SclName`: Wert plus Merker, ob er noch aus der E-Planung kommen muss.
Heute sind alle Platzhalter mit ``todo=True``; die Namensregeln aus Schritt 4
(cfg/scl_naming.ini) ersetzen dann nur den Wert und loeschen den Merker.
"""
from __future__ import annotations
import re
from collections import deque
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
from model import TroBase, TroDocument
from tro_catalog import TroItem
__all__ = [
"TODO",
"SclName",
"SclSeparator",
"SclSwitch",
"SclSwitchExit",
"SclScanner",
"SclJam",
"SclTro",
"SclFile",
"build_context",
"flow_order",
"reachable_via",
]
TODO = "TODO(E-Planung)"
_CONFIG = ConfigDict(extra="forbid")
class SclName(BaseModel):
"""Ein Name/eine Adresse in der SCL und ob er noch offen ist."""
model_config = _CONFIG
value: str
# True: Platzhalter, muss aus der E-Planung kommen -> TODO-Kommentar
todo: bool = True
def _offen(platzhalter: str) -> SclName:
return SclName(value=platzhalter, todo=True)
class SclSeparator(BaseModel):
"""Ein stInSeparator<n>-Block."""
model_config = _CONFIG
n: int
# Separatornummer aus dem Layout ("?" wenn der Typ mehr Separatoren hat
# als im Layout gefunden wurden)
layout: str
no: SclName
sensor: SclName
stopper: SclName
class SclSwitchExit(BaseModel):
"""Ein Abgang eines Weichen-TRO und die darueber erreichbaren TROs."""
model_config = _CONFIG
via: str
targets: list[str]
class SclSwitch(BaseModel):
"""Ein stInSwitch<n>-Block plus sein FC_Direction-Aufruf."""
model_config = _CONFIG
n: int
no: SclName
valve: SclName
# None: mehrere Weichen teilen sich die Abgaenge - Aufteilung ist eine
# Planungsentscheidung und wird nicht geraten
to1_destinations: int | None
# Ziel von nOutDirection, z. B. "#TRO07.nInDirection" bzw. "...nInDirection2"
direction_target: str
# Staubereich, dessen erster Traeger in FC_Direction ausgewertet wird
jam_db: SclName
class SclScanner(BaseModel):
"""Ein stInBarcodeReader-Block ("" als Suffix, wenn es nur einen gibt)."""
model_config = _CONFIG
n: int
suffix: str
class SclJam(BaseModel):
"""Ein Staubereich am Ein- oder Ausgang (JamEntr<n> / JamExit<n>)."""
model_config = _CONFIG
n: int
# Nachbar als Text fuer den Kommentar, SYSn als Station markiert
neighbour: str
db: SclName
# Stausensor des Ausgangs (stInSenJam<n>); None an Eingaengen
sensor: SclName | None = None
class SclTro(BaseModel):
"""Alles, was eine REGION fuer einen TRO braucht."""
model_config = _CONFIG
id: str
# Nummernteil der ID, wie geschrieben ("TRO01" -> "01"); "" ohne Ziffern
nr: str
type: str
fb: str
region_title: str
layout_separators: list[str]
position: tuple[float, float] | None
predecessors: list[str]
successors: list[str]
confidence: str
separators: list[SclSeparator]
switches: list[SclSwitch]
switch_exits: list[SclSwitchExit]
has_vario: bool
# Vario-Sensoren in Aufrufreihenfolge (Parametername -> Sensor); leer ohne Vario
vario_sensors: dict[str, SclName]
scanners: list[SclScanner]
storage_lines: int
jam_entries: list[SclJam]
jam_exits: list[SclJam]
main_tro: SclName
safety: SclName
release: str
motor_protection: SclName
vario_motor: SclName
machine_state: SclName
# Nur in den Templates (Referenz-Aufrufstellen), nicht im generischen Aufbau:
# UDT des Prioritaetsmanagers ("udt_TRO107") und ob Richtung 2 Vorrang hat
priority_udt: SclName
prio_dir2: SclName
# Kreisel-Freigabe (xInCarouselRun1). Ob ein TRO am Kreisel liegt, steht
# nicht in der TRO-JSON - deshalb immer offen (doc/SCL_Templates.md §6).
carousel_run: SclName
@property
def has_scanner(self) -> bool:
return bool(self.scanners)
class SclFile(BaseModel):
"""Kontext der ganzen Datei: Kopf und die TROs in Fliessrichtung."""
model_config = _CONFIG
source: str
created: str
start_reason: str
tros: list[SclTro] = Field(default_factory=list)
# ---------------------------------------------------------------------------
# Graph
# ---------------------------------------------------------------------------
def flow_order(tros: list[TroBase], start_id: str = "") -> tuple[list[TroBase], str]:
"""TROs in Fliessrichtung sortieren.
Startpunkt ist ein TRO ohne Vorgaenger - also die Stelle, an der Material
in die Anlage kommt. Solange Be-/Entladestation fehlen, ist der Fluss ein
geschlossener Kreis und es gibt keinen solchen TRO; dann muss der Kreis
irgendwo aufgetrennt werden. Das ist eine willkuerliche Wahl, deshalb wird
sie zurueckgegeben und im Kopf der SCL vermerkt (und laesst sich mit
--start ueberschreiben). Nicht erreichte TROs haengt die Funktion hinten
an, damit nie einer verlorengeht.
"""
nach_id = {t.tro_id: t for t in tros}
ohne_vorgaenger = sorted(t.tro_id for t in tros if not t.predecessors)
# Materialeingang ueber eine Station (SYSn von tro_flow.py): der TRO, den
# sie speist, ist der natuerliche Anfang - auch wenn er zusaetzlich einen
# TRO-Vorgaenger hat (Kreisel-Umlauf).
eingaenge = sorted({
t.tro_id for t in tros
for vor in t.predecessors if vor not in nach_id
})
if start_id and start_id in nach_id:
start, grund = [start_id], "per --start gesetzt"
elif ohne_vorgaenger:
start, grund = ohne_vorgaenger, "TRO ohne Vorgaenger (Materialeingang)"
elif eingaenge:
stationen = sorted({
vor for i in eingaenge for vor in nach_id[i].predecessors
if vor not in nach_id
})
start = eingaenge
grund = f"Materialeingang ueber {', '.join(stationen)}"
else:
start = [min(nach_id)]
grund = ("Kreislauf ohne Eingang - willkuerlich aufgetrennt; sobald "
"Be-/Entladestation im Export stehen, ergibt sich der Anfang")
gesehen: list[str] = []
queue = deque(start)
while queue:
tro_id = queue.popleft()
if tro_id in gesehen:
continue
gesehen.append(tro_id)
for nxt in nach_id[tro_id].successors if tro_id in nach_id else []:
# SYSn (Materialausgang) ist kein TRO - keine REGION, keine Instanz.
if nxt in nach_id and nxt not in gesehen:
queue.append(nxt)
for tro_id in sorted(nach_id):
if tro_id not in gesehen:
gesehen.append(tro_id)
return [nach_id[i] for i in gesehen], grund
def reachable_via(start: str, first: str, tros: dict[str, TroBase]) -> list[str]:
"""Welche TROs sind ueber diesen Abgang erreichbar?
Das ist die Zielliste eines Weichenabgangs: von `first` aus weiterlaufen,
ohne ueber die Weiche selbst zurueckzugehen. Genau die Information, die
FC_Direction braucht, um zu entscheiden - und sie steht im Graphen.
"""
gesehen: set[str] = set()
queue = deque([first])
while queue:
node = queue.popleft()
if node in gesehen or node == start:
continue
gesehen.add(node)
if node in tros:
queue.extend(tros[node].successors)
return sorted(gesehen)
def _nachbar(node: str, alle: dict[str, TroBase]) -> str:
"""Nachbar fuer Kommentare; SYSn als Station kenntlich machen."""
return node if node in alle else f"{node} (Station, kein TRO)"
def _region_title(tro: TroBase) -> str:
seps = ", ".join(tro.separators)
teile = f" Sep {seps}" if seps else ""
return f"{tro.tro_id} ({tro.type_name}){teile}"
def _nummer(tro_id: str) -> str:
treffer = re.search(r"(\d+)$", tro_id)
return treffer.group(1) if treffer else ""
# ---------------------------------------------------------------------------
# Kontext bauen
# ---------------------------------------------------------------------------
def _tro_context(tro: TroBase, alle: dict[str, TroBase]) -> SclTro:
items = tro.items
n_sep = items.get(TroItem.SEPARATOR, 1)
n_swi = items.get(TroItem.SWITCH, 0)
n_scan = items.get(TroItem.SCANNER, 0)
tro_id = tro.tro_id
jam_db = '"DB_JamArea____".stJam____'
separators = [
SclSeparator(
n=i,
layout=tro.separators[i - 1] if i <= len(tro.separators) else "?",
no=_offen("cSep_____"),
sensor=_offen("cInBG____"),
stopper=_offen("MB____"),
)
for i in range(1, n_sep + 1)
]
switches = [
SclSwitch(
n=j,
no=_offen("cSwi_____"),
valve=_offen("MB____"),
# Eine Weiche bedient alle Abgaenge - direkt ableitbar.
to1_destinations=len(tro.successors) if n_swi == 1 else None,
direction_target=(f"#{tro_id}.nInDirection" if n_swi == 1
else f"#{tro_id}.nInDirection{j}"),
jam_db=_offen(jam_db),
)
for j in range(1, n_swi + 1)
]
has_vario = bool(items.get(TroItem.VARIO_DRIVE))
vario_sensors = {
name: _offen("cInBG____")
for name in ("stSenCarrInPos", "stSenFinger", "stSenLastPos", "stSenJam")
} if has_vario else {}
switch_exits = [
SclSwitchExit(via=abgang, targets=reachable_via(tro_id, abgang, alle))
for abgang in tro.successors
] if n_swi else []
return SclTro(
id=tro_id,
nr=_nummer(tro_id),
type=tro.type_name,
fb=tro.fb_block or "FB_UNBEKANNT",
region_title=_region_title(tro),
layout_separators=list(tro.separators),
position=(tro.x, tro.y) if tro.position else None,
predecessors=list(tro.predecessors),
successors=list(tro.successors),
confidence=tro.confidence,
separators=separators,
switches=switches,
switch_exits=switch_exits,
has_vario=has_vario,
vario_sensors=vario_sensors,
scanners=[
SclScanner(n=i, suffix="" if n_scan == 1 else str(i))
for i in range(1, n_scan + 1)
],
storage_lines=items.get(TroItem.STORAGE_LINE, 0),
# Staubereiche: je ankommender/abgehender Verbindung einer. Welche
# DB-Struktur dahintersteht, ist eine Planungsentscheidung - hier steht
# nur, WIE VIELE es sein muessen und zu welchem Nachbarn sie gehoeren.
jam_entries=[
SclJam(n=n, neighbour=_nachbar(vor, alle), db=_offen(jam_db))
for n, vor in enumerate(tro.predecessors, start=1)
],
jam_exits=[
SclJam(n=n, neighbour=_nachbar(nach, alle), db=_offen(jam_db),
sensor=_offen("cInBG____"))
for n, nach in enumerate(tro.successors, start=2)
],
main_tro=_offen("cMainTro____"),
safety=_offen('"DB_InterfaceSafety".stFromSafety.EStopMain.Q'),
release=f'"DB_TRO_TEST".{tro_id}',
motor_protection=_offen('"FC____"'),
vario_motor=_offen("MA____"),
# Schaltschrank ist anlagenspezifisch ("...OF1" in der Referenz)
machine_state=_offen("#stInOutControlUnitCabinet"),
priority_udt=_offen("udt_____"),
# Vorschlag aus der Referenz TRO107, Prioritaet bleibt Planungsentscheidung
prio_dir2=_offen("TRUE"),
carousel_run=_offen("#fbCarousel____.xOutConveyorFullSpeed"),
)
def build_context(document: TroDocument, source: str, start_id: str = "",
created: str | None = None) -> SclFile:
"""TroDocument -> SclFile (TROs in Fliessrichtung)."""
alle = {t.tro_id: t for t in document.tros}
geordnet, startgrund = flow_order(document.tros, start_id)
return SclFile(
source=source,
created=created or datetime.now().strftime("%Y-%m-%d %H:%M"),
start_reason=startgrund,
tros=[_tro_context(t, alle) for t in geordnet],
)
+242 -211
View File
@@ -40,17 +40,60 @@ from __future__ import annotations
import argparse
import json
import sys
from collections import deque
from datetime import datetime
from pathlib import Path
from jinja2 import (
Environment,
FileSystemLoader,
StrictUndefined,
TemplateError,
TemplateNotFound,
)
from pydantic import ValidationError
from material_flow import env_dir
from model import SCHEMA, TroBase, TroDocument
from tro_catalog import TroItem
from model import SCHEMA, TroDocument
from scl_context import TODO, SclFile, SclName, SclTro, build_context
TODO = "TODO(E-Planung)"
# Parametrisierte Aufrufstellen je FB (doc/SCL_Templates.md); Dateiname = fbType.
TEMPLATE_DIR = Path(__file__).resolve().parent / "scl_templates"
TEMPLATE_SUFFIX = ".scl.j2"
class SclTemplates:
"""Die FB-Templates eines Ordners; ohne Template -> generischer Aufbau."""
def __init__(self, folder: Path) -> None:
self.folder = folder
self.env = Environment(
loader=FileSystemLoader(str(folder)),
# Tippfehler im Template -> Fehler statt leerer SCL-Stelle
undefined=StrictUndefined,
trim_blocks=True,
lstrip_blocks=True,
keep_trailing_newline=True,
autoescape=False,
)
self.env.globals["TODO"] = TODO
def has(self, fb: str) -> bool:
return (self.folder / f"{fb}{TEMPLATE_SUFFIX}").is_file()
def render(self, tro: SclTro) -> str:
"""REGION eines TRO aus seinem Template (ohne abschliessenden Umbruch)."""
try:
template = self.env.get_template(f"{tro.fb}{TEMPLATE_SUFFIX}")
except TemplateNotFound as exc:
raise TemplateError(f"Template fuer {tro.fb} fehlt: {exc}") from exc
# Leerzeilen hier zusammenfassen statt im Template mit Whitespace-
# Steuerung ({%- ... -%}) - die macht Templates schwer lesbar und
# bricht leicht die Einrueckung.
zeilen: list[str] = []
for zeile in template.render(t=tro).split("\n"):
zeile = zeile.rstrip()
if zeile or (zeilen and zeilen[-1]):
zeilen.append(zeile)
return "\n".join(zeilen).strip("\n")
# Zeitwerte aus den Referenz-Aufrufstellen. Sie sind plausible Startwerte, KEINE
# fuer diese Anlage ermittelten - deshalb ueberall mit Pruefhinweis.
@@ -67,140 +110,58 @@ def load_document(path: Path) -> TroDocument:
return TroDocument.from_json(path.read_text(encoding="utf-8"))
def flow_order(tros: list[TroBase], start_id: str = "") -> tuple[list[TroBase], str]:
"""TROs in Fliessrichtung sortieren.
Startpunkt ist ein TRO ohne Vorgaenger - also die Stelle, an der Material
in die Anlage kommt. Solange Be-/Entladestation fehlen, ist der Fluss ein
geschlossener Kreis und es gibt keinen solchen TRO; dann muss der Kreis
irgendwo aufgetrennt werden. Das ist eine willkuerliche Wahl, deshalb wird
sie zurueckgegeben und im Kopf der SCL vermerkt (und laesst sich mit
--start ueberschreiben). Nicht erreichte TROs haengt die Funktion hinten
an, damit nie einer verlorengeht.
"""
nach_id = {t.tro_id: t for t in tros}
ohne_vorgaenger = sorted(t.tro_id for t in tros if not t.predecessors)
# Materialeingang ueber eine Station (SYSn von tro_flow.py): der TRO, den
# sie speist, ist der natuerliche Anfang - auch wenn er zusaetzlich einen
# TRO-Vorgaenger hat (Kreisel-Umlauf).
eingaenge = sorted({
t.tro_id for t in tros
for vor in t.predecessors if vor not in nach_id
})
if start_id and start_id in nach_id:
start, grund = [start_id], "per --start gesetzt"
elif ohne_vorgaenger:
start, grund = ohne_vorgaenger, "TRO ohne Vorgaenger (Materialeingang)"
elif eingaenge:
stationen = sorted({
vor for i in eingaenge for vor in nach_id[i].predecessors
if vor not in nach_id
})
start = eingaenge
grund = f"Materialeingang ueber {', '.join(stationen)}"
else:
start = [min(nach_id)]
grund = ("Kreislauf ohne Eingang - willkuerlich aufgetrennt; sobald "
"Be-/Entladestation im Export stehen, ergibt sich der Anfang")
gesehen: list[str] = []
queue = deque(start)
while queue:
tro_id = queue.popleft()
if tro_id in gesehen:
continue
gesehen.append(tro_id)
for nxt in nach_id[tro_id].successors if tro_id in nach_id else []:
# SYSn (Materialausgang) ist kein TRO - keine REGION, keine Instanz.
if nxt in nach_id and nxt not in gesehen:
queue.append(nxt)
for tro_id in sorted(nach_id):
if tro_id not in gesehen:
gesehen.append(tro_id)
return [nach_id[i] for i in gesehen], grund
def _todo(name: SclName, abstand: str) -> str:
"""TODO-Kommentar hinter einer Zeile, wenn der Name noch offen ist."""
return f"{abstand}// {TODO}" if name.todo else ""
def reachable_via(start: str, first: str, tros: dict[str, TroBase]) -> list[str]:
"""Welche TROs sind ueber diesen Abgang erreichbar?
Das ist die Zielliste eines Weichenabgangs: von `first` aus weiterlaufen,
ohne ueber die Weiche selbst zurueckzugehen. Genau die Information, die
FC_Direction braucht, um zu entscheiden - und sie steht im Graphen.
"""
gesehen: set[str] = set()
queue = deque([first])
while queue:
node = queue.popleft()
if node in gesehen or node == start:
continue
gesehen.add(node)
if node in tros:
queue.extend(tros[node].successors)
return sorted(gesehen)
def nachbar(node: str, alle: dict[str, TroBase]) -> str:
"""Nachbar fuer Kommentare; SYSn als Station kenntlich machen."""
return node if node in alle else f"{node} (Station, kein TRO)"
def region_title(tro: TroBase) -> str:
seps = ", ".join(tro.separators)
teile = f" Sep {seps}" if seps else ""
return f"{tro.tro_id} ({tro.type_name}){teile}"
def emit_separators(add, tro: TroBase, anzahl: int, hat_scanner: bool) -> None:
seps = tro.separators
for i in range(1, anzahl + 1):
pfad = f"#{tro.tro_id}.stInSeparator{i}"
layout = seps[i - 1] if i <= len(seps) else "?"
add(f" // Separator {i} = Bauteil {layout} aus dem Layout")
add(f' {pfad}.Settings.nSeparatorNo := "cSep_____"; // {TODO}')
def emit_separators(add, tro: SclTro) -> None:
for s in tro.separators:
pfad = f"#{tro.id}.stInSeparator{s.n}"
add(f" // Separator {s.n} = Bauteil {s.layout} aus dem Layout")
add(f' {pfad}.Settings.nSeparatorNo := "{s.no.value}";{_todo(s.no, " ")}')
for name, wert, hinweis in DEFAULT_SEP_TIMES:
kommentar = f" // {TODO}: {hinweis}" if hinweis else ""
add(f" {pfad}.Settings.{name} := {wert};{kommentar}")
add(f" {pfad}.Settings.xPluggedJam := TRUE;")
add(f" {pfad}.Settings.xPluggedPart := FALSE;")
add(f" {pfad}.Settings.xPluggedScanner := "
f"{'TRUE' if hat_scanner else 'FALSE'};")
add(f' {pfad}.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // {TODO}')
f"{'TRUE' if tro.has_scanner else 'FALSE'};")
add(f' {pfad}.stSenInSep := "DB_Inputs".Sensors["{s.sensor.value}"];'
f'{_todo(s.sensor, " ")}')
add(f" {pfad}.Settings.tSenFree := T#1500ms; // {TODO}: pruefen")
add(f" {pfad}.Settings.tSenWait := T#4000ms; // {TODO}: pruefen")
add("")
def emit_switches(add, tro: TroBase, anzahl: int, alle: dict[str, TroBase]) -> None:
abgaenge = tro.successors
for j in range(1, anzahl + 1):
pfad = f"#{tro.tro_id}.stInSwitch{j}"
add(f' {pfad}.Settings.nSwitchNo := "cSwi_____"; // {TODO}')
def emit_switches(add, tro: SclTro) -> None:
for w in tro.switches:
pfad = f"#{tro.id}.stInSwitch{w.n}"
add(f' {pfad}.Settings.nSwitchNo := "{w.no.value}";{_todo(w.no, " ")}')
add(f" {pfad}.Settings.xPluggedExSen3 := FALSE;")
add(f" {pfad}.Settings.xPluggedExSen4 := FALSE;")
if anzahl == 1:
# Eine Weiche bedient alle Abgaenge - direkt ableitbar.
add(f" {pfad}.Settings.nTo1Destinations := {len(abgaenge)};"
if w.to1_destinations is not None:
add(f" {pfad}.Settings.nTo1Destinations := {w.to1_destinations};"
f" // Abgaenge laut Topologie")
else:
# Bei mehreren Weichen ist es eine Planungsentscheidung, welche
# Weiche welche Abgaenge bedient - die Summe ist bekannt, die
# Aufteilung nicht. Deshalb hier kein geratener Wert.
add(f" {pfad}.Settings.nTo1Destinations := _;"
f" // {TODO}: dieser TRO hat {len(abgaenge)} "
f"Abgaenge auf {anzahl} Weichen - Aufteilung festlegen")
f" // {TODO}: dieser TRO hat {len(tro.successors)} "
f"Abgaenge auf {len(tro.switches)} Weichen - Aufteilung festlegen")
add("")
if abgaenge:
if tro.switch_exits:
add(" // Zielliste je Abgang (aus dem TRO-Graphen berechnet) -")
add(" // Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:")
for abgang in abgaenge:
ziele = reachable_via(tro.tro_id, abgang, alle)
add(f" // ueber {abgang}: {', '.join(ziele) if ziele else '-'}")
for abgang in tro.switch_exits:
ziele = ", ".join(abgang.targets) if abgang.targets else "-"
add(f" // ueber {abgang.via}: {ziele}")
add("")
def emit_vario(add, tro: TroBase) -> None:
pfad = f"#{tro.tro_id}.stInVario"
def emit_vario(add, tro: SclTro) -> None:
pfad = f"#{tro.id}.stInVario"
add(f" {pfad}.Settings.xContinousEmptying := FALSE;")
add(f" {pfad}.Settings.tWaitForJog := T#300ms; // {TODO}: pruefen")
add(f" {pfad}.Settings.tConvEmpty := T#45000ms; // {TODO}: pruefen")
@@ -210,17 +171,18 @@ def emit_vario(add, tro: TroBase) -> None:
add(f" {pfad}.Settings.tCarrierInPosEdgeDelay := t#100ms;")
add(f" {pfad}.Settings.xJamSenDelayActive := TRUE;")
add(f" {pfad}.Settings.tJamSenDelay := T#2s;")
add(f' {pfad}.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // {TODO}')
add(f' {pfad}.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // {TODO}')
add(f' {pfad}.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // {TODO}')
add(f' {pfad}.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // {TODO}')
# Der Kommentar steht bei allen Sensoren in derselben Spalte
# (Parametername + Abstand = 16 Zeichen).
for name, sensor in tro.vario_sensors.items():
abstand = " " * (16 - len(name))
add(f' {pfad}.{name} := "DB_Inputs".Sensors["{sensor.value}"];'
f"{_todo(sensor, abstand)}")
add("")
def emit_barcode(add, tro: TroBase, anzahl: int) -> None:
for i in range(1, anzahl + 1):
suffix = "" if anzahl == 1 else str(i)
pfad = f"#{tro.tro_id}.stInBarcodeReader{suffix}"
def emit_barcode(add, tro: SclTro) -> None:
for scanner in tro.scanners:
pfad = f"#{tro.id}.stInBarcodeReader{scanner.suffix}"
add(f" {pfad}.Settings.xActivateCheckASCI := TRUE;")
add(f" {pfad}.Settings.tTimeout := T#3000ms;")
add(f' // {TODO}: Cognex-Interface verdrahten '
@@ -228,49 +190,55 @@ def emit_barcode(add, tro: TroBase, anzahl: int) -> None:
add("")
def emit_call(add, tro: TroBase, items: dict[str, int], alle: dict[str, TroBase]) -> None:
def emit_call(add, tro: SclTro) -> None:
"""Aufrufstelle schreiben.
Die Zeilen werden als (Code, Kommentar) gefuehrt und das Komma erst beim
Zusammensetzen gesetzt - sonst landet es hinter dem "//" und ist Teil des
Kommentars, womit die Parameterliste nicht mehr uebersetzt.
"""
tro_id = tro.tro_id
def offen(name: SclName, text: str = "") -> str:
if not name.todo:
return text
return f"{TODO} - {text}" if text else TODO
zeilen: list[tuple[str, str]] = [
('nInMainTroNo := "cMainTro____"', TODO),
('xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q', TODO),
(f'nInMainTroNo := "{tro.main_tro.value}"', offen(tro.main_tro)),
(f"xInSftyOk := {tro.safety.value}", offen(tro.safety)),
("xInAllRdyToStart := TRUE", ""),
(f'xInRelease := "DB_TRO_TEST".{tro_id}', ""),
(f"xInRelease := {tro.release}", ""),
]
if items.get(TroItem.VARIO_DRIVE):
zeilen.append(('xInMotorProtection := "FC____"', TODO))
if tro.has_vario:
zeilen.append((f"xInMotorProtection := {tro.motor_protection.value}",
offen(tro.motor_protection)))
zeilen.append(("xInAutomatic := #t_automatik", ""))
zeilen.append(("stInOutMachineState := #stInOutControlUnitCabinet", ""))
# Der generische Aufbau hat den Schaltschrank nie als offen markiert;
# das bleibt so, damit seine Ausgabe stabil ist (Golden-Files). Die
# Templates markieren ihn.
zeilen.append((f"stInOutMachineState := {tro.machine_state.value}", ""))
zeilen.append(("stInOutCognexInterface := #stCognexInterfaceDummy", ""))
# Staubereiche: je ankommender/abgehender Verbindung einer. Welche
# DB-Struktur dahintersteht, ist eine Planungsentscheidung - hier steht
# nur, WIE VIELE es sein muessen und zu welchem Nachbarn sie gehoeren.
for n, vor in enumerate(tro.predecessors, start=1):
zeilen.append((f'arInOutJamEntr{n} := "DB_JamArea____".stJam____.arCarrier',
f"{TODO} - Staubereich von {nachbar(vor, alle)}"))
zeilen.append((f'stInOutJamEntr{n} := "DB_JamArea____".stJam____.stData', ""))
for n, nach in enumerate(tro.successors, start=2):
zeilen.append((f'arInOutJamExit{n} := "DB_JamArea____".stJam____.arCarrier',
f"{TODO} - Staubereich nach {nachbar(nach, alle)}"))
zeilen.append((f'stInOutJamExit{n} := "DB_JamArea____".stJam____.stData', ""))
for jam in tro.jam_entries:
zeilen.append((f"arInOutJamEntr{jam.n} := {jam.db.value}.arCarrier",
offen(jam.db, f"Staubereich von {jam.neighbour}")))
zeilen.append((f"stInOutJamEntr{jam.n} := {jam.db.value}.stData", ""))
for jam in tro.jam_exits:
zeilen.append((f"arInOutJamExit{jam.n} := {jam.db.value}.arCarrier",
offen(jam.db, f"Staubereich nach {jam.neighbour}")))
zeilen.append((f"stInOutJamExit{jam.n} := {jam.db.value}.stData", ""))
for i in range(1, items.get(TroItem.SEPARATOR, 1) + 1):
zeilen.append((f'xOutStopper{i} => "MB____"', TODO))
if items.get(TroItem.VARIO_DRIVE):
zeilen.append(('xOutVarioMotor => "MA____"', TODO))
for j in range(1, items.get(TroItem.SWITCH, 0) + 1):
zeilen.append((f'xOutSw{j}ExTo3 => "MB____"', TODO))
zeilen.append((f'stInOutHMI := "DB_Interface_HMI".stTRO.{tro_id}', ""))
zeilen.append(('nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]',
TODO))
for s in tro.separators:
zeilen.append((f'xOutStopper{s.n} => "{s.stopper.value}"', offen(s.stopper)))
if tro.has_vario:
zeilen.append((f'xOutVarioMotor => "{tro.vario_motor.value}"',
offen(tro.vario_motor)))
for w in tro.switches:
zeilen.append((f'xOutSw{w.n}ExTo3 => "{w.valve.value}"', offen(w.valve)))
zeilen.append((f'stInOutHMI := "DB_Interface_HMI".stTRO.{tro.id}', ""))
zeilen.append((f'nOutStateLast => "DB_GLOB_TroState".arTroState["{tro.main_tro.value}"]',
offen(tro.main_tro)))
kopf = f" #{tro_id}("
kopf = f" #{tro.id}("
einzug = " " * len(kopf)
for index, (code, kommentar) in enumerate(zeilen):
trenner = ");" if index == len(zeilen) - 1 else ","
@@ -279,34 +247,75 @@ def emit_call(add, tro: TroBase, items: dict[str, int], alle: dict[str, TroBase]
add(f"{text} // {kommentar}" if kommentar else text)
def emit_direction(add, tro: TroBase, anzahl: int) -> None:
def emit_direction(add, tro: SclTro) -> None:
"""Weichenlogik - je Weiche ein FC_Direction-Aufruf."""
add("")
add(" REGION Direction")
for j in range(1, anzahl + 1):
ziel = (f"#{tro.tro_id}.nInDirection" if anzahl == 1
else f"#{tro.tro_id}.nInDirection{j}")
add(f' "FC_Direction"(nInSwitchNo := "cSwi_____", // {TODO}')
add(f" nOutDirection => {ziel},")
add(f' InOutCarrier := "DB_JamArea____".stJam____'
f".arCarrier[1]);")
if j < anzahl:
for w in tro.switches:
add(f' "FC_Direction"(nInSwitchNo := "{w.no.value}",{_todo(w.no, " ")}')
add(f" nOutDirection => {w.direction_target},")
add(f" InOutCarrier := {w.jam_db.value}.arCarrier[1]);")
if w.n < len(tro.switches):
add("")
add(" END_REGION")
def render(document: TroDocument, quelle: str, start_id: str = "") -> str:
tros = document.tros
alle = {t.tro_id: t for t in tros}
geordnet, startgrund = flow_order(tros, start_id)
def emit_region(add, tro: SclTro) -> None:
"""Eine REGION je TRO (heutiger, generischer Aufbau aus den Bauteilen)."""
add("")
add(f"REGION {tro.region_title}")
if tro.position:
add(f" // Anlagenkoordinate x/y: {tro.position[0]:.0f} / {tro.position[1]:.0f} mm")
add(f" // Vorgaenger: {', '.join(tro.predecessors) or '-'}")
add(f" // Nachfolger: {', '.join(tro.successors) or '-'}")
if tro.confidence:
add(f" // Einstufung: {tro.confidence}")
add("")
emit_separators(add, tro)
if tro.switches:
emit_switches(add, tro)
if tro.has_vario:
emit_vario(add, tro)
if tro.scanners:
emit_barcode(add, tro)
if tro.storage_lines:
add(f" // {TODO}: Linienspeicher mit {tro.storage_lines} Linien - "
f"Parametrierung je Linie")
add("")
add(" #%s.stInPriorityManager.xReleaseOk := TRUE;" % tro.id)
add("")
emit_call(add, tro)
if tro.switches:
emit_direction(add, tro)
add("END_REGION")
def template_usage(context: SclFile, templates: SclTemplates | None
) -> tuple[list[str], list[str]]:
"""FB-Typen mit bzw. ohne Template (je sortiert, ohne Doppelte)."""
fbs = sorted({t.fb for t in context.tros})
if templates is None:
return [], fbs
return ([fb for fb in fbs if templates.has(fb)],
[fb for fb in fbs if not templates.has(fb)])
def render_context(context: SclFile, templates: SclTemplates | None = None) -> str:
"""SCL-Text aus dem fertigen Kontext.
Mit ``templates`` wird jeder TRO, fuer dessen FB ein Template existiert, aus
dem Template erzeugt, alle anderen generisch. Ohne ``templates`` ist die
Ausgabe die bisherige (Golden-Files in tests/fixtures/scl/).
"""
out: list[str] = []
add = out.append
add("// ============================================================")
add("// FB_Main - GERUEST, erzeugt von lib/scl_skeleton.py")
add(f"// Quelle : {quelle}")
add(f"// Erzeugt: {datetime.now().strftime('%Y-%m-%d %H:%M')}")
add(f"// Quelle : {context.source}")
add(f"// Erzeugt: {context.created}")
add("//")
add("// Das ist KEIN lauffaehiges Programm, sondern ein Geruest zum")
add("// Ausfuellen. Struktur, Reihenfolge und Bauteilzahl stammen aus dem")
@@ -319,57 +328,33 @@ def render(document: TroDocument, quelle: str, start_id: str = "") -> str:
add("// (DB_JamArea...) und die Zeiten, soweit als 'pruefen' vermerkt.")
add("//")
add("// Reihenfolge der REGIONs = Materialfluss.")
add(f"// Anfang bei {geordnet[0].tro_id}: {startgrund}.")
add(f"// Anfang bei {context.tros[0].id}: {context.start_reason}.")
if templates is not None:
mit, ohne = template_usage(context, templates)
add("//")
add(f"// Aus Template : {', '.join(mit) or '-'}")
add(f"// Generisch : {', '.join(ohne) or '-'} (kein Template - von Hand pruefen)")
add("// ============================================================")
add("")
add('FUNCTION_BLOCK "FB_Main"')
add("{ S7_Optimized_Access := 'TRUE' }")
add("VERSION : 0.1")
add(" VAR ")
for tro in geordnet:
fb = tro.fb_block or "FB_UNBEKANNT"
kommentar = f" // {tro.type_name}"
if tro.separators:
kommentar += f", Sep {', '.join(tro.separators)}"
add(f' {tro.tro_id} : "{fb}";{kommentar}')
for tro in context.tros:
kommentar = f" // {tro.type}"
if tro.layout_separators:
kommentar += f", Sep {', '.join(tro.layout_separators)}"
add(f' {tro.id} : "{tro.fb}";{kommentar}')
add(" END_VAR")
add("")
add("BEGIN")
for tro in geordnet:
items = tro.items
n_sep = items.get(TroItem.SEPARATOR, 1)
n_swi = items.get(TroItem.SWITCH, 0)
n_scan = items.get(TroItem.SCANNER, 0)
add("")
add(f"REGION {region_title(tro)}")
if tro.position:
add(f" // Anlagenkoordinate x/y: {tro.x:.0f} / {tro.y:.0f} mm")
add(f" // Vorgaenger: {', '.join(tro.predecessors) or '-'}")
add(f" // Nachfolger: {', '.join(tro.successors) or '-'}")
if tro.confidence:
add(f" // Einstufung: {tro.confidence}")
add("")
emit_separators(add, tro, n_sep, hat_scanner=bool(n_scan))
if n_swi:
emit_switches(add, tro, n_swi, alle)
if items.get(TroItem.VARIO_DRIVE):
emit_vario(add, tro)
if n_scan:
emit_barcode(add, tro, n_scan)
if items.get(TroItem.STORAGE_LINE):
add(f" // {TODO}: Linienspeicher mit {items[TroItem.STORAGE_LINE]} Linien - "
f"Parametrierung je Linie")
for tro in context.tros:
if templates is not None and templates.has(tro.fb):
add("")
add(" #%s.stInPriorityManager.xReleaseOk := TRUE;" % tro.tro_id)
add("")
emit_call(add, tro, items, alle)
if n_swi:
emit_direction(add, tro, n_swi)
add("END_REGION")
out.extend(templates.render(tro).split("\n"))
else:
emit_region(add, tro)
add("")
add("END_FUNCTION_BLOCK")
@@ -377,6 +362,12 @@ def render(document: TroDocument, quelle: str, start_id: str = "") -> str:
return "\n".join(out)
def render(document: TroDocument, quelle: str, start_id: str = "",
templates: SclTemplates | None = None) -> str:
"""TRO-JSON -> SCL-Text (Kontext bauen, dann ausgeben)."""
return render_context(build_context(document, quelle, start_id), templates)
def main(argv: list[str] | None = None) -> int:
args = parse_args(argv)
results = env_dir("SKEL_RESULTS", "results")
@@ -413,20 +404,42 @@ def main(argv: list[str] | None = None) -> int:
print(f"FEHLER: {json_file} enthaelt keine TROs.", file=sys.stderr)
return 1
text = render(document, json_file.name, args.start)
templates = None
if args.templates is not None:
ordner = Path(args.templates)
if not ordner.is_dir():
print(f"FEHLER: Template-Ordner nicht gefunden: {ordner}", file=sys.stderr)
return 1
templates = SclTemplates(ordner)
context = build_context(document, json_file.name, args.start)
mit, ohne = template_usage(context, templates)
if args.strict and ohne:
print(f"FEHLER: kein Template fuer {', '.join(ohne)} (--strict) - "
f"keine SCL geschrieben.", file=sys.stderr)
return 1
try:
text = render_context(context, templates)
except TemplateError as exc:
# StrictUndefined, Syntaxfehler, fehlendes Makro ... - lieber keine SCL
# als eine mit stillen Luecken.
print(f"FEHLER im Template: {exc}", file=sys.stderr)
return 1
out_file = results / (args.out or f"{json_file.stem.replace('_tro', '')}_FB_Main.scl")
out_file.write_text(text, encoding="utf-8")
offen = text.count(TODO)
geordnet, startgrund = flow_order(document.tros, args.start)
print("")
print("================================================================")
print("FB_MAIN-GERUEST")
print("================================================================")
print(f"Quelle = {json_file}")
print(f"TROs = {len(document.tros)}")
print(f"Reihenfolge = {' -> '.join(t.tro_id for t in geordnet)}")
print(f"Anfang = {geordnet[0].tro_id} ({startgrund})")
print(f"TROs = {len(context.tros)}")
print(f"Reihenfolge = {' -> '.join(t.id for t in context.tros)}")
print(f"Anfang = {context.tros[0].id} ({context.start_reason})")
if templates is not None:
print(f"Templates = {len(mit)} von {len(mit) + len(ohne)} Typen "
f"(generisch: {', '.join(ohne) or '-'})")
print(f"Offene Stellen = {offen} (Marker '{TODO}')")
print(f"SCL = {out_file}")
print("================================================================")
@@ -451,10 +464,12 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
epilog="Beispiele:\n"
" scl_skeleton.bat\n"
" scl_skeleton.bat --json export_tro.json --out FB_Main.scl\n"
" scl_skeleton.bat --json mubea_tro.json --templates\n"
"\n"
"Exit-Codes:\n"
" 0 ok\n"
" 1 Eingabe- oder Aufruffehler\n",
" 0 ok (auch wenn TROs ohne Template generisch erzeugt wurden)\n"
" 1 Eingabe-, Aufruf- oder Templatefehler; mit --strict auch\n"
" ein FB-Typ ohne Template\n",
)
parser.add_argument(
"--json",
@@ -475,6 +490,22 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
help="TRO, bei dem die Reihenfolge beginnt. Nur noetig, solange der "
"Fluss ein geschlossener Kreis ohne Be-/Entladestation ist.",
)
parser.add_argument(
"--templates",
nargs="?",
const=str(TEMPLATE_DIR),
default=None,
metavar="DIR",
help="REGIONs aus den FB-Templates erzeugen (doc/SCL_Templates.md). "
"Ohne DIR: lib/scl_templates. FB-Typen ohne Template bleiben "
"generisch. Ohne diesen Schalter: bisherige Ausgabe.",
)
parser.add_argument(
"--strict",
action="store_true",
help="Nur mit --templates: abbrechen (Exit 1), wenn ein FB-Typ der "
"Anlage kein Template hat.",
)
return parser.parse_args(argv)
@@ -0,0 +1,64 @@
{#-
FB_ILS_MTRO_1Sep1Swi - Aufrufstelle in FB_Main
Referenz: doc/TRO_Katalog/scl_templates/FB_ILS_MTRO_1Sep1Swi.scl
(TRO 107, =A01+UH01-KF00 FB_Main). Zeilen und Reihenfolge folgen
dieser Aufrufstelle; geprueft per tests/test_scl_templates.py.
Entscheidungen zu den ortsgebundenen Zeilen (doc/SCL_Templates.md §6):
stInSenJam<n> je Ausgang einer, Sensor offen
stInSettings.xPrioDir2 TRUE wie Referenz, aber offen (Planungsentscheidung)
PriorityManagerDir2 immer, UDT-Name offen
xInCarouselRun1 immer, offen - ob der TRO am Kreisel liegt, steht
nicht in der TRO-JSON; sonst Zeile loeschen
xInRelease TRUE wie Referenz (generisch: "DB_TRO_TEST")
Separatorzeiten 100/50 ms wie Referenz, "pruefen"
stInOutMachineState Schaltschrank offen (anlagenspezifisch)
Alle noch mit den SPS-Kollegen zu bestaetigen.
-#}
{% import "_macros.scl.j2" as m %}
REGION {{ t.region_title }}
{{ m.kopf(t) }}
{% for s in t.separators %}
{{ m.separator(t, s) }}
{% endfor %}
{{ m.jam_sensors(t) }}
{% for w in t.switches %}
{{ m.switch(t, w) }}
{% endfor %}
{{ m.ziele(t) }}
{% set z = [] %}
{% set _ = z.append(('stInPriorityManagerDir2 := "DB_Prozessdaten".stPriorityManager.' ~ t.priority_udt.value ~ '.TroIn', m.note(t.priority_udt))) %}
{% set _ = z.append(('stOutPriorityManagerDir2 => "DB_Prozessdaten".stPriorityManager.' ~ t.priority_udt.value ~ '.TroOut', m.note(t.priority_udt))) %}
{% set _ = z.append(('nInMainTroNo := "' ~ t.main_tro.value ~ '"', m.note(t.main_tro))) %}
{% set _ = z.append(("xInSftyOk := " ~ t.safety.value, m.note(t.safety))) %}
{% set _ = z.append(("xInAllRdyToStart := TRUE", "")) %}
{% set _ = z.append(("xInCarouselRun1 := " ~ t.carousel_run.value, m.note(t.carousel_run, "nur am Kreisel, sonst Zeile loeschen"))) %}
{% set _ = z.append(("xInRelease := TRUE", "")) %}
{% set _ = z.append(("stInOutMachineState := " ~ t.machine_state.value, m.note(t.machine_state, "Schaltschrank"))) %}
{% set _ = z.append(("stInOutCognexInterface := #stCognexInterfaceDummy", "")) %}
{% for j in t.jam_entries %}
{% set _ = z.append(("arInOutJamEntr" ~ j.n ~ " := " ~ j.db.value ~ ".arCarrier", m.note(j.db, "Staubereich von " ~ j.neighbour))) %}
{% set _ = z.append(("stInOutJamEntr" ~ j.n ~ " := " ~ j.db.value ~ ".stData", m.note(j.db))) %}
{% endfor %}
{% for j in t.jam_exits %}
{% set _ = z.append(("arInOutJamExit" ~ j.n ~ " := " ~ j.db.value ~ ".arCarrier", m.note(j.db, "Staubereich nach " ~ j.neighbour))) %}
{% set _ = z.append(("stInOutJamExit" ~ j.n ~ " := " ~ j.db.value ~ ".stData", m.note(j.db))) %}
{% endfor %}
{% set _ = z.append(('stInOutHMI := "DB_Interface_HMI".stTRO.' ~ t.id, "")) %}
{% set _ = z.append(('nOutStateLast => "DB_GLOB_TroState".arTroState["' ~ t.main_tro.value ~ '"]', m.note(t.main_tro))) %}
{% for s in t.separators %}
{% set _ = z.append(("xOutStopper" ~ s.n ~ ' => "' ~ s.stopper.value ~ '"', m.note(s.stopper))) %}
{% endfor %}
{% for w in t.switches %}
{% set _ = z.append(("xOutSw" ~ w.n ~ 'ExTo3 => "' ~ w.valve.value ~ '"', m.note(w.valve))) %}
{% endfor %}
#{{ t.id }}.stInSettings.xPrioDir2 := {{ t.prio_dir2.value }};{{ m.todo(t.prio_dir2) }}
{{ m.call(t, z) }}
{{ m.direction(t) }}
END_REGION
+103
View File
@@ -0,0 +1,103 @@
{#-
_macros.scl.j2 - gemeinsame Bausteine der FB-Templates (doc/SCL_Templates.md §5.2)
Jede Zeile ist eine der Klassen aus §6: L (Layout, aus dem Kontext),
N (Name, heute Platzhalter + TODO), R (Referenzwert aus der realen Aufrufstelle),
E (E-Planung, Platzhalter + TODO), C (Bedingung).
Makros liefern ihre Zeilen OHNE abschliessenden Zeilenumbruch; der Aufrufer
setzt ihn. Globale Variable: TODO (Marker "TODO(E-Planung)").
-#}
{#- TODO-Kommentar hinter einer Zeile, wenn der Name noch offen ist -#}
{% macro todo(name, abstand=" ") -%}
{% if name.todo %}{{ abstand }}// {{ TODO }}{% endif %}
{%- endmacro %}
{#- Kommentartext fuer eine Parameterzeile des Aufrufs -#}
{% macro note(name, text="") -%}
{% if name.todo %}{{ TODO }}{% if text %} - {{ text }}{% endif %}{% else %}{{ text }}{% endif %}
{%- endmacro %}
{#- Kommentarkopf der REGION: Lage und Nachbarn im Layout (L) -#}
{% macro kopf(t) %}
{% if t.position %}
// Anlagenkoordinate x/y: {{ "%.0f"|format(t.position[0]) }} / {{ "%.0f"|format(t.position[1]) }} mm
{% endif %}
// Vorgaenger: {{ t.predecessors|join(", ") or "-" }}
// Nachfolger: {{ t.successors|join(", ") or "-" }}
{% if t.confidence %}
// Einstufung: {{ t.confidence }}
{% endif %}
// Aufbau nach Template {{ t.fb }}.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates)
{%- endmacro %}
{#- stInSeparator<n>: Zeiten R aus der Referenz (TRO107), Nummer N, Sensor E -#}
{% macro separator(t, s) %}
// Separator {{ s.n }} = Bauteil {{ s.layout }} aus dem Layout
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.nSeparatorNo := "{{ s.no.value }}";{{ todo(s.no) }}
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.tTrailingTime := t#100ms; // {{ TODO }}: pruefen
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.tHandlingTime := t#50ms; // {{ TODO }}: pruefen
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.tJam := "TimeForSepJam";
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.xPluggedJam := TRUE;
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.xPluggedPart := FALSE;
#{{ t.id }}.stInSeparator{{ s.n }}.Settings.xPluggedScanner := {{ "TRUE" if t.has_scanner else "FALSE" }};
#{{ t.id }}.stInSeparator{{ s.n }}.stSenInSep := "DB_Inputs".Sensors["{{ s.sensor.value }}"];{{ todo(s.sensor) }}
{%- endmacro %}
{#- stInSenJam<n>: ein Stausensor je Ausgang (E) -#}
{% macro jam_sensors(t) %}
{% for j in t.jam_exits %}
#{{ t.id }}.stInSenJam{{ j.n }} := "DB_Inputs".Sensors["{{ j.sensor.value }}"];{{ todo(j.sensor) }}
{% endfor %}
{%- endmacro %}
{#- stInSwitch<n>: Nummer N; nTo1Destinations L, aber Bedeutung noch zu klaeren -#}
{% macro switch(t, w) %}
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.nSwitchNo := "{{ w.no.value }}";{{ todo(w.no) }}
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.xPluggedExSen3 := FALSE;
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.xPluggedExSen4 := FALSE;
{% if w.to1_destinations is not none %}
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.nTo1Destinations := {{ w.to1_destinations }}; // Abgaenge laut Topologie - {{ TODO }}: pruefen (Info fuer HMI; Referenz TRO107 hat 3 bei 2 Abgaengen)
{% else %}
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.nTo1Destinations := _; // {{ TODO }}: {{ t.successors|length }} Abgaenge auf {{ t.switches|length }} Weichen - Aufteilung festlegen
{% endif %}
{%- endmacro %}
{#- Zielliste je Weichenabgang (L, nur Kommentar) -#}
{% macro ziele(t) %}
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
{% for e in t.switch_exits %}
// ueber {{ e.via }}: {{ e.targets|join(", ") or "-" }}
{% endfor %}
{%- endmacro %}
{#-
Instanzaufruf aus einer Liste von (Code, Kommentar). Das Komma wird hier
gesetzt und steht damit VOR dem Kommentar - sonst waere es Teil des
Kommentars und die Parameterliste uebersetzt nicht.
-#}
{% macro call(t, zeilen) %}
{% set einzug = " " * (6 + t.id|length) %}
{% for code, kommentar in zeilen %}
{{ (" #" ~ t.id ~ "(") if loop.first else einzug }}{{ code }}{{ ");" if loop.last else "," }}{% if kommentar %} // {{ kommentar }}{% endif %}
{% endfor %}
{%- endmacro %}
{#- REGION Direction: je Weiche ein FC_Direction-Aufruf -#}
{% macro direction(t) %}
REGION Direction
{% for w in t.switches %}
"FC_Direction"(nInSwitchNo := "{{ w.no.value }}",{{ todo(w.no) }}
nOutDirection => {{ w.direction_target }},
InOutCarrier := {{ w.jam_db.value }}.arCarrier[1]);{{ todo(w.jam_db) }}
{% if not loop.last %}
{% endif %}
{% endfor %}
END_REGION
{%- endmacro %}
+3
View File
@@ -3,6 +3,9 @@
pydantic >= 2.0.0
# SCL-Templates (scl_skeleton --templates, lib/scl_templates/*.scl.j2)
jinja2 >= 3.1
# DXF lesen und schreiben (tro_annotate). DWG wird nicht unterstuetzt.
ezdxf >= 1.4.0
+981
View File
@@ -0,0 +1,981 @@
// ============================================================
// FB_Main - GERUEST, erzeugt von lib/scl_skeleton.py
// Quelle : HundM05_tro.json
// Erzeugt: <maskiert>
//
// Das ist KEIN lauffaehiges Programm, sondern ein Geruest zum
// Ausfuellen. Struktur, Reihenfolge und Bauteilzahl stammen aus dem
// Anlagenlayout und der vor Ort aufgenommenen Topologie.
//
// Jede Stelle, die aus der E-Planung kommen muss, ist mit
// 'TODO(E-Planung)' markiert - danach suchen, dann ist nichts vergessen.
// Offen sind durchgaengig: Sensor-/Aktoradressen (cInBG/MB/MA),
// Separator- und Weichennummern, MainTro-Nummern, die Staubereiche
// (DB_JamArea...) und die Zeiten, soweit als 'pruefen' vermerkt.
//
// Reihenfolge der REGIONs = Materialfluss.
// Anfang bei TRO20: Materialeingang ueber SYS1, SYS2.
// ============================================================
FUNCTION_BLOCK "FB_Main"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR
TRO20 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0007
TRO01 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0008
TRO02 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0025
TRO06 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0010
TRO03 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0026
TRO07 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0031
TRO09 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0012
TRO04 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0027
TRO08 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0032
TRO10 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0035
TRO12 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0014
TRO05 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0028
TRO11 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0036
TRO13 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0039
TRO15 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0016
TRO14 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0040
TRO16 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0018
TRO17 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0043
TRO19 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0020
TRO18 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0044
END_VAR
BEGIN
REGION TRO20 (1Sep) Sep 0007
// Anlagenkoordinate x/y: 2415 / 365 mm
// Vorgaenger: SYS1, SYS2, TRO19
// Nachfolger: TRO01
// Einstufung: mittel
// Separator 1 = Bauteil 0007 aus dem Layout
#TRO20.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO20.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO20.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO20.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO20.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO20.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO20.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO20.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO20.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO20.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO20.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO20.stInPriorityManager.xReleaseOk := TRUE;
#TRO20(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO20,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von SYS1 (Station, kein TRO)
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von SYS2 (Station, kein TRO)
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO19
stInOutJamEntr3 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO01
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO20,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO01 (1Sep1Swi) Sep 0008
// Anlagenkoordinate x/y: 4076 / 985 mm
// Vorgaenger: TRO20
// Nachfolger: TRO02, TRO06
// Einstufung: mittel
// Separator 1 = Bauteil 0008 aus dem Layout
#TRO01.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO01.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO01.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO01.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO01.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO01.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO01.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO01.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO01.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO01.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO01.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO01.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO02: SYS3, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18, TRO19, TRO20
// ueber TRO06: SYS3, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18, TRO19, TRO20
#TRO01.stInPriorityManager.xReleaseOk := TRUE;
#TRO01(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO01,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO20
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO02
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO06
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO01,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO01.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO02 (Vario) Sep 0025
// Anlagenkoordinate x/y: 5070 / 2530 mm
// Vorgaenger: TRO01
// Nachfolger: TRO03
// Einstufung: hoch
// Separator 1 = Bauteil 0025 aus dem Layout
#TRO02.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO02.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO02.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO02.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO02.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO02.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO02.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO02.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO02.stInVario.Settings.xContinousEmptying := FALSE;
#TRO02.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO02.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO02.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO02.stInVario.Settings.tWaitForStop := t#3s;
#TRO02.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO02.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO02.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO02.stInVario.Settings.tJamSenDelay := T#2s;
#TRO02.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO02.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO02.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO02.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO02.stInPriorityManager.xReleaseOk := TRUE;
#TRO02(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO02,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO01
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO03
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO02,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO06 (1Sep1Swi) Sep 0010
// Anlagenkoordinate x/y: 8577 / 989 mm
// Vorgaenger: TRO01, TRO05
// Nachfolger: TRO07, TRO09
// Einstufung: mittel
// Separator 1 = Bauteil 0010 aus dem Layout
#TRO06.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO06.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO06.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO06.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO06.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO06.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO06.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO06.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO06.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO06.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO06.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO06.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO06.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO06.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO06.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO07: SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18, TRO19, TRO20
// ueber TRO09: SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO09, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18, TRO19, TRO20
#TRO06.stInPriorityManager.xReleaseOk := TRUE;
#TRO06(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO06,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO01
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO05
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO07
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO09
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO06,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO06.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO03 (1Sep) Sep 0026
// Anlagenkoordinate x/y: 7223 / 6180 mm
// Vorgaenger: TRO02
// Nachfolger: TRO04
// Einstufung: mittel
// Separator 1 = Bauteil 0026 aus dem Layout
#TRO03.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO03.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO03.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO03.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO03.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO03.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO03.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO03.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO03.stInPriorityManager.xReleaseOk := TRUE;
#TRO03(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO03,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO02
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO04
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO03,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO07 (Vario) Sep 0031
// Anlagenkoordinate x/y: 9571 / 5933 mm
// Vorgaenger: TRO06
// Nachfolger: TRO08
// Einstufung: hoch
// Separator 1 = Bauteil 0031 aus dem Layout
#TRO07.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO07.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO07.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO07.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO07.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO07.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO07.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO07.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO07.stInVario.Settings.xContinousEmptying := FALSE;
#TRO07.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO07.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO07.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO07.stInVario.Settings.tWaitForStop := t#3s;
#TRO07.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO07.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO07.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO07.stInVario.Settings.tJamSenDelay := T#2s;
#TRO07.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO07.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO07.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO07.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO07.stInPriorityManager.xReleaseOk := TRUE;
#TRO07(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO07,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO06
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO08
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO07,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO09 (1Sep1Swi) Sep 0012
// Anlagenkoordinate x/y: 12650 / 987 mm
// Vorgaenger: TRO06, TRO08
// Nachfolger: TRO10, TRO12
// Einstufung: mittel
// Separator 1 = Bauteil 0012 aus dem Layout
#TRO09.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO09.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO09.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO09.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO09.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO09.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO09.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO09.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO09.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO09.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO09.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO09.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO10: SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18, TRO19, TRO20
// ueber TRO12: SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18, TRO19, TRO20
#TRO09.stInPriorityManager.xReleaseOk := TRUE;
#TRO09(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO09,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO06
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO08
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO10
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO12
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO09,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO09.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO04 (Vario) Sep 0027
// Anlagenkoordinate x/y: 7223 / 5680 mm
// Vorgaenger: TRO03
// Nachfolger: TRO05
// Einstufung: hoch
// Separator 1 = Bauteil 0027 aus dem Layout
#TRO04.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO04.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO04.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO04.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO04.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO04.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO04.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO04.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO04.stInVario.Settings.xContinousEmptying := FALSE;
#TRO04.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO04.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO04.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO04.stInVario.Settings.tWaitForStop := t#3s;
#TRO04.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO04.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO04.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO04.stInVario.Settings.tJamSenDelay := T#2s;
#TRO04.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO04.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO04.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO04.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO04.stInPriorityManager.xReleaseOk := TRUE;
#TRO04(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO04,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO03
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO05
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO04,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO08 (1Sep) Sep 0032
// Anlagenkoordinate x/y: 10841 / 1724 mm
// Vorgaenger: TRO07
// Nachfolger: TRO09
// Einstufung: mittel
// Separator 1 = Bauteil 0032 aus dem Layout
#TRO08.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO08.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO08.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO08.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO08.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO08.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO08.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO08.stInPriorityManager.xReleaseOk := TRUE;
#TRO08(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO08,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO07
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO09
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO08,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO10 (Vario) Sep 0035
// Anlagenkoordinate x/y: 13648 / 5933 mm
// Vorgaenger: TRO09
// Nachfolger: TRO11
// Einstufung: hoch
// Separator 1 = Bauteil 0035 aus dem Layout
#TRO10.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO10.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO10.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO10.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO10.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO10.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO10.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO10.stInVario.Settings.xContinousEmptying := FALSE;
#TRO10.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO10.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO10.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO10.stInVario.Settings.tWaitForStop := t#3s;
#TRO10.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO10.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO10.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO10.stInVario.Settings.tJamSenDelay := T#2s;
#TRO10.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInPriorityManager.xReleaseOk := TRUE;
#TRO10(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO10,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO09
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO11
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO10,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO12 (1Sep1Swi) Sep 0014
// Anlagenkoordinate x/y: 16820 / 991 mm
// Vorgaenger: TRO09, TRO11
// Nachfolger: TRO13, TRO15
// Einstufung: mittel
// Separator 1 = Bauteil 0014 aus dem Layout
#TRO12.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO12.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO12.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO12.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO12.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO12.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO12.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO12.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO12.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO12.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO12.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO12.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO13: SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18, TRO19, TRO20
// ueber TRO15: SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO15, TRO16, TRO17, TRO18, TRO19, TRO20
#TRO12.stInPriorityManager.xReleaseOk := TRUE;
#TRO12(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO12,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO09
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO11
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO13
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO15
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO12,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO12.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO05 (1Sep) Sep 0028
// Anlagenkoordinate x/y: 6274 / 1756 mm
// Vorgaenger: TRO04
// Nachfolger: TRO06
// Einstufung: mittel
// Separator 1 = Bauteil 0028 aus dem Layout
#TRO05.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO05.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO05.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO05.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO05.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO05.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO05.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO05.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO05.stInPriorityManager.xReleaseOk := TRUE;
#TRO05(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO05,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO04
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO06
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO05,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO11 (1Sep) Sep 0036
// Anlagenkoordinate x/y: 14918 / 1725 mm
// Vorgaenger: TRO10
// Nachfolger: TRO12
// Einstufung: mittel
// Separator 1 = Bauteil 0036 aus dem Layout
#TRO11.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO11.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO11.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO11.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO11.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO11.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO11.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO11.stInPriorityManager.xReleaseOk := TRUE;
#TRO11(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO11,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO10
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO12
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO11,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO13 (Vario) Sep 0039
// Anlagenkoordinate x/y: 17816 / 5934 mm
// Vorgaenger: TRO12
// Nachfolger: TRO14
// Einstufung: hoch
// Separator 1 = Bauteil 0039 aus dem Layout
#TRO13.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO13.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO13.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO13.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO13.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO13.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO13.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO13.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO13.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO13.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO13.stInVario.Settings.xContinousEmptying := FALSE;
#TRO13.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO13.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO13.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO13.stInVario.Settings.tWaitForStop := t#3s;
#TRO13.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO13.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO13.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO13.stInVario.Settings.tJamSenDelay := T#2s;
#TRO13.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInPriorityManager.xReleaseOk := TRUE;
#TRO13(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO13,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO12
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO14
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO13,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO15 (1Sep1Swi) Sep 0016
// Anlagenkoordinate x/y: 20692 / 985 mm
// Vorgaenger: TRO12, TRO14
// Nachfolger: TRO16, TRO17
// Einstufung: mittel
// Separator 1 = Bauteil 0016 aus dem Layout
#TRO15.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO15.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO15.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO15.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO15.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO15.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO15.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO15.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO15.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO15.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO15.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO15.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO16: SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO13, TRO14, TRO16, TRO19, TRO20
// ueber TRO17: SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO13, TRO14, TRO16, TRO17, TRO18, TRO19, TRO20
#TRO15.stInPriorityManager.xReleaseOk := TRUE;
#TRO15(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO15,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO12
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO14
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO16
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO17
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO15,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO15.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO14 (1Sep) Sep 0040
// Anlagenkoordinate x/y: 19086 / 1725 mm
// Vorgaenger: TRO13
// Nachfolger: TRO15
// Einstufung: mittel
// Separator 1 = Bauteil 0040 aus dem Layout
#TRO14.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO14.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO14.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO14.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO14.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO14.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO14.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO14.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO14.stInPriorityManager.xReleaseOk := TRUE;
#TRO14(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO14,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO13
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO15
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO14,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO16 (1Sep) Sep 0018
// Anlagenkoordinate x/y: 23729 / 990 mm
// Vorgaenger: TRO15, TRO18
// Nachfolger: TRO19
// Einstufung: mittel
// Separator 1 = Bauteil 0018 aus dem Layout
#TRO16.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO16.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO16.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO16.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO16.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO16.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO16.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO16.stInPriorityManager.xReleaseOk := TRUE;
#TRO16(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO16,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO15
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO18
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO19
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO16,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO17 (Vario) Sep 0043
// Anlagenkoordinate x/y: 21590 / 5933 mm
// Vorgaenger: TRO15
// Nachfolger: TRO18
// Einstufung: hoch
// Separator 1 = Bauteil 0043 aus dem Layout
#TRO17.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO17.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO17.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO17.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO17.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO17.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO17.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO17.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO17.stInVario.Settings.xContinousEmptying := FALSE;
#TRO17.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO17.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO17.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO17.stInVario.Settings.tWaitForStop := t#3s;
#TRO17.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO17.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO17.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO17.stInVario.Settings.tJamSenDelay := T#2s;
#TRO17.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO17.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO17.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO17.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO17.stInPriorityManager.xReleaseOk := TRUE;
#TRO17(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO17,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO15
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO18
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO17,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO19 (1Sep) Sep 0020
// Anlagenkoordinate x/y: 24570 / 1167 mm
// Vorgaenger: TRO16
// Nachfolger: SYS3, TRO20
// Einstufung: mittel
// Separator 1 = Bauteil 0020 aus dem Layout
#TRO19.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO19.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO19.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO19.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO19.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO19.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO19.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO19.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO19.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO19.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO19.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO19.stInPriorityManager.xReleaseOk := TRUE;
#TRO19(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO19,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO16
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach SYS3 (Station, kein TRO)
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO20
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO19,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO18 (1Sep) Sep 0044
// Anlagenkoordinate x/y: 22860 / 1724 mm
// Vorgaenger: TRO17
// Nachfolger: TRO16
// Einstufung: mittel
// Separator 1 = Bauteil 0044 aus dem Layout
#TRO18.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO18.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO18.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO18.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO18.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO18.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO18.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO18.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO18.stInPriorityManager.xReleaseOk := TRUE;
#TRO18(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO18,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO17
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO16
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO18,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
END_FUNCTION_BLOCK
File diff suppressed because it is too large Load Diff
+932
View File
@@ -0,0 +1,932 @@
{
"schema": "sps_skel-tro-v2",
"source": "HundM05.csv",
"created": "2026-10-09 11:30",
"note": "Aus dem CSV-Export abgeleitet (lib/tro_flow.py) - die Zeichnung ist nur Ansicht, keine Datenquelle.",
"tros": [
{
"id": "TRO01",
"type": "1Sep1Swi",
"confidence": "mittel",
"separators": [
"0008"
],
"predecessors": [
"TRO20"
],
"successors": [
"TRO02",
"TRO06"
],
"position": {
"x": 4075.94,
"y": 985.0,
"z": 2154.75
},
"label": "Separator 0008 an Ausschleuselement 0024 (Strecke 0001, Anfang)",
"hosts": [
"0001"
],
"scanners": [
"0009"
],
"reason": "1014mm von Ausschleuselement 0024 entfernt - kein eigenes Weichen-Bauteil im Layout, das Ausschleuselement uebernimmt diese Rolle",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep1Swi",
"items": {
"Separator": 1,
"Switch": 1
}
},
{
"id": "TRO02",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0025"
],
"predecessors": [
"TRO01"
],
"successors": [
"TRO03"
],
"position": {
"x": 5070.1,
"y": 2530.06,
"z": 2098.34
},
"label": "VF_1",
"hosts": [
"0001"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: horizontal,horizontal,horizontal,Auf,horizontal)",
"colocated": [
"TRO04",
"TRO05"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO03",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0026"
],
"predecessors": [
"TRO02"
],
"successors": [
"TRO04"
],
"position": {
"x": 7222.54,
"y": 6180.03,
"z": 2019.94
},
"label": "VF_1",
"hosts": [
"0001"
],
"scanners": [],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_1 rueckwaerts (3. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [
"TRO05"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO04",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0027"
],
"predecessors": [
"TRO03"
],
"successors": [
"TRO05"
],
"position": {
"x": 7222.54,
"y": 5679.62,
"z": 1993.71
},
"label": "VF_1",
"hosts": [
"0001"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: horizontal,horizontal,horizontal,Auf,horizontal)",
"colocated": [
"TRO02"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO05",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0028"
],
"predecessors": [
"TRO04"
],
"successors": [
"TRO06"
],
"position": {
"x": 6273.83,
"y": 1756.17,
"z": 2305.73
},
"label": "VF_1",
"hosts": [
"0001"
],
"scanners": [],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_1 rueckwaerts (1. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [
"TRO02",
"TRO03"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO06",
"type": "1Sep1Swi",
"confidence": "mittel",
"separators": [
"0010"
],
"predecessors": [
"TRO01",
"TRO05"
],
"successors": [
"TRO07",
"TRO09"
],
"position": {
"x": 8577.09,
"y": 988.6,
"z": 2154.75
},
"label": "Separator 0010 an Ausschleuselement 0030 (Strecke 0002, Anfang)",
"hosts": [
"0002"
],
"scanners": [
"0011"
],
"reason": "1015mm von Ausschleuselement 0030 entfernt - kein eigenes Weichen-Bauteil im Layout, das Ausschleuselement uebernimmt diese Rolle",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep1Swi",
"items": {
"Separator": 1,
"Switch": 1
}
},
{
"id": "TRO07",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0031"
],
"predecessors": [
"TRO06"
],
"successors": [
"TRO08"
],
"position": {
"x": 9570.9,
"y": 5932.96,
"z": 1918.34
},
"label": "VF_2",
"hosts": [
"0002"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: horizontal,horizontal,Auf)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO08",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0032"
],
"predecessors": [
"TRO07"
],
"successors": [
"TRO09"
],
"position": {
"x": 10840.84,
"y": 1724.4,
"z": 2305.73
},
"label": "VF_2",
"hosts": [
"0002"
],
"scanners": [],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_2 rueckwaerts (1. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO09",
"type": "1Sep1Swi",
"confidence": "mittel",
"separators": [
"0012"
],
"predecessors": [
"TRO06",
"TRO08"
],
"successors": [
"TRO10",
"TRO12"
],
"position": {
"x": 12650.4,
"y": 987.3,
"z": 2154.75
},
"label": "Separator 0012 an Ausschleuselement 0034 (Strecke 0003, Anfang)",
"hosts": [
"0003"
],
"scanners": [
"0013"
],
"reason": "1016mm von Ausschleuselement 0034 entfernt - kein eigenes Weichen-Bauteil im Layout, das Ausschleuselement uebernimmt diese Rolle",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep1Swi",
"items": {
"Separator": 1,
"Switch": 1
}
},
{
"id": "TRO10",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0035"
],
"predecessors": [
"TRO09"
],
"successors": [
"TRO11"
],
"position": {
"x": 13648.0,
"y": 5933.46,
"z": 1918.34
},
"label": "VF_3",
"hosts": [
"0003"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: horizontal,horizontal,Auf)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO11",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0036"
],
"predecessors": [
"TRO10"
],
"successors": [
"TRO12"
],
"position": {
"x": 14917.94,
"y": 1724.9,
"z": 2305.73
},
"label": "VF_3",
"hosts": [
"0003"
],
"scanners": [],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_3 rueckwaerts (1. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO12",
"type": "1Sep1Swi",
"confidence": "mittel",
"separators": [
"0014"
],
"predecessors": [
"TRO09",
"TRO11"
],
"successors": [
"TRO13",
"TRO15"
],
"position": {
"x": 16819.62,
"y": 990.75,
"z": 2154.75
},
"label": "Separator 0014 an Ausschleuselement 0038 (Strecke 0004, Anfang)",
"hosts": [
"0004"
],
"scanners": [
"0015"
],
"reason": "1016mm von Ausschleuselement 0038 entfernt - kein eigenes Weichen-Bauteil im Layout, das Ausschleuselement uebernimmt diese Rolle",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep1Swi",
"items": {
"Separator": 1,
"Switch": 1
}
},
{
"id": "TRO13",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0039"
],
"predecessors": [
"TRO12"
],
"successors": [
"TRO14"
],
"position": {
"x": 17816.0,
"y": 5933.96,
"z": 1918.34
},
"label": "VF_4",
"hosts": [
"0004"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: horizontal,horizontal,Auf)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO14",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0040"
],
"predecessors": [
"TRO13"
],
"successors": [
"TRO15"
],
"position": {
"x": 19085.94,
"y": 1725.4,
"z": 2305.73
},
"label": "VF_4",
"hosts": [
"0004"
],
"scanners": [],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_4 rueckwaerts (1. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO15",
"type": "1Sep1Swi",
"confidence": "mittel",
"separators": [
"0016"
],
"predecessors": [
"TRO12",
"TRO14"
],
"successors": [
"TRO16",
"TRO17"
],
"position": {
"x": 20692.43,
"y": 985.25,
"z": 2154.75
},
"label": "Separator 0016 an Ausschleuselement 0042 (Strecke 0005, Anfang)",
"hosts": [
"0005"
],
"scanners": [
"0017"
],
"reason": "1013mm von Ausschleuselement 0042 entfernt - kein eigenes Weichen-Bauteil im Layout, das Ausschleuselement uebernimmt diese Rolle",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep1Swi",
"items": {
"Separator": 1,
"Switch": 1
}
},
{
"id": "TRO16",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0018"
],
"predecessors": [
"TRO15",
"TRO18"
],
"successors": [
"TRO19"
],
"position": {
"x": 23729.42,
"y": 989.7,
"z": 2154.75
},
"label": "VF_5",
"hosts": [
"0005"
],
"scanners": [
"0019"
],
"reason": "Separator 0018: Zuordnung zeigt auf VF_5, ist aber nicht Teil von dessen TrackIds-Kette - kein eigenes VF treibt ihn an",
"colocated": [
"TRO17"
],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO17",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0043"
],
"predecessors": [
"TRO15"
],
"successors": [
"TRO18"
],
"position": {
"x": 21590.2,
"y": 5932.86,
"z": 1918.34
},
"label": "VF_5",
"hosts": [
"0005"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: horizontal,horizontal,Auf)",
"colocated": [
"TRO16"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO18",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0044"
],
"predecessors": [
"TRO17"
],
"successors": [
"TRO16"
],
"position": {
"x": 22860.14,
"y": 1724.3,
"z": 2305.73
},
"label": "VF_5",
"hosts": [
"0005"
],
"scanners": [],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_5 rueckwaerts (1. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO19",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0020"
],
"predecessors": [
"TRO16"
],
"successors": [
"SYS3",
"TRO20"
],
"position": {
"x": 24570.15,
"y": 1167.2,
"z": 2155.5
},
"label": "Separator 0020 auf Kreisel1 Bahn L",
"hosts": [
"0006-L"
],
"scanners": [],
"reason": "einzelner Separator auf angetriebener Kreisel-Bahn",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO20",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0007"
],
"predecessors": [
"SYS1",
"SYS2",
"TRO19"
],
"successors": [
"TRO01"
],
"position": {
"x": 2414.95,
"y": 365.0,
"z": 2155.5
},
"label": "Separator 0007 auf Kreisel1 Bahn R",
"hosts": [
"0006-R"
],
"scanners": [],
"reason": "einzelner Separator auf angetriebener Kreisel-Bahn",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
}
],
"boundaries": [
{
"id": "SYS1",
"type": "Materialeingang",
"confidence": "hoch",
"separators": [],
"predecessors": [],
"successors": [
"TRO20"
],
"position": {
"x": 5532.67,
"y": 265.14,
"z": 2109.31
},
"label": "BTMT Beladung :2",
"hosts": [
"0021"
],
"scanners": [],
"reason": "Systemgrenze (Be-/Entladestation) - kein TRO, nur Materialein-/ausgang",
"colocated": [],
"positionFrom": "Host-Objekte",
"positionPoints": 1,
"fbType": "",
"items": {}
},
{
"id": "SYS2",
"type": "Materialeingang",
"confidence": "hoch",
"separators": [],
"predecessors": [],
"successors": [
"TRO20"
],
"position": {
"x": 4503.25,
"y": 269.77,
"z": 2109.31
},
"label": "BTMT Beladung :1",
"hosts": [
"0022"
],
"scanners": [],
"reason": "Systemgrenze (Be-/Entladestation) - kein TRO, nur Materialein-/ausgang",
"colocated": [],
"positionFrom": "Host-Objekte",
"positionPoints": 1,
"fbType": "",
"items": {}
},
{
"id": "SYS3",
"type": "Materialausgang",
"confidence": "hoch",
"separators": [],
"predecessors": [
"TRO19"
],
"successors": [],
"position": {
"x": 25014.37,
"y": 1545.51,
"z": 2001.09
},
"label": "BTMT Entladung :1",
"hosts": [
"0023"
],
"scanners": [],
"reason": "Systemgrenze (Be-/Entladestation) - kein TRO, nur Materialein-/ausgang",
"colocated": [],
"positionFrom": "Host-Objekte",
"positionPoints": 1,
"fbType": "",
"items": {}
}
],
"connections": [
{
"from": "SYS1",
"to": "TRO20",
"kind": "normal"
},
{
"from": "SYS2",
"to": "TRO20",
"kind": "normal"
},
{
"from": "TRO01",
"to": "TRO02",
"kind": "weiche"
},
{
"from": "TRO01",
"to": "TRO06",
"kind": "bahn"
},
{
"from": "TRO02",
"to": "TRO03",
"kind": "bahn"
},
{
"from": "TRO03",
"to": "TRO04",
"kind": "bahn"
},
{
"from": "TRO04",
"to": "TRO05",
"kind": "bahn"
},
{
"from": "TRO05",
"to": "TRO06",
"kind": "bahn"
},
{
"from": "TRO06",
"to": "TRO07",
"kind": "weiche"
},
{
"from": "TRO06",
"to": "TRO09",
"kind": "bahn"
},
{
"from": "TRO07",
"to": "TRO08",
"kind": "bahn"
},
{
"from": "TRO08",
"to": "TRO09",
"kind": "bahn"
},
{
"from": "TRO09",
"to": "TRO10",
"kind": "weiche"
},
{
"from": "TRO09",
"to": "TRO12",
"kind": "bahn"
},
{
"from": "TRO10",
"to": "TRO11",
"kind": "bahn"
},
{
"from": "TRO11",
"to": "TRO12",
"kind": "bahn"
},
{
"from": "TRO12",
"to": "TRO13",
"kind": "weiche"
},
{
"from": "TRO12",
"to": "TRO15",
"kind": "bahn"
},
{
"from": "TRO13",
"to": "TRO14",
"kind": "bahn"
},
{
"from": "TRO14",
"to": "TRO15",
"kind": "bahn"
},
{
"from": "TRO15",
"to": "TRO16",
"kind": "bahn"
},
{
"from": "TRO15",
"to": "TRO17",
"kind": "weiche"
},
{
"from": "TRO16",
"to": "TRO19",
"kind": "bahn"
},
{
"from": "TRO17",
"to": "TRO18",
"kind": "bahn"
},
{
"from": "TRO18",
"to": "TRO16",
"kind": "bahn"
},
{
"from": "TRO19",
"to": "SYS3",
"kind": "normal"
},
{
"from": "TRO19",
"to": "TRO20",
"kind": "bahn"
},
{
"from": "TRO20",
"to": "TRO01",
"kind": "bahn"
}
],
"openPoints": [],
"findings": [
"Scanner 0019 'Scanner :1': montiert an 0006-L, liest aber an Separator 0018 auf 0005",
"TRO16 (VF_5): Scanner 0019 am Separator - als 1Sep eingestuft. Pruefen, ob 1Sep_SSCC (SSCC-Scanner, Endmessung, WCS-Telegramm) erforderlich ist; das ist aus dem mechanischen Layout nicht erkennbar.",
"VF_1 Separator 0026: alternierendes Muster (3. von hinten) - als 1Sep statt Vario eingestuft",
"VF_1 Separator 0028: alternierendes Muster (1. von hinten) - als 1Sep statt Vario eingestuft",
"VF_2 Separator 0032: alternierendes Muster (1. von hinten) - als 1Sep statt Vario eingestuft",
"VF_3 Separator 0036: alternierendes Muster (1. von hinten) - als 1Sep statt Vario eingestuft",
"VF_4 Separator 0040: alternierendes Muster (1. von hinten) - als 1Sep statt Vario eingestuft",
"VF_5 Separator 0018: Zuordnung ohne TrackIds-Mitgliedschaft - als 1Sep statt Vario eingestuft",
"VF_5 Separator 0044: alternierendes Muster (1. von hinten) - als 1Sep statt Vario eingestuft"
]
}
+861
View File
@@ -0,0 +1,861 @@
// ============================================================
// FB_Main - GERUEST, erzeugt von lib/scl_skeleton.py
// Quelle : mubea_tro.json
// Erzeugt: <maskiert>
//
// Das ist KEIN lauffaehiges Programm, sondern ein Geruest zum
// Ausfuellen. Struktur, Reihenfolge und Bauteilzahl stammen aus dem
// Anlagenlayout und der vor Ort aufgenommenen Topologie.
//
// Jede Stelle, die aus der E-Planung kommen muss, ist mit
// 'TODO(E-Planung)' markiert - danach suchen, dann ist nichts vergessen.
// Offen sind durchgaengig: Sensor-/Aktoradressen (cInBG/MB/MA),
// Separator- und Weichennummern, MainTro-Nummern, die Staubereiche
// (DB_JamArea...) und die Zeiten, soweit als 'pruefen' vermerkt.
//
// Reihenfolge der REGIONs = Materialfluss.
// Anfang bei TRO03: Materialeingang ueber SYS1.
// ============================================================
FUNCTION_BLOCK "FB_Main"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR
TRO03 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0042
TRO05 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0044
TRO18 : "FB_ILS_MTRO_PinStore_Auto"; // PinStore_Auto, Sep 0066, 0069, 0072, 0075, 0078, 0081, 0084, 0087, 0090, 0093, 0096, 0099, 0102, 0105, 0108, 0111, 0114, 0117, 0120, 0123
TRO07 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0045
TRO10 : "FB_ILS_MTRO_2Sep2Swi"; // 2Sep2Swi, Sep 0005, 0036
TRO04 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0043
TRO01 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0040
TRO02 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0012
TRO11 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0058
TRO13 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0011
TRO12 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0059
TRO16 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0062
TRO17 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0063
TRO15 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0038
TRO06 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0003
TRO14 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0037
TRO08 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0054
TRO09 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0055
END_VAR
BEGIN
REGION TRO03 (1Sep) Sep 0042
// Anlagenkoordinate x/y: 10490 / -525 mm
// Vorgaenger: SYS1, TRO04
// Nachfolger: TRO05
// Einstufung: mittel
// Separator 1 = Bauteil 0042 aus dem Layout
#TRO03.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO03.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO03.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO03.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO03.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO03.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO03.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO03.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO03.stInPriorityManager.xReleaseOk := TRUE;
#TRO03(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO03,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von SYS1 (Station, kein TRO)
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO04
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO05
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO03,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO05 (1Sep) Sep 0044
// Anlagenkoordinate x/y: 10310 / -5013 mm
// Vorgaenger: TRO03
// Nachfolger: TRO18
// Einstufung: mittel
// Separator 1 = Bauteil 0044 aus dem Layout
#TRO05.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO05.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO05.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO05.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO05.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO05.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO05.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO05.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO05.stInPriorityManager.xReleaseOk := TRUE;
#TRO05(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO05,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO03
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO18
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO05,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO18 (PinStore_Auto) Sep 0066, 0069, 0072, 0075, 0078, 0081, 0084, 0087, 0090, 0093, 0096, 0099, 0102, 0105, 0108, 0111, 0114, 0117, 0120, 0123
// Anlagenkoordinate x/y: 958 / 4700 mm
// Vorgaenger: TRO05, TRO12
// Nachfolger: TRO07, TRO10
// Einstufung: hoch
// Separator 1 = Bauteil 0066 aus dem Layout
#TRO18.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO18.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO18.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO18.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO18.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO18.stInSeparator1.Settings.xPluggedScanner := TRUE;
#TRO18.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO18.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO18.stInBarcodeReader.Settings.xActivateCheckASCI := TRUE;
#TRO18.stInBarcodeReader.Settings.tTimeout := T#3000ms;
// TODO(E-Planung): Cognex-Interface verdrahten (#arCognexInterface["cScanner____"])
// TODO(E-Planung): Linienspeicher mit 19 Linien - Parametrierung je Linie
#TRO18.stInPriorityManager.xReleaseOk := TRUE;
#TRO18(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO18,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO05
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO12
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO07
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO10
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO18,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO07 (1Sep) Sep 0045
// Anlagenkoordinate x/y: 9510 / 14217 mm
// Vorgaenger: TRO09, TRO18
// Nachfolger: TRO04
// Einstufung: mittel
// Separator 1 = Bauteil 0045 aus dem Layout
#TRO07.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO07.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO07.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO07.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO07.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO07.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO07.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO07.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO07.stInPriorityManager.xReleaseOk := TRUE;
#TRO07(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO07,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO09
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO18
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO04
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO07,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO10 (2Sep2Swi) Sep 0005, 0036
// Anlagenkoordinate x/y: 1012 / -4650 mm
// Vorgaenger: TRO01, TRO06, TRO18
// Nachfolger: TRO01, TRO02, TRO11
// Einstufung: hoch
// Separator 1 = Bauteil 0005 aus dem Layout
#TRO10.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO10.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO10.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO10.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO10.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO10.stInSeparator1.Settings.xPluggedScanner := TRUE;
#TRO10.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
// Separator 2 = Bauteil 0036 aus dem Layout
#TRO10.stInSeparator2.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO10.stInSeparator2.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO10.stInSeparator2.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator2.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator2.Settings.tJam := "TimeForSepJam";
#TRO10.stInSeparator2.Settings.xPluggedJam := TRUE;
#TRO10.stInSeparator2.Settings.xPluggedPart := FALSE;
#TRO10.stInSeparator2.Settings.xPluggedScanner := TRUE;
#TRO10.stInSeparator2.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInSeparator2.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator2.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO10.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO10.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO10.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO10.stInSwitch1.Settings.nTo1Destinations := _; // TODO(E-Planung): dieser TRO hat 3 Abgaenge auf 2 Weichen - Aufteilung festlegen
#TRO10.stInSwitch2.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO10.stInSwitch2.Settings.xPluggedExSen3 := FALSE;
#TRO10.stInSwitch2.Settings.xPluggedExSen4 := FALSE;
#TRO10.stInSwitch2.Settings.nTo1Destinations := _; // TODO(E-Planung): dieser TRO hat 3 Abgaenge auf 2 Weichen - Aufteilung festlegen
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO01: TRO01
// ueber TRO02: SYS2, SYS3, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18
// ueber TRO11: TRO03, TRO04, TRO05, TRO07, TRO11, TRO12, TRO18
#TRO10.stInBarcodeReader1.Settings.xActivateCheckASCI := TRUE;
#TRO10.stInBarcodeReader1.Settings.tTimeout := T#3000ms;
// TODO(E-Planung): Cognex-Interface verdrahten (#arCognexInterface["cScanner____"])
#TRO10.stInBarcodeReader2.Settings.xActivateCheckASCI := TRUE;
#TRO10.stInBarcodeReader2.Settings.tTimeout := T#3000ms;
// TODO(E-Planung): Cognex-Interface verdrahten (#arCognexInterface["cScanner____"])
#TRO10.stInPriorityManager.xReleaseOk := TRUE;
#TRO10(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO10,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO01
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO06
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO18
stInOutJamEntr3 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO01
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO02
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
arInOutJamExit4 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO11
stInOutJamExit4 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutStopper2 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
xOutSw2ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO10,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO10.nInDirection1,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO10.nInDirection2,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO04 (1Sep) Sep 0043
// Anlagenkoordinate x/y: 10310 / 160 mm
// Vorgaenger: TRO07
// Nachfolger: TRO03
// Einstufung: mittel
// Separator 1 = Bauteil 0043 aus dem Layout
#TRO04.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO04.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO04.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO04.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO04.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO04.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO04.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO04.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO04.stInPriorityManager.xReleaseOk := TRUE;
#TRO04(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO04,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO07
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO03
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO04,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO01 (1Sep) Sep 0040
// Anlagenkoordinate x/y: 5355 / -5878 mm
// Vorgaenger: TRO10
// Nachfolger: TRO10
// Einstufung: mittel
// Separator 1 = Bauteil 0040 aus dem Layout
#TRO01.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO01.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO01.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO01.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO01.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO01.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO01.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO01.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO01.stInPriorityManager.xReleaseOk := TRUE;
#TRO01(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO01,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO10
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO10
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO01,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO02 (1Sep) Sep 0012
// Anlagenkoordinate x/y: -220 / -3472 mm
// Vorgaenger: TRO10
// Nachfolger: SYS2, SYS3, TRO13
// Einstufung: mittel
// Separator 1 = Bauteil 0012 aus dem Layout
#TRO02.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO02.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO02.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO02.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO02.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO02.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO02.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO02.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO02.stInPriorityManager.xReleaseOk := TRUE;
#TRO02(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO02,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO10
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach SYS2 (Station, kein TRO)
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach SYS3 (Station, kein TRO)
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
arInOutJamExit4 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO13
stInOutJamExit4 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO02,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO11 (Vario) Sep 0058
// Anlagenkoordinate x/y: 3300 / -4743 mm
// Vorgaenger: TRO10
// Nachfolger: TRO12
// Einstufung: hoch
// Separator 1 = Bauteil 0058 aus dem Layout
#TRO11.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO11.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO11.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO11.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO11.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO11.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO11.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO11.stInVario.Settings.xContinousEmptying := FALSE;
#TRO11.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO11.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO11.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO11.stInVario.Settings.tWaitForStop := t#3s;
#TRO11.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO11.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO11.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO11.stInVario.Settings.tJamSenDelay := T#2s;
#TRO11.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInPriorityManager.xReleaseOk := TRUE;
#TRO11(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO11,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO10
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO12
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO11,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO13 (1Sep1Swi) Sep 0011
// Anlagenkoordinate x/y: -220 / -481 mm
// Vorgaenger: TRO02
// Nachfolger: TRO16, TRO17
// Einstufung: mittel
// Separator 1 = Bauteil 0011 aus dem Layout
#TRO13.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO13.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO13.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO13.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO13.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO13.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO13.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO13.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO13.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO13.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO13.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO13.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO13.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO13.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO16: SYS2, SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO14, TRO15, TRO16, TRO17, TRO18
// ueber TRO17: SYS2, SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO17, TRO18
#TRO13.stInPriorityManager.xReleaseOk := TRUE;
#TRO13(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO13,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO02
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO16
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO17
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO13,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO13.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO12 (1Sep) Sep 0059
// Anlagenkoordinate x/y: 9412 / -4150 mm
// Vorgaenger: TRO11
// Nachfolger: TRO18
// Einstufung: mittel
// Separator 1 = Bauteil 0059 aus dem Layout
#TRO12.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO12.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO12.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO12.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO12.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO12.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO12.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO12.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO12.stInPriorityManager.xReleaseOk := TRUE;
#TRO12(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO12,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO11
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO18
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO12,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO16 (Vario) Sep 0062
// Anlagenkoordinate x/y: -899 / 1135 mm
// Vorgaenger: TRO13
// Nachfolger: TRO15
// Einstufung: hoch
// Separator 1 = Bauteil 0062 aus dem Layout
#TRO16.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO16.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO16.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO16.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO16.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO16.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO16.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO16.stInVario.Settings.xContinousEmptying := FALSE;
#TRO16.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO16.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO16.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO16.stInVario.Settings.tWaitForStop := t#3s;
#TRO16.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO16.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO16.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO16.stInVario.Settings.tJamSenDelay := T#2s;
#TRO16.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInPriorityManager.xReleaseOk := TRUE;
#TRO16(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO16,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO13
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO15
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO16,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO17 (1Sep) Sep 0063
// Anlagenkoordinate x/y: -703 / 12296 mm
// Vorgaenger: TRO13, TRO14
// Nachfolger: TRO06
// Einstufung: mittel
// Separator 1 = Bauteil 0063 aus dem Layout
#TRO17.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO17.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO17.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO17.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO17.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO17.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO17.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO17.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO17.stInPriorityManager.xReleaseOk := TRUE;
#TRO17(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO17,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO13
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO14
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO06
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO17,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO15 (1Sep) Sep 0038
// Anlagenkoordinate x/y: -1206 / 5330 mm
// Vorgaenger: TRO16
// Nachfolger: TRO14
// Einstufung: mittel
// Separator 1 = Bauteil 0038 aus dem Layout
#TRO15.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO15.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO15.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO15.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO15.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO15.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO15.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO15.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO15.stInPriorityManager.xReleaseOk := TRUE;
#TRO15(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO15,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO16
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO14
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO15,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO06 (1Sep1Swi) Sep 0003
// Anlagenkoordinate x/y: -220 / 13960 mm
// Vorgaenger: TRO17
// Nachfolger: TRO08, TRO10
// Einstufung: mittel
// Separator 1 = Bauteil 0003 aus dem Layout
#TRO06.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO06.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO06.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO06.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO06.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO06.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO06.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO06.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO06.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO06.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO06.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO06.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO06.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO06.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO06.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO08: SYS2, SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18
// ueber TRO10: SYS2, SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO07, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18
#TRO06.stInPriorityManager.xReleaseOk := TRUE;
#TRO06(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO06,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO17
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO08
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO10
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO06,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO06.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO14 (1Sep) Sep 0037
// Anlagenkoordinate x/y: -1026 / 10723 mm
// Vorgaenger: TRO15
// Nachfolger: TRO17
// Einstufung: mittel
// Separator 1 = Bauteil 0037 aus dem Layout
#TRO14.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO14.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO14.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO14.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO14.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO14.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO14.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO14.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO14.stInPriorityManager.xReleaseOk := TRUE;
#TRO14(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO14,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO15
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO17
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO14,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO08 (Vario) Sep 0054
// Anlagenkoordinate x/y: 3300 / 13510 mm
// Vorgaenger: TRO06
// Nachfolger: TRO09
// Einstufung: hoch
// Separator 1 = Bauteil 0054 aus dem Layout
#TRO08.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO08.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO08.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO08.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO08.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO08.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO08.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO08.stInVario.Settings.xContinousEmptying := FALSE;
#TRO08.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO08.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO08.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO08.stInVario.Settings.tWaitForStop := t#3s;
#TRO08.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO08.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO08.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO08.stInVario.Settings.tJamSenDelay := T#2s;
#TRO08.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInPriorityManager.xReleaseOk := TRUE;
#TRO08(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO08,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO06
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO09
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO08,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO09 (1Sep) Sep 0055
// Anlagenkoordinate x/y: 8953 / 13510 mm
// Vorgaenger: TRO08
// Nachfolger: TRO07
// Einstufung: mittel
// Separator 1 = Bauteil 0055 aus dem Layout
#TRO09.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO09.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO09.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO09.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO09.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO09.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO09.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO09.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO09.stInPriorityManager.xReleaseOk := TRUE;
#TRO09(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO09,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO08
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO07
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO09,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
END_FUNCTION_BLOCK
+872
View File
@@ -0,0 +1,872 @@
// ============================================================
// FB_Main - GERUEST, erzeugt von lib/scl_skeleton.py
// Quelle : mubea_tro.json
// Erzeugt: <maskiert>
//
// Das ist KEIN lauffaehiges Programm, sondern ein Geruest zum
// Ausfuellen. Struktur, Reihenfolge und Bauteilzahl stammen aus dem
// Anlagenlayout und der vor Ort aufgenommenen Topologie.
//
// Jede Stelle, die aus der E-Planung kommen muss, ist mit
// 'TODO(E-Planung)' markiert - danach suchen, dann ist nichts vergessen.
// Offen sind durchgaengig: Sensor-/Aktoradressen (cInBG/MB/MA),
// Separator- und Weichennummern, MainTro-Nummern, die Staubereiche
// (DB_JamArea...) und die Zeiten, soweit als 'pruefen' vermerkt.
//
// Reihenfolge der REGIONs = Materialfluss.
// Anfang bei TRO03: Materialeingang ueber SYS1.
//
// Aus Template : FB_ILS_MTRO_1Sep1Swi
// Generisch : FB_ILS_MTRO_1Sep, FB_ILS_MTRO_2Sep2Swi, FB_ILS_MTRO_PinStore_Auto, FB_ILS_MTRO_Vario (kein Template - von Hand pruefen)
// ============================================================
FUNCTION_BLOCK "FB_Main"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR
TRO03 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0042
TRO05 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0044
TRO18 : "FB_ILS_MTRO_PinStore_Auto"; // PinStore_Auto, Sep 0066, 0069, 0072, 0075, 0078, 0081, 0084, 0087, 0090, 0093, 0096, 0099, 0102, 0105, 0108, 0111, 0114, 0117, 0120, 0123
TRO07 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0045
TRO10 : "FB_ILS_MTRO_2Sep2Swi"; // 2Sep2Swi, Sep 0005, 0036
TRO04 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0043
TRO01 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0040
TRO02 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0012
TRO11 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0058
TRO13 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0011
TRO12 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0059
TRO16 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0062
TRO17 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0063
TRO15 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0038
TRO06 : "FB_ILS_MTRO_1Sep1Swi"; // 1Sep1Swi, Sep 0003
TRO14 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0037
TRO08 : "FB_ILS_MTRO_Vario"; // Vario, Sep 0054
TRO09 : "FB_ILS_MTRO_1Sep"; // 1Sep, Sep 0055
END_VAR
BEGIN
REGION TRO03 (1Sep) Sep 0042
// Anlagenkoordinate x/y: 10490 / -525 mm
// Vorgaenger: SYS1, TRO04
// Nachfolger: TRO05
// Einstufung: mittel
// Separator 1 = Bauteil 0042 aus dem Layout
#TRO03.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO03.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO03.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO03.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO03.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO03.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO03.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO03.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO03.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO03.stInPriorityManager.xReleaseOk := TRUE;
#TRO03(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO03,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von SYS1 (Station, kein TRO)
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO04
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO05
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO03,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO05 (1Sep) Sep 0044
// Anlagenkoordinate x/y: 10310 / -5013 mm
// Vorgaenger: TRO03
// Nachfolger: TRO18
// Einstufung: mittel
// Separator 1 = Bauteil 0044 aus dem Layout
#TRO05.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO05.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO05.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO05.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO05.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO05.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO05.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO05.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO05.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO05.stInPriorityManager.xReleaseOk := TRUE;
#TRO05(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO05,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO03
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO18
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO05,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO18 (PinStore_Auto) Sep 0066, 0069, 0072, 0075, 0078, 0081, 0084, 0087, 0090, 0093, 0096, 0099, 0102, 0105, 0108, 0111, 0114, 0117, 0120, 0123
// Anlagenkoordinate x/y: 958 / 4700 mm
// Vorgaenger: TRO05, TRO12
// Nachfolger: TRO07, TRO10
// Einstufung: hoch
// Separator 1 = Bauteil 0066 aus dem Layout
#TRO18.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO18.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO18.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO18.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO18.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO18.stInSeparator1.Settings.xPluggedScanner := TRUE;
#TRO18.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO18.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO18.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO18.stInBarcodeReader.Settings.xActivateCheckASCI := TRUE;
#TRO18.stInBarcodeReader.Settings.tTimeout := T#3000ms;
// TODO(E-Planung): Cognex-Interface verdrahten (#arCognexInterface["cScanner____"])
// TODO(E-Planung): Linienspeicher mit 19 Linien - Parametrierung je Linie
#TRO18.stInPriorityManager.xReleaseOk := TRUE;
#TRO18(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO18,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO05
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO12
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO07
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO10
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO18,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO07 (1Sep) Sep 0045
// Anlagenkoordinate x/y: 9510 / 14217 mm
// Vorgaenger: TRO09, TRO18
// Nachfolger: TRO04
// Einstufung: mittel
// Separator 1 = Bauteil 0045 aus dem Layout
#TRO07.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO07.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO07.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO07.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO07.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO07.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO07.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO07.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO07.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO07.stInPriorityManager.xReleaseOk := TRUE;
#TRO07(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO07,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO09
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO18
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO04
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO07,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO10 (2Sep2Swi) Sep 0005, 0036
// Anlagenkoordinate x/y: 1012 / -4650 mm
// Vorgaenger: TRO01, TRO06, TRO18
// Nachfolger: TRO01, TRO02, TRO11
// Einstufung: hoch
// Separator 1 = Bauteil 0005 aus dem Layout
#TRO10.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO10.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO10.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO10.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO10.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO10.stInSeparator1.Settings.xPluggedScanner := TRUE;
#TRO10.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
// Separator 2 = Bauteil 0036 aus dem Layout
#TRO10.stInSeparator2.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO10.stInSeparator2.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO10.stInSeparator2.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator2.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator2.Settings.tJam := "TimeForSepJam";
#TRO10.stInSeparator2.Settings.xPluggedJam := TRUE;
#TRO10.stInSeparator2.Settings.xPluggedPart := FALSE;
#TRO10.stInSeparator2.Settings.xPluggedScanner := TRUE;
#TRO10.stInSeparator2.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInSeparator2.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator2.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO10.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO10.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO10.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO10.stInSwitch1.Settings.nTo1Destinations := _; // TODO(E-Planung): dieser TRO hat 3 Abgaenge auf 2 Weichen - Aufteilung festlegen
#TRO10.stInSwitch2.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO10.stInSwitch2.Settings.xPluggedExSen3 := FALSE;
#TRO10.stInSwitch2.Settings.xPluggedExSen4 := FALSE;
#TRO10.stInSwitch2.Settings.nTo1Destinations := _; // TODO(E-Planung): dieser TRO hat 3 Abgaenge auf 2 Weichen - Aufteilung festlegen
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO01: TRO01
// ueber TRO02: SYS2, SYS3, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18
// ueber TRO11: TRO03, TRO04, TRO05, TRO07, TRO11, TRO12, TRO18
#TRO10.stInBarcodeReader1.Settings.xActivateCheckASCI := TRUE;
#TRO10.stInBarcodeReader1.Settings.tTimeout := T#3000ms;
// TODO(E-Planung): Cognex-Interface verdrahten (#arCognexInterface["cScanner____"])
#TRO10.stInBarcodeReader2.Settings.xActivateCheckASCI := TRUE;
#TRO10.stInBarcodeReader2.Settings.tTimeout := T#3000ms;
// TODO(E-Planung): Cognex-Interface verdrahten (#arCognexInterface["cScanner____"])
#TRO10.stInPriorityManager.xReleaseOk := TRUE;
#TRO10(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO10,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO01
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO06
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO18
stInOutJamEntr3 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO01
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO02
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
arInOutJamExit4 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO11
stInOutJamExit4 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutStopper2 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
xOutSw2ExTo3 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO10,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO10.nInDirection1,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO10.nInDirection2,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
END_REGION
END_REGION
REGION TRO04 (1Sep) Sep 0043
// Anlagenkoordinate x/y: 10310 / 160 mm
// Vorgaenger: TRO07
// Nachfolger: TRO03
// Einstufung: mittel
// Separator 1 = Bauteil 0043 aus dem Layout
#TRO04.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO04.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO04.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO04.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO04.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO04.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO04.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO04.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO04.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO04.stInPriorityManager.xReleaseOk := TRUE;
#TRO04(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO04,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO07
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO03
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO04,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO01 (1Sep) Sep 0040
// Anlagenkoordinate x/y: 5355 / -5878 mm
// Vorgaenger: TRO10
// Nachfolger: TRO10
// Einstufung: mittel
// Separator 1 = Bauteil 0040 aus dem Layout
#TRO01.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO01.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO01.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO01.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO01.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO01.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO01.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO01.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO01.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO01.stInPriorityManager.xReleaseOk := TRUE;
#TRO01(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO01,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO10
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO10
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO01,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO02 (1Sep) Sep 0012
// Anlagenkoordinate x/y: -220 / -3472 mm
// Vorgaenger: TRO10
// Nachfolger: SYS2, SYS3, TRO13
// Einstufung: mittel
// Separator 1 = Bauteil 0012 aus dem Layout
#TRO02.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO02.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO02.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO02.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO02.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO02.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO02.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO02.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO02.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO02.stInPriorityManager.xReleaseOk := TRUE;
#TRO02(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO02,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO10
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach SYS2 (Station, kein TRO)
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach SYS3 (Station, kein TRO)
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
arInOutJamExit4 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO13
stInOutJamExit4 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO02,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO11 (Vario) Sep 0058
// Anlagenkoordinate x/y: 3300 / -4743 mm
// Vorgaenger: TRO10
// Nachfolger: TRO12
// Einstufung: hoch
// Separator 1 = Bauteil 0058 aus dem Layout
#TRO11.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO11.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO11.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO11.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO11.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO11.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO11.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO11.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO11.stInVario.Settings.xContinousEmptying := FALSE;
#TRO11.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO11.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO11.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO11.stInVario.Settings.tWaitForStop := t#3s;
#TRO11.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO11.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO11.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO11.stInVario.Settings.tJamSenDelay := T#2s;
#TRO11.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO11.stInPriorityManager.xReleaseOk := TRUE;
#TRO11(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO11,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO10
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO12
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO11,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO13 (1Sep1Swi) Sep 0011
// Anlagenkoordinate x/y: -220 / -481 mm
// Vorgaenger: TRO02
// Nachfolger: TRO16, TRO17
// Einstufung: mittel
// Aufbau nach Template FB_ILS_MTRO_1Sep1Swi.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates)
// Separator 1 = Bauteil 0011 aus dem Layout
#TRO13.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO13.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO13.stInSeparator1.Settings.tTrailingTime := t#100ms; // TODO(E-Planung): pruefen
#TRO13.stInSeparator1.Settings.tHandlingTime := t#50ms; // TODO(E-Planung): pruefen
#TRO13.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO13.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO13.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO13.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO13.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInSenJam2 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInSenJam3 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO13.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO13.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO13.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO13.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie - TODO(E-Planung): pruefen (Info fuer HMI; Referenz TRO107 hat 3 bei 2 Abgaengen)
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO16: SYS2, SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO14, TRO15, TRO16, TRO17, TRO18
// ueber TRO17: SYS2, SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO06, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO17, TRO18
#TRO13.stInSettings.xPrioDir2 := TRUE; // TODO(E-Planung)
#TRO13(stInPriorityManagerDir2 := "DB_Prozessdaten".stPriorityManager.udt_____.TroIn, // TODO(E-Planung)
stOutPriorityManagerDir2 => "DB_Prozessdaten".stPriorityManager.udt_____.TroOut, // TODO(E-Planung)
nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInCarouselRun1 := #fbCarousel____.xOutConveyorFullSpeed, // TODO(E-Planung) - nur am Kreisel, sonst Zeile loeschen
xInRelease := TRUE,
stInOutMachineState := #stInOutControlUnitCabinet, // TODO(E-Planung) - Schaltschrank
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO02
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO16
stInOutJamExit2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO17
stInOutJamExit3 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO13,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"], // TODO(E-Planung)
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____"); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO13.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]); // TODO(E-Planung)
END_REGION
END_REGION
REGION TRO12 (1Sep) Sep 0059
// Anlagenkoordinate x/y: 9412 / -4150 mm
// Vorgaenger: TRO11
// Nachfolger: TRO18
// Einstufung: mittel
// Separator 1 = Bauteil 0059 aus dem Layout
#TRO12.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO12.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO12.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO12.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO12.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO12.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO12.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO12.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO12.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO12.stInPriorityManager.xReleaseOk := TRUE;
#TRO12(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO12,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO11
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO18
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO12,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO16 (Vario) Sep 0062
// Anlagenkoordinate x/y: -899 / 1135 mm
// Vorgaenger: TRO13
// Nachfolger: TRO15
// Einstufung: hoch
// Separator 1 = Bauteil 0062 aus dem Layout
#TRO16.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO16.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO16.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO16.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO16.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO16.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO16.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO16.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO16.stInVario.Settings.xContinousEmptying := FALSE;
#TRO16.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO16.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO16.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO16.stInVario.Settings.tWaitForStop := t#3s;
#TRO16.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO16.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO16.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO16.stInVario.Settings.tJamSenDelay := T#2s;
#TRO16.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO16.stInPriorityManager.xReleaseOk := TRUE;
#TRO16(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO16,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO13
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO15
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO16,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO17 (1Sep) Sep 0063
// Anlagenkoordinate x/y: -703 / 12296 mm
// Vorgaenger: TRO13, TRO14
// Nachfolger: TRO06
// Einstufung: mittel
// Separator 1 = Bauteil 0063 aus dem Layout
#TRO17.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO17.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO17.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO17.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO17.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO17.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO17.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO17.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO17.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO17.stInPriorityManager.xReleaseOk := TRUE;
#TRO17(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO17,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO13
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO14
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO06
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO17,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO15 (1Sep) Sep 0038
// Anlagenkoordinate x/y: -1206 / 5330 mm
// Vorgaenger: TRO16
// Nachfolger: TRO14
// Einstufung: mittel
// Separator 1 = Bauteil 0038 aus dem Layout
#TRO15.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO15.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO15.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO15.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO15.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO15.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO15.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO15.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO15.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO15.stInPriorityManager.xReleaseOk := TRUE;
#TRO15(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO15,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO16
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO14
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO15,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO06 (1Sep1Swi) Sep 0003
// Anlagenkoordinate x/y: -220 / 13960 mm
// Vorgaenger: TRO17
// Nachfolger: TRO08, TRO10
// Einstufung: mittel
// Aufbau nach Template FB_ILS_MTRO_1Sep1Swi.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates)
// Separator 1 = Bauteil 0003 aus dem Layout
#TRO06.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO06.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO06.stInSeparator1.Settings.tTrailingTime := t#100ms; // TODO(E-Planung): pruefen
#TRO06.stInSeparator1.Settings.tHandlingTime := t#50ms; // TODO(E-Planung): pruefen
#TRO06.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO06.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO06.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO06.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO06.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO06.stInSenJam2 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO06.stInSenJam3 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO06.stInSwitch1.Settings.nSwitchNo := "cSwi_____"; // TODO(E-Planung)
#TRO06.stInSwitch1.Settings.xPluggedExSen3 := FALSE;
#TRO06.stInSwitch1.Settings.xPluggedExSen4 := FALSE;
#TRO06.stInSwitch1.Settings.nTo1Destinations := 2; // Abgaenge laut Topologie - TODO(E-Planung): pruefen (Info fuer HMI; Referenz TRO107 hat 3 bei 2 Abgaengen)
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
// ueber TRO08: SYS2, SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO07, TRO08, TRO09, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18
// ueber TRO10: SYS2, SYS3, TRO01, TRO02, TRO03, TRO04, TRO05, TRO07, TRO10, TRO11, TRO12, TRO13, TRO14, TRO15, TRO16, TRO17, TRO18
#TRO06.stInSettings.xPrioDir2 := TRUE; // TODO(E-Planung)
#TRO06(stInPriorityManagerDir2 := "DB_Prozessdaten".stPriorityManager.udt_____.TroIn, // TODO(E-Planung)
stOutPriorityManagerDir2 => "DB_Prozessdaten".stPriorityManager.udt_____.TroOut, // TODO(E-Planung)
nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInCarouselRun1 := #fbCarousel____.xOutConveyorFullSpeed, // TODO(E-Planung) - nur am Kreisel, sonst Zeile loeschen
xInRelease := TRUE,
stInOutMachineState := #stInOutControlUnitCabinet, // TODO(E-Planung) - Schaltschrank
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO17
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO08
stInOutJamExit2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO10
stInOutJamExit3 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO06,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"], // TODO(E-Planung)
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____"); // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO06.nInDirection,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]); // TODO(E-Planung)
END_REGION
END_REGION
REGION TRO14 (1Sep) Sep 0037
// Anlagenkoordinate x/y: -1026 / 10723 mm
// Vorgaenger: TRO15
// Nachfolger: TRO17
// Einstufung: mittel
// Separator 1 = Bauteil 0037 aus dem Layout
#TRO14.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO14.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO14.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO14.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO14.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO14.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO14.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO14.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO14.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO14.stInPriorityManager.xReleaseOk := TRUE;
#TRO14(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO14,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO15
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO17
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO14,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO08 (Vario) Sep 0054
// Anlagenkoordinate x/y: 3300 / 13510 mm
// Vorgaenger: TRO06
// Nachfolger: TRO09
// Einstufung: hoch
// Separator 1 = Bauteil 0054 aus dem Layout
#TRO08.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO08.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO08.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO08.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO08.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO08.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO08.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO08.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO08.stInVario.Settings.xContinousEmptying := FALSE;
#TRO08.stInVario.Settings.tWaitForJog := T#300ms; // TODO(E-Planung): pruefen
#TRO08.stInVario.Settings.tConvEmpty := T#45000ms; // TODO(E-Planung): pruefen
#TRO08.stInVario.Settings.nCountCarrier := 1; // TODO(E-Planung): pruefen
#TRO08.stInVario.Settings.tWaitForStop := t#3s;
#TRO08.stInVario.Settings.tCarrierInPosDelay := t#1200ms;
#TRO08.stInVario.Settings.tCarrierInPosEdgeDelay := t#100ms;
#TRO08.stInVario.Settings.xJamSenDelayActive := TRUE;
#TRO08.stInVario.Settings.tJamSenDelay := T#2s;
#TRO08.stInVario.stSenCarrInPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInVario.stSenFinger := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInVario.stSenLastPos := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInVario.stSenJam := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO08.stInPriorityManager.xReleaseOk := TRUE;
#TRO08(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO08,
xInMotorProtection := "FC____", // TODO(E-Planung)
xInAutomatic := #t_automatik,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO06
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO09
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutVarioMotor => "MA____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO08,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
REGION TRO09 (1Sep) Sep 0055
// Anlagenkoordinate x/y: 8953 / 13510 mm
// Vorgaenger: TRO08
// Nachfolger: TRO07
// Einstufung: mittel
// Separator 1 = Bauteil 0055 aus dem Layout
#TRO09.stInSeparator1.Settings.nSeparatorNo := "cSep_____"; // TODO(E-Planung)
#TRO09.stInSeparator1.Settings.tDelayToNextItem := "TimeForSepWaiting_Short";
#TRO09.stInSeparator1.Settings.tTrailingTime := t#600ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tHandlingTime := t#200ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tJam := "TimeForSepJam";
#TRO09.stInSeparator1.Settings.xPluggedJam := TRUE;
#TRO09.stInSeparator1.Settings.xPluggedPart := FALSE;
#TRO09.stInSeparator1.Settings.xPluggedScanner := FALSE;
#TRO09.stInSeparator1.stSenInSep := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO09.stInSeparator1.Settings.tSenFree := T#1500ms; // TODO(E-Planung): pruefen
#TRO09.stInSeparator1.Settings.tSenWait := T#4000ms; // TODO(E-Planung): pruefen
#TRO09.stInPriorityManager.xReleaseOk := TRUE;
#TRO09(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInRelease := "DB_TRO_TEST".TRO09,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO08
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO07
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
xOutStopper1 => "MB____", // TODO(E-Planung)
stInOutHMI := "DB_Interface_HMI".stTRO.TRO09,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
END_REGION
END_FUNCTION_BLOCK
+907
View File
@@ -0,0 +1,907 @@
{
"schema": "sps_skel-tro-v2",
"source": "mubea.csv",
"created": "2026-10-09 11:38",
"note": "Aus dem CSV-Export abgeleitet (lib/tro_flow.py) - die Zeichnung ist nur Ansicht, keine Datenquelle.",
"tros": [
{
"id": "TRO01",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0040"
],
"predecessors": [
"TRO10"
],
"successors": [
"TRO10"
],
"position": {
"x": 5355.05,
"y": -5878.0,
"z": 1555.5
},
"label": "Separator 0040 auf Kreisel1 Bahn R",
"hosts": [
"0001-R"
],
"scanners": [],
"reason": "einzelner Separator auf angetriebener Kreisel-Bahn",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO02",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0012"
],
"predecessors": [
"TRO10"
],
"successors": [
"SYS2",
"SYS3",
"TRO13"
],
"position": {
"x": -220.0,
"y": -3472.47,
"z": 1554.75
},
"label": "Separator 0012 auf Kreisel2 Bahn L",
"hosts": [
"0002-L"
],
"scanners": [
"0007"
],
"reason": "Separator mit Scanner auf angetriebener Kreisel-Bahn",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO03",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0042"
],
"predecessors": [
"SYS1",
"TRO04"
],
"successors": [
"TRO05"
],
"position": {
"x": 10490.0,
"y": -525.02,
"z": 2028.75
},
"label": "Separator 0042 auf Kreisel3 Bahn R",
"hosts": [
"0010-R"
],
"scanners": [
"0008"
],
"reason": "Separator mit Scanner auf angetriebener Kreisel-Bahn",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO04",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0043"
],
"predecessors": [
"TRO07"
],
"successors": [
"TRO03"
],
"position": {
"x": 10310.0,
"y": 159.95,
"z": 2029.5
},
"label": "Separator 0043 auf Kreisel3 Bahn R",
"hosts": [
"0010-R"
],
"scanners": [],
"reason": "einzelner Separator auf angetriebener Kreisel-Bahn",
"colocated": [
"TRO05"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO05",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0044"
],
"predecessors": [
"TRO03"
],
"successors": [
"TRO18"
],
"position": {
"x": 10310.0,
"y": -5013.05,
"z": 2029.5
},
"label": "Separator 0044 auf Kreisel3 Bahn R",
"hosts": [
"0010-R"
],
"scanners": [],
"reason": "einzelner Separator auf angetriebener Kreisel-Bahn",
"colocated": [
"TRO04"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO06",
"type": "1Sep1Swi",
"confidence": "mittel",
"separators": [
"0003"
],
"predecessors": [
"TRO17"
],
"successors": [
"TRO08",
"TRO10"
],
"position": {
"x": -220.0,
"y": 13960.02,
"z": 1554.75
},
"label": "Separator 0003 an Ausschleuselement 0053 (Strecke 0013, Anfang)",
"hosts": [
"0013"
],
"scanners": [
"0004"
],
"reason": "899mm von Ausschleuselement 0053 entfernt - kein eigenes Weichen-Bauteil im Layout, das Ausschleuselement uebernimmt diese Rolle",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep1Swi",
"items": {
"Separator": 1,
"Switch": 1
}
},
{
"id": "TRO07",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0045"
],
"predecessors": [
"TRO09",
"TRO18"
],
"successors": [
"TRO04"
],
"position": {
"x": 9510.0,
"y": 14217.05,
"z": 2029.5
},
"label": "VF_1",
"hosts": [
"0013"
],
"scanners": [],
"reason": "Separator 0045: Zuordnung zeigt auf VF_1, ist aber nicht Teil von dessen TrackIds-Kette - kein eigenes VF treibt ihn an",
"colocated": [
"TRO08"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO08",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0054"
],
"predecessors": [
"TRO06"
],
"successors": [
"TRO09"
],
"position": {
"x": 3299.55,
"y": 13509.62,
"z": 1416.12
},
"label": "VF_1",
"hosts": [
"0013"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: Auf)",
"colocated": [
"TRO07"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO09",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0055"
],
"predecessors": [
"TRO08"
],
"successors": [
"TRO07"
],
"position": {
"x": 8953.1,
"y": 13509.62,
"z": 2179.73
},
"label": "VF_1",
"hosts": [
"0013"
],
"scanners": [],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_1 rueckwaerts (1. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO10",
"type": "2Sep2Swi",
"confidence": "hoch",
"separators": [
"0005",
"0036"
],
"predecessors": [
"TRO01",
"TRO06",
"TRO18"
],
"successors": [
"TRO01",
"TRO02",
"TRO11"
],
"position": {
"x": 1012.49,
"y": -4649.76,
"z": 1554.75
},
"label": "Uebergabestelle Kreisel2: Ausschleuselement 0057 + ILS Weiche 0125",
"hosts": [
"0014"
],
"scanners": [
"0006",
"0041"
],
"reason": "Ausschleuselement 0057 (Separator 0005) und ILS Weiche 0125 (Separator 0036) liegen in der TrackIds-Kette von Kreisel2 direkt hintereinander - eine Uebergabestelle",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 4,
"fbType": "FB_ILS_MTRO_2Sep2Swi",
"items": {
"Separator": 2,
"Switch": 2,
"Scanner": 2
}
},
{
"id": "TRO11",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0058"
],
"predecessors": [
"TRO10"
],
"successors": [
"TRO12"
],
"position": {
"x": 3299.55,
"y": -4743.38,
"z": 1416.12
},
"label": "VF_2",
"hosts": [
"0014"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: Auf)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO12",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0059"
],
"predecessors": [
"TRO11"
],
"successors": [
"TRO18"
],
"position": {
"x": 9411.55,
"y": -4150.19,
"z": 2103.86
},
"label": "VF_2",
"hosts": [
"0014"
],
"scanners": [
"0046"
],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_2 rueckwaerts (1. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO13",
"type": "1Sep1Swi",
"confidence": "mittel",
"separators": [
"0011"
],
"predecessors": [
"TRO02"
],
"successors": [
"TRO16",
"TRO17"
],
"position": {
"x": -220.0,
"y": -480.98,
"z": 1554.75
},
"label": "Separator 0011 an Ausschleuselement 0061 (Strecke 0015, Anfang)",
"hosts": [
"0015"
],
"scanners": [
"0009"
],
"reason": "832mm von Ausschleuselement 0061 entfernt - kein eigenes Weichen-Bauteil im Layout, das Ausschleuselement uebernimmt diese Rolle",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep1Swi",
"items": {
"Separator": 1,
"Switch": 1
}
},
{
"id": "TRO14",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0037"
],
"predecessors": [
"TRO15"
],
"successors": [
"TRO17"
],
"position": {
"x": -1026.0,
"y": 10723.05,
"z": 1634.5
},
"label": "VF_3",
"hosts": [
"0015"
],
"scanners": [],
"reason": "Separator 0037: Zuordnung zeigt auf VF_3, ist aber nicht Teil von dessen TrackIds-Kette - kein eigenes VF treibt ihn an",
"colocated": [
"TRO16"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO15",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0038"
],
"predecessors": [
"TRO16"
],
"successors": [
"TRO14"
],
"position": {
"x": -1206.0,
"y": 5330.02,
"z": 1477.75
},
"label": "VF_3",
"hosts": [
"0015"
],
"scanners": [
"0039"
],
"reason": "Separator 0038: Zuordnung zeigt auf VF_3, ist aber nicht Teil von dessen TrackIds-Kette - kein eigenes VF treibt ihn an",
"colocated": [
"TRO17"
],
"positionFrom": "Bauteile",
"positionPoints": 2,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO16",
"type": "Vario",
"confidence": "hoch",
"separators": [
"0062"
],
"predecessors": [
"TRO13"
],
"successors": [
"TRO15"
],
"position": {
"x": -898.87,
"y": 1134.6,
"z": 1534.33
},
"label": "VF_3",
"hosts": [
"0015"
],
"scanners": [],
"reason": "angetriebenes Streckensegment (Antriebfahrtrichtung: Auf)",
"colocated": [
"TRO14",
"TRO17"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_Vario",
"items": {
"Separator": 1,
"VarioDrive": 1
}
},
{
"id": "TRO17",
"type": "1Sep",
"confidence": "mittel",
"separators": [
"0063"
],
"predecessors": [
"TRO13",
"TRO14"
],
"successors": [
"TRO06"
],
"position": {
"x": -702.98,
"y": 12296.45,
"z": 1751.35
},
"label": "VF_3",
"hosts": [
"0015"
],
"scanners": [],
"reason": "alternierendes VF/GF-Muster vom Wiedereinschleusen von VF_3 rueckwaerts (1. Separator von hinten) - unbetriebener Abschnitt ohne eigenes VarioDrive (Review 2026-09-23/25)",
"colocated": [
"TRO15",
"TRO16"
],
"positionFrom": "Bauteile",
"positionPoints": 1,
"fbType": "FB_ILS_MTRO_1Sep",
"items": {
"Separator": 1
}
},
{
"id": "TRO18",
"type": "PinStore_Auto",
"confidence": "hoch",
"separators": [
"0066",
"0069",
"0072",
"0075",
"0078",
"0081",
"0084",
"0087",
"0090",
"0093",
"0096",
"0099",
"0102",
"0105",
"0108",
"0111",
"0114",
"0117",
"0120",
"0123"
],
"predecessors": [
"TRO05",
"TRO12"
],
"successors": [
"TRO07",
"TRO10"
],
"position": {
"x": 958.0,
"y": 4700.0,
"z": 1697.6
},
"label": "Speicher (20 Schwerkraftlinien)",
"hosts": [
"0016",
"0017",
"0018",
"0019",
"0020",
"0021",
"0022",
"0023",
"0024",
"0025",
"0026",
"0027",
"0028",
"0029",
"0030",
"0031",
"0032",
"0033",
"0034",
"0035"
],
"scanners": [],
"reason": "20 Gefaellestrecken mit je eigenem Separator, gemeinsamer Zu-/Ablauf - Muster eines Linienspeichers",
"colocated": [],
"positionFrom": "Bauteile",
"positionPoints": 20,
"fbType": "FB_ILS_MTRO_PinStore_Auto",
"items": {
"Separator": 1,
"StorageLine": 19,
"Scanner": 1,
"Encoder": 1
}
}
],
"boundaries": [
{
"id": "SYS1",
"type": "Materialeingang",
"confidence": "hoch",
"separators": [],
"predecessors": [],
"successors": [
"TRO03"
],
"position": {
"x": 10410.95,
"y": 3.52,
"z": 1983.31
},
"label": "BTMT Beladung :1",
"hosts": [
"0047"
],
"scanners": [],
"reason": "Systemgrenze (Be-/Entladestation) - kein TRO, nur Materialein-/ausgang",
"colocated": [],
"positionFrom": "Host-Objekte",
"positionPoints": 1,
"fbType": "",
"items": {}
},
{
"id": "SYS2",
"type": "Materialausgang",
"confidence": "hoch",
"separators": [],
"predecessors": [
"TRO02"
],
"successors": [],
"position": {
"x": -778.79,
"y": -1226.1,
"z": 1401.09
},
"label": "BTMT Entladung :2",
"hosts": [
"0048"
],
"scanners": [],
"reason": "Systemgrenze (Be-/Entladestation) - kein TRO, nur Materialein-/ausgang",
"colocated": [],
"positionFrom": "Host-Objekte",
"positionPoints": 1,
"fbType": "",
"items": {}
},
{
"id": "SYS3",
"type": "Materialausgang",
"confidence": "hoch",
"separators": [],
"predecessors": [
"TRO02"
],
"successors": [],
"position": {
"x": -775.22,
"y": -2466.46,
"z": 1401.09
},
"label": "BTMT Entladung :1",
"hosts": [
"0049"
],
"scanners": [],
"reason": "Systemgrenze (Be-/Entladestation) - kein TRO, nur Materialein-/ausgang",
"colocated": [],
"positionFrom": "Host-Objekte",
"positionPoints": 1,
"fbType": "",
"items": {}
}
],
"connections": [
{
"from": "SYS1",
"to": "TRO03",
"kind": "normal"
},
{
"from": "TRO01",
"to": "TRO10",
"kind": "normal"
},
{
"from": "TRO02",
"to": "SYS2",
"kind": "normal"
},
{
"from": "TRO02",
"to": "SYS3",
"kind": "normal"
},
{
"from": "TRO02",
"to": "TRO13",
"kind": "transfer"
},
{
"from": "TRO03",
"to": "TRO05",
"kind": "bahn"
},
{
"from": "TRO04",
"to": "TRO03",
"kind": "bahn"
},
{
"from": "TRO05",
"to": "TRO18",
"kind": "normal"
},
{
"from": "TRO06",
"to": "TRO08",
"kind": "weiche"
},
{
"from": "TRO06",
"to": "TRO10",
"kind": "bahn"
},
{
"from": "TRO07",
"to": "TRO04",
"kind": "bahn"
},
{
"from": "TRO08",
"to": "TRO09",
"kind": "bahn"
},
{
"from": "TRO09",
"to": "TRO07",
"kind": "bahn"
},
{
"from": "TRO10",
"to": "TRO01",
"kind": "bahn"
},
{
"from": "TRO10",
"to": "TRO02",
"kind": "bahn"
},
{
"from": "TRO10",
"to": "TRO11",
"kind": "weiche"
},
{
"from": "TRO11",
"to": "TRO12",
"kind": "bahn"
},
{
"from": "TRO12",
"to": "TRO18",
"kind": "normal"
},
{
"from": "TRO13",
"to": "TRO16",
"kind": "weiche"
},
{
"from": "TRO13",
"to": "TRO17",
"kind": "bahn"
},
{
"from": "TRO14",
"to": "TRO17",
"kind": "bahn"
},
{
"from": "TRO15",
"to": "TRO14",
"kind": "bahn"
},
{
"from": "TRO16",
"to": "TRO15",
"kind": "bahn"
},
{
"from": "TRO17",
"to": "TRO06",
"kind": "normal"
},
{
"from": "TRO18",
"to": "TRO07",
"kind": "normal"
},
{
"from": "TRO18",
"to": "TRO10",
"kind": "normal"
}
],
"openPoints": [],
"findings": [
"Kreisel2: Ausschleuselement 0057 und ILS Weiche 0125 benachbart - als 2Sep2Swi zusammengefasst (FB_ILS_MTRO_2Sep2Swi fehlt noch in der ILSLib)",
"Scanner 0008 'Scanner :5': montiert an 0010, liest aber an Separator 0042 auf 0010-R",
"Scanner 0046 'Scanner :1': montiert an 0035, liest aber an Separator 0059 auf 0014",
"TRO02 (Separator 0012 auf Kreisel2 Bahn L): Scanner 0007 am Separator - als 1Sep eingestuft. Pruefen, ob 1Sep_SSCC (SSCC-Scanner, Endmessung, WCS-Telegramm) erforderlich ist; das ist aus dem mechanischen Layout nicht erkennbar.",
"TRO03 (Separator 0042 auf Kreisel3 Bahn R): Scanner 0008 am Separator - als 1Sep eingestuft. Pruefen, ob 1Sep_SSCC (SSCC-Scanner, Endmessung, WCS-Telegramm) erforderlich ist; das ist aus dem mechanischen Layout nicht erkennbar.",
"TRO12 (VF_2): Scanner 0046 am Separator - als 1Sep eingestuft. Pruefen, ob 1Sep_SSCC (SSCC-Scanner, Endmessung, WCS-Telegramm) erforderlich ist; das ist aus dem mechanischen Layout nicht erkennbar.",
"TRO15 (VF_3): Scanner 0039 am Separator - als 1Sep eingestuft. Pruefen, ob 1Sep_SSCC (SSCC-Scanner, Endmessung, WCS-Telegramm) erforderlich ist; das ist aus dem mechanischen Layout nicht erkennbar.",
"VF_1 Separator 0045: Zuordnung ohne TrackIds-Mitgliedschaft - als 1Sep statt Vario eingestuft",
"VF_1 Separator 0055: alternierendes Muster (1. von hinten) - als 1Sep statt Vario eingestuft",
"VF_2 Separator 0059: alternierendes Muster (1. von hinten) - als 1Sep statt Vario eingestuft",
"VF_3 Separator 0037: Zuordnung ohne TrackIds-Mitgliedschaft - als 1Sep statt Vario eingestuft",
"VF_3 Separator 0038: Zuordnung ohne TrackIds-Mitgliedschaft - als 1Sep statt Vario eingestuft",
"VF_3 Separator 0063: alternierendes Muster (1. von hinten) - als 1Sep statt Vario eingestuft"
]
}
+128
View File
@@ -0,0 +1,128 @@
# -*- coding: utf-8 -*-
"""Tests fuer lib/scl_context.py - TroDocument -> Render-Kontext.
Die komplette Ausgabe sichern die Golden-Files (test_scl_skeleton_golden.py);
hier stehen die Ableitungen einzeln, auf die sich Templates (Schritt 3) und
Namensregeln (Schritt 4) aus doc/SCL_Templates.md verlassen.
"""
from pathlib import Path
import pytest
from model import Analysis, DerivedTro, TroDocument
from scl_context import SclName, build_context, flow_order
from scl_skeleton import load_document
FIXTURES = Path(__file__).resolve().parent / "fixtures" / "scl"
def _tro(tro_id: str, type_name: str, **extra) -> DerivedTro:
data = dict(
tro_id=tro_id,
type_name=type_name,
label=f"Label {tro_id}",
hosts=["0001"],
separators=["0040"],
scanners=[],
reason="Test",
)
data.update(extra)
return DerivedTro(**data)
@pytest.fixture
def kontext():
"""SYS1 -> TRO01 (1 Weiche) -> TRO02 -> SYS2 und TRO01 -> TRO03 (Vario)."""
analysis = Analysis(tros=[
_tro("TRO01", "1Sep1Swi", predecessors=["SYS1"], successors=["TRO02", "TRO03"]),
_tro("TRO02", "1Sep", separators=["0041"], predecessors=["TRO01"],
successors=["SYS2"]),
_tro("TRO03", "Vario", separators=[], predecessors=["TRO01"]),
])
document = TroDocument.from_analysis(analysis, source="test.csv")
return build_context(document, "test_tro.json", created="2026-01-01 00:00")
def _by_id(context, tro_id):
return next(t for t in context.tros if t.id == tro_id)
def test_reihenfolge_und_startgrund(kontext):
assert [t.id for t in kontext.tros] == ["TRO01", "TRO02", "TRO03"]
assert kontext.start_reason == "Materialeingang ueber SYS1"
assert kontext.created == "2026-01-01 00:00"
def test_nummernteil_wie_geschrieben():
"""{nr} fuer die Namensregeln: fuehrende Nullen bleiben stehen."""
analysis = Analysis(tros=[_tro("TRO07", "1Sep"), _tro("TRO107", "1Sep"),
_tro("XY", "1Sep")])
ctx = build_context(TroDocument.from_analysis(analysis, source="t"), "t")
assert {t.id: t.nr for t in ctx.tros} == {"TRO07": "07", "TRO107": "107", "XY": ""}
def test_staubereiche_nummerierung(kontext):
"""Eingaenge ab 1, Ausgaenge ab 2 - wie in den Referenz-Aufrufstellen."""
tro = _by_id(kontext, "TRO01")
assert [(j.n, j.neighbour) for j in tro.jam_entries] == [
(1, "SYS1 (Station, kein TRO)")]
assert [(j.n, j.neighbour) for j in tro.jam_exits] == [(2, "TRO02"), (3, "TRO03")]
def test_eine_weiche_bedient_alle_abgaenge(kontext):
tro = _by_id(kontext, "TRO01")
assert len(tro.switches) == 1
weiche = tro.switches[0]
assert weiche.to1_destinations == 2
assert weiche.direction_target == "#TRO01.nInDirection"
assert [(e.via, e.targets) for e in tro.switch_exits] == [
("TRO02", ["SYS2", "TRO02"]), ("TRO03", ["TRO03"])]
def test_mehrere_weichen_keine_geratene_aufteilung():
"""2Sep2Swi (mubea): nTo1Destinations bleibt offen, Richtung je Weiche."""
ctx = build_context(load_document(FIXTURES / "mubea_tro.json"), "mubea_tro.json")
tro = next(t for t in ctx.tros if t.type == "2Sep2Swi")
assert [w.to1_destinations for w in tro.switches] == [None, None]
assert [w.direction_target for w in tro.switches] == [
f"#{tro.id}.nInDirection1", f"#{tro.id}.nInDirection2"]
def test_separatoren_aus_dem_layout(kontext):
"""Mehr Separatoren laut Typ als im Layout -> '?' statt Fehler."""
assert [s.layout for s in _by_id(kontext, "TRO01").separators] == ["0040"]
assert [s.layout for s in _by_id(kontext, "TRO03").separators] == ["?"]
def test_vario_nur_beim_vario_typ(kontext):
vario = _by_id(kontext, "TRO03")
assert vario.has_vario
assert list(vario.vario_sensors) == [
"stSenCarrInPos", "stSenFinger", "stSenLastPos", "stSenJam"]
assert _by_id(kontext, "TRO02").vario_sensors == {}
def test_heute_sind_alle_namen_offen(kontext):
"""Bis zu den Namensregeln (Schritt 4) ist jeder Name ein TODO-Platzhalter."""
namen: list[SclName] = []
for tro in kontext.tros:
namen += [tro.main_tro, tro.safety, tro.motor_protection, tro.vario_motor,
tro.machine_state, tro.priority_udt, tro.prio_dir2, tro.carousel_run]
namen += [j.sensor for j in tro.jam_exits]
assert all(j.sensor is None for j in tro.jam_entries)
namen += [n for s in tro.separators for n in (s.no, s.sensor, s.stopper)]
namen += [n for w in tro.switches for n in (w.no, w.valve, w.jam_db)]
namen += [j.db for j in tro.jam_entries + tro.jam_exits]
namen += list(tro.vario_sensors.values())
assert namen and all(n.todo for n in namen)
def test_flow_order_kreislauf_ohne_eingang():
analysis = Analysis(tros=[
_tro("TRO02", "1Sep", predecessors=["TRO01"], successors=["TRO01"]),
_tro("TRO01", "1Sep", predecessors=["TRO02"], successors=["TRO02"]),
])
geordnet, grund = flow_order(analysis.tros)
assert [t.tro_id for t in geordnet] == ["TRO01", "TRO02"]
assert grund.startswith("Kreislauf ohne Eingang")
+130
View File
@@ -0,0 +1,130 @@
# -*- coding: utf-8 -*-
"""Golden-File-Tests fuer scl_skeleton.py - die komplette FB_Main-Ausgabe.
Schritt 1 aus doc/SCL_Templates.md (§8.3, §11): die heutige Ausgabe wird
festgeschrieben, bevor der Generator auf Templates umgebaut wird. Solange kein
Template eingeschaltet ist, muss jede SCL byte-gleich zur Referenz bleiben.
Eingaben: tests/fixtures/scl/<name>_tro.json - feste Kopien der TRO-JSON aus
tro_flow --json, damit nur scl_skeleton geprueft wird und nicht tro_flow.
Erwartung: tests/fixtures/scl/<name>_FB_Main.scl, Zeitstempel maskiert.
Eine gewollte Aenderung der Ausgabe (z. B. ein Template wird eingeschaltet):
Diff pruefen, dann die Referenzen neu schreiben mit
set SKEL_UPDATE_GOLDEN=1 & python -m pytest tests/test_scl_skeleton_golden.py
"""
import os
import re
from pathlib import Path
import pytest
import scl_skeleton
from scl_skeleton import TEMPLATE_DIR, SclTemplates, load_document, render
FIXTURES = Path(__file__).resolve().parent / "fixtures" / "scl"
# mubea: alle fuenf dort vorkommenden Typen, auch 2Sep2Swi (ohne Template);
# HundM05: die Referenzanlage der TRO-Templates.
PROJEKTE = ["mubea", "HundM05"]
# Die einzige Zeile, die sich von Lauf zu Lauf aendert.
_ZEITSTEMPEL = re.compile(r"^// Erzeugt: .*$", re.MULTILINE)
_MASKE = "// Erzeugt: <maskiert>"
def _maskiert(text: str) -> str:
return _ZEITSTEMPEL.sub(_MASKE, text)
def _aktualisieren() -> bool:
return os.environ.get("SKEL_UPDATE_GOLDEN") == "1"
def _vergleichen(ist: str, referenz: Path) -> None:
if _aktualisieren():
referenz.write_text(ist, encoding="utf-8", newline="\n")
pytest.skip(f"Referenz neu geschrieben: {referenz.name}")
assert referenz.is_file(), (
f"{referenz.name} fehlt - mit SKEL_UPDATE_GOLDEN=1 erzeugen")
soll = referenz.read_text(encoding="utf-8")
if ist != soll:
# Erste abweichende Zeile nennen; der volle Diff ist bei ~900 Zeilen
# in der pytest-Ausgabe nicht lesbar.
ist_z, soll_z = ist.splitlines(), soll.splitlines()
for nr, (a, b) in enumerate(zip(ist_z, soll_z), start=1):
if a != b:
pytest.fail(f"{referenz.name} Zeile {nr}:\n soll: {b}\n ist : {a}")
pytest.fail(f"{referenz.name}: {len(ist_z)} statt {len(soll_z)} Zeilen")
@pytest.mark.parametrize("name", PROJEKTE)
def test_render_wie_referenz(name: str) -> None:
"""render() liefert byte-gleich die festgeschriebene SCL."""
quelle = f"{name}_tro.json"
document = load_document(FIXTURES / quelle)
_vergleichen(_maskiert(render(document, quelle)), FIXTURES / f"{name}_FB_Main.scl")
@pytest.mark.parametrize("name", PROJEKTE)
def test_render_mit_templates_wie_referenz(name: str) -> None:
"""--templates: TROs mit Template aus dem Template, der Rest generisch.
Eigene Referenz <name>_FB_Main_templates.scl. Eine Aenderung an einem
Template zeigt sich hier als Diff - pruefen, dann neu schreiben.
"""
quelle = f"{name}_tro.json"
document = load_document(FIXTURES / quelle)
text = render(document, quelle, templates=SclTemplates(TEMPLATE_DIR))
_vergleichen(_maskiert(text), FIXTURES / f"{name}_FB_Main_templates.scl")
@pytest.mark.parametrize("name", PROJEKTE)
def test_cli_schreibt_referenz(name: str, tmp_path: Path, monkeypatch) -> None:
"""Der CLI-Weg: Exit 0, Dateiname <name>_FB_Main.scl, Inhalt wie render().
Das ist der Vertrag, auf den sich ein Workflow verlaesst (doc/SCL_Templates.md §12).
"""
if _aktualisieren():
pytest.skip("Referenzen werden nur ueber test_render_wie_referenz geschrieben")
monkeypatch.setenv("SKEL_RESULTS", str(tmp_path))
exit_code = scl_skeleton.main(["--json", str(FIXTURES / f"{name}_tro.json")])
assert exit_code == 0
ausgabe = tmp_path / f"{name}_FB_Main.scl"
assert ausgabe.is_file()
soll = (FIXTURES / f"{name}_FB_Main.scl").read_text(encoding="utf-8")
assert _maskiert(ausgabe.read_text(encoding="utf-8")) == soll
def test_cli_templates_und_strict(tmp_path: Path, monkeypatch) -> None:
"""--templates schreibt die Template-Referenz; --strict bricht ab, solange
ein FB-Typ der Anlage (mubea: u. a. 2Sep2Swi) kein Template hat."""
if _aktualisieren():
pytest.skip("Referenzen werden nur ueber die render-Tests geschrieben")
monkeypatch.setenv("SKEL_RESULTS", str(tmp_path))
json_file = str(FIXTURES / "mubea_tro.json")
assert scl_skeleton.main(["--json", json_file, "--templates"]) == 0
soll = (FIXTURES / "mubea_FB_Main_templates.scl").read_text(encoding="utf-8")
ist = (tmp_path / "mubea_FB_Main.scl").read_text(encoding="utf-8")
assert _maskiert(ist) == soll
(tmp_path / "mubea_FB_Main.scl").unlink()
assert scl_skeleton.main(["--json", json_file, "--templates", "--strict"]) == 1
assert not (tmp_path / "mubea_FB_Main.scl").exists()
assert scl_skeleton.main(["--json", json_file, "--templates",
str(tmp_path / "gibt_es_nicht")]) == 1
def test_todo_marker_bleiben_zaehlbar() -> None:
"""Die Zahl der offenen Stellen ist eine Qualitaetsgroesse im Workflow.
Sie darf sich nur mit Absicht aendern (dann Referenz neu schreiben).
"""
for name in PROJEKTE:
text = (FIXTURES / f"{name}_FB_Main.scl").read_text(encoding="utf-8")
assert text.count(scl_skeleton.TODO) > 0, name
+133
View File
@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
"""Rundlauf der FB-Templates gegen die realen Aufrufstellen (doc/SCL_Templates.md §8.1).
Je Template: Kontext mit den ECHTEN Werten der Referenz-Aufrufstelle bauen
(TRO-Nummer, Sensoren, Ventile, Staubereiche ...), Template rendern und mit dem
REGION-Block der Referenz in doc/TRO_Katalog/scl_templates/ vergleichen.
Verglichen wird normalisiert: Kommentare und Leerzeilen weg, Leerraum
zusammengefasst. Stimmt das, hat die Parametrisierung nichts verloren -
gleiche Zeilen, gleiche Reihenfolge, gleiche Werte.
Wird eine Referenzdatei durch eine neuere Aufrufstelle ersetzt, zeigt dieser
Test genau die Zeilen, denen das Template folgen muss.
"""
import re
from pathlib import Path
import pytest
from model import Analysis, DerivedTro, TroDocument
from scl_context import SclName, SclTro, build_context
from scl_skeleton import TEMPLATE_DIR, SclTemplates, load_document, render
ROOT = Path(__file__).resolve().parent.parent
REFERENZ = ROOT / "doc" / "TRO_Katalog" / "scl_templates"
FIXTURES = Path(__file__).resolve().parent / "fixtures" / "scl"
def _name(wert: str) -> SclName:
"""Ein bekannter Name aus der Referenz - also nicht mehr offen."""
return SclName(value=wert, todo=False)
def _normalisiert(text: str) -> list[str]:
zeilen = []
for zeile in text.splitlines():
zeile = re.sub(r"//.*$", "", zeile) # Kommentar
zeile = re.sub(r"\s+", " ", zeile).strip() # Leerraum
if zeile:
zeilen.append(zeile)
return zeilen
def _referenz_region(datei: str) -> list[str]:
"""Vom ersten 'REGION' bis zum letzten 'END_REGION' der Referenzdatei."""
zeilen = (REFERENZ / datei).read_text(encoding="utf-8-sig").splitlines()
anfang = next(i for i, z in enumerate(zeilen) if z.startswith("REGION "))
ende = max(i for i, z in enumerate(zeilen) if z.strip() == "END_REGION")
return _normalisiert("\n".join(zeilen[anfang:ende + 1]))
def _kontext(tro_id: str, type_name: str, vorgaenger: list[str],
nachfolger: list[str]) -> SclTro:
"""Kontext eines TRO mit der Topologie der Referenzstelle."""
tro = DerivedTro(tro_id=tro_id, type_name=type_name, label=tro_id, hosts=[],
separators=["0001"], scanners=[], reason="Referenz",
predecessors=vorgaenger, successors=nachfolger)
document = TroDocument.from_analysis(Analysis(tros=[tro]), source="referenz")
return build_context(document, "referenz").tros[0]
def _vergleich(ist: list[str], soll: list[str]) -> None:
for nr, (a, b) in enumerate(zip(ist, soll), start=1):
assert a == b, f"Zeile {nr}:\n Referenz: {b}\n Template: {a}"
assert len(ist) == len(soll), (
f"{len(ist)} statt {len(soll)} Zeilen; zuviel/fehlend: "
f"{ist[len(soll):] or soll[len(ist):]}")
@pytest.fixture(scope="module")
def templates() -> SclTemplates:
return SclTemplates(TEMPLATE_DIR)
def test_1sep1swi_wie_tro107(templates):
"""FB_ILS_MTRO_1Sep1Swi gegen TRO 107 (=A01+UH01-KF00 FB_Main)."""
t = _kontext("TRO107", "1Sep1Swi", ["TRO106"], ["TRO108", "TRO110"])
t.region_title = "TRO 107(1Sep1Swi)"
sep = t.separators[0]
sep.no = _name("cSep107.1")
sep.sensor = _name("cInBG3306")
sep.stopper = _name("MB3306")
t.jam_exits[0].sensor = _name("cInBG3305")
t.jam_exits[1].sensor = _name("cInBG3330")
weiche = t.switches[0]
weiche.no = _name("cSwi107.1")
weiche.valve = _name("MB3304")
weiche.to1_destinations = 3 # Referenz: 3 Ziele bei 2 Abgaengen (§13)
weiche.jam_db = _name('"DB_JamArea0102".stJam0102_1')
t.prio_dir2 = _name("TRUE")
t.priority_udt = _name("udt_TRO107")
t.main_tro = _name("cMainTro107")
t.safety = _name('"DB_InterfaceSafety".stFromSafety.EStopMainOF1.Q')
t.carousel_run = _name("#fbCarousel0102.xOutConveyorFullSpeed")
t.machine_state = _name("#stInOutControlUnitCabinetOF1")
t.jam_entries[0].db = _name('"DB_JamArea0102".stJam0102_1')
t.jam_exits[0].db = _name('"DB_JamArea0103".stJam0103_1')
t.jam_exits[1].db = _name('"DB_JamArea0102".stJam0102_2')
ist = _normalisiert(templates.render(t))
_vergleich(ist, _referenz_region("FB_ILS_MTRO_1Sep1Swi.scl"))
def test_template_ohne_bekannte_namen_hat_nur_markierte_luecken(templates):
"""Mit den heutigen Platzhaltern: jede offene Stelle traegt den TODO-Marker."""
t = _kontext("TRO07", "1Sep1Swi", ["SYS1"], ["TRO08", "TRO09"])
text = templates.render(t)
for zeile in text.splitlines():
if "____" in zeile.split("//")[0]:
assert "TODO(E-Planung)" in zeile, zeile
@pytest.mark.parametrize("name", ["mubea", "HundM05"])
def test_jedes_template_rendert_fuer_echte_anlagen(name, templates):
"""StrictUndefined: ein Tippfehler im Template faellt hier auf, nicht erst beim Kunden."""
document = load_document(FIXTURES / f"{name}_tro.json")
text = render(document, f"{name}_tro.json", templates=templates)
regionen = [z for z in text.splitlines() if z.startswith("REGION ")]
assert len(regionen) == len(document.tros)
assert "// Aus Template : FB_ILS_MTRO_1Sep1Swi" in text
def test_strikter_undefined_bricht_ab(tmp_path):
"""Unbekannte Variable im Template -> Fehler statt leerer SCL-Stelle."""
(tmp_path / "FB_X.scl.j2").write_text("REGION {{ t.gibt_es_nicht }}\n", encoding="utf-8")
t = _kontext("TRO01", "1Sep", [], [])
t.fb = "FB_X"
with pytest.raises(Exception):
SclTemplates(tmp_path).render(t)