From 4895ebf5ed4caceeffa61fbb1fdd413925537281 Mon Sep 17 00:00:00 2001 From: Samer Ayadi Date: Fri, 9 Oct 2026 18:06:18 +0200 Subject: [PATCH] SCL aus parametrisierten Templates: Golden-Files, Render-Kontext, Pilot 1Sep1Swi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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, 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 --- CLAUDE.md | 8 + doc/Commandlines.md | 7 +- doc/Python_Scripts.md | 27 + doc/SCL_Templates.md | 492 ++++++++ lib/scl_context.py | 383 +++++++ lib/scl_skeleton.py | 453 ++++---- lib/scl_templates/FB_ILS_MTRO_1Sep1Swi.scl.j2 | 64 ++ lib/scl_templates/_macros.scl.j2 | 103 ++ requirements.txt | 3 + tests/fixtures/scl/HundM05_FB_Main.scl | 981 ++++++++++++++++ .../scl/HundM05_FB_Main_templates.scl | 1004 +++++++++++++++++ tests/fixtures/scl/HundM05_tro.json | 932 +++++++++++++++ tests/fixtures/scl/mubea_FB_Main.scl | 861 ++++++++++++++ .../fixtures/scl/mubea_FB_Main_templates.scl | 872 ++++++++++++++ tests/fixtures/scl/mubea_tro.json | 907 +++++++++++++++ tests/test_scl_context.py | 128 +++ tests/test_scl_skeleton_golden.py | 130 +++ tests/test_scl_templates.py | 133 +++ 18 files changed, 7276 insertions(+), 212 deletions(-) create mode 100644 doc/SCL_Templates.md create mode 100644 lib/scl_context.py create mode 100644 lib/scl_templates/FB_ILS_MTRO_1Sep1Swi.scl.j2 create mode 100644 lib/scl_templates/_macros.scl.j2 create mode 100644 tests/fixtures/scl/HundM05_FB_Main.scl create mode 100644 tests/fixtures/scl/HundM05_FB_Main_templates.scl create mode 100644 tests/fixtures/scl/HundM05_tro.json create mode 100644 tests/fixtures/scl/mubea_FB_Main.scl create mode 100644 tests/fixtures/scl/mubea_FB_Main_templates.scl create mode 100644 tests/fixtures/scl/mubea_tro.json create mode 100644 tests/test_scl_context.py create mode 100644 tests/test_scl_skeleton_golden.py create mode 100644 tests/test_scl_templates.py diff --git a/CLAUDE.md b/CLAUDE.md index a6555c4..484eb32 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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/.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 `_tro.json` (schema `sps_skel-tro-v2`, `model.TroDocument`): TROs, system boundaries `SYSn`, connections with diff --git a/doc/Commandlines.md b/doc/Commandlines.md index 9d7cbd3..4bde249 100644 --- a/doc/Commandlines.md +++ b/doc/Commandlines.md @@ -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` | `_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 diff --git a/doc/Python_Scripts.md b/doc/Python_Scripts.md index ef24804..c707687 100644 --- a/doc/Python_Scripts.md +++ b/doc/Python_Scripts.md @@ -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/.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`, `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 diff --git a/doc/SCL_Templates.md b/doc/SCL_Templates.md new file mode 100644 index 0000000..a616a69 --- /dev/null +++ b/doc/SCL_Templates.md @@ -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 ─► _tro.json ─► scl_skeleton ─► _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) +│ └── _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/ + ├── _tro.json fixed inputs (mubea, HundM05) + ├── _FB_Main.scl expected output, generic + └── _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 … .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".`) | 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%/_scl_naming.ini` — per project, `` = 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 .csv --json +bin\scl_skeleton.bat --json _tro.json [--templates [DIR]] [--strict] [--naming ] +``` + +`--templates` and `--strict` exist today; `--naming` follows with step 4. + +**Inputs:** + +| File | Where | Who writes it | +|---|---|---| +| `.csv` | `%SKEL_DATA%` | dxfmakros `EXPORTCSV` | +| `_tro.json` | `%SKEL_RESULTS%` | `tro_flow --json` (schema `sps_skel-tro-v2`) | +| `scl_naming.ini`, `_scl_naming.ini` | `%SKEL_CFG%` | you, once per project (optional) | +| `lib/scl_templates/*.scl.j2` | repo | maintained with the PLC engineers | + +**Outputs:** `%SKEL_RESULTS%/_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. diff --git a/lib/scl_context.py b/lib/scl_context.py new file mode 100644 index 0000000..997e1f4 --- /dev/null +++ b/lib/scl_context.py @@ -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-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-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 / JamExit).""" + + model_config = _CONFIG + + n: int + # Nachbar als Text fuer den Kommentar, SYSn als Station markiert + neighbour: str + db: SclName + # Stausensor des Ausgangs (stInSenJam); 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], + ) diff --git a/lib/scl_skeleton.py b/lib/scl_skeleton.py index c3e7258..b24cd2e 100644 --- a/lib/scl_skeleton.py +++ b/lib/scl_skeleton.py @@ -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) diff --git a/lib/scl_templates/FB_ILS_MTRO_1Sep1Swi.scl.j2 b/lib/scl_templates/FB_ILS_MTRO_1Sep1Swi.scl.j2 new file mode 100644 index 0000000..5e550ce --- /dev/null +++ b/lib/scl_templates/FB_ILS_MTRO_1Sep1Swi.scl.j2 @@ -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 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 diff --git a/lib/scl_templates/_macros.scl.j2 b/lib/scl_templates/_macros.scl.j2 new file mode 100644 index 0000000..bcefce8 --- /dev/null +++ b/lib/scl_templates/_macros.scl.j2 @@ -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: 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: 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: 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 %} diff --git a/requirements.txt b/requirements.txt index 67bcdde..2264059 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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 diff --git a/tests/fixtures/scl/HundM05_FB_Main.scl b/tests/fixtures/scl/HundM05_FB_Main.scl new file mode 100644 index 0000000..7921a3d --- /dev/null +++ b/tests/fixtures/scl/HundM05_FB_Main.scl @@ -0,0 +1,981 @@ +// ============================================================ +// FB_Main - GERUEST, erzeugt von lib/scl_skeleton.py +// Quelle : HundM05_tro.json +// Erzeugt: +// +// 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 diff --git a/tests/fixtures/scl/HundM05_FB_Main_templates.scl b/tests/fixtures/scl/HundM05_FB_Main_templates.scl new file mode 100644 index 0000000..8eaf49b --- /dev/null +++ b/tests/fixtures/scl/HundM05_FB_Main_templates.scl @@ -0,0 +1,1004 @@ +// ============================================================ +// FB_Main - GERUEST, erzeugt von lib/scl_skeleton.py +// Quelle : HundM05_tro.json +// Erzeugt: +// +// 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. +// +// Aus Template : FB_ILS_MTRO_1Sep1Swi +// Generisch : FB_ILS_MTRO_1Sep, FB_ILS_MTRO_Vario (kein Template - von Hand pruefen) +// ============================================================ + +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 + // Aufbau nach Template FB_ILS_MTRO_1Sep1Swi.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates) + + // 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#100ms; // TODO(E-Planung): pruefen + #TRO01.stInSeparator1.Settings.tHandlingTime := t#50ms; // 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.stInSenJam2 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung) + #TRO01.stInSenJam3 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung) + + #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 - 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 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.stInSettings.xPrioDir2 := TRUE; // TODO(E-Planung) + #TRO01(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 TRO20 + stInOutJamEntr1 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO02 + stInOutJamExit2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO06 + stInOutJamExit3 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + stInOutHMI := "DB_Interface_HMI".stTRO.TRO01, + 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 => #TRO01.nInDirection, + InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]); // TODO(E-Planung) + + 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 + // Aufbau nach Template FB_ILS_MTRO_1Sep1Swi.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates) + + // 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#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 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.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 TRO01 + stInOutJamEntr1 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO05 + stInOutJamEntr2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO07 + stInOutJamExit2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO09 + 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 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 + // Aufbau nach Template FB_ILS_MTRO_1Sep1Swi.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates) + + // 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#100ms; // TODO(E-Planung): pruefen + #TRO09.stInSeparator1.Settings.tHandlingTime := t#50ms; // 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.stInSenJam2 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung) + #TRO09.stInSenJam3 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung) + + #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 - 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 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.stInSettings.xPrioDir2 := TRUE; // TODO(E-Planung) + #TRO09(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 TRO06 + stInOutJamEntr1 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO08 + stInOutJamEntr2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO10 + stInOutJamExit2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO12 + stInOutJamExit3 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + stInOutHMI := "DB_Interface_HMI".stTRO.TRO09, + 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 => #TRO09.nInDirection, + InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]); // TODO(E-Planung) + + 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 + // Aufbau nach Template FB_ILS_MTRO_1Sep1Swi.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates) + + // 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#100ms; // TODO(E-Planung): pruefen + #TRO12.stInSeparator1.Settings.tHandlingTime := t#50ms; // 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.stInSenJam2 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung) + #TRO12.stInSenJam3 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung) + + #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 - 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 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.stInSettings.xPrioDir2 := TRUE; // TODO(E-Planung) + #TRO12(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 TRO09 + stInOutJamEntr1 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO11 + stInOutJamEntr2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO13 + stInOutJamExit2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich nach TRO15 + stInOutJamExit3 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + stInOutHMI := "DB_Interface_HMI".stTRO.TRO12, + 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 => #TRO12.nInDirection, + InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]); // TODO(E-Planung) + + 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 + // Aufbau nach Template FB_ILS_MTRO_1Sep1Swi.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates) + + // 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#100ms; // TODO(E-Planung): pruefen + #TRO15.stInSeparator1.Settings.tHandlingTime := t#50ms; // 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.stInSenJam2 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung) + #TRO15.stInSenJam3 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung) + + #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 - 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: 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.stInSettings.xPrioDir2 := TRUE; // TODO(E-Planung) + #TRO15(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 TRO12 + stInOutJamEntr1 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung) + arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich von TRO14 + stInOutJamEntr2 := "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.TRO15, + 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 => #TRO15.nInDirection, + InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]); // TODO(E-Planung) + + 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 diff --git a/tests/fixtures/scl/HundM05_tro.json b/tests/fixtures/scl/HundM05_tro.json new file mode 100644 index 0000000..18745c4 --- /dev/null +++ b/tests/fixtures/scl/HundM05_tro.json @@ -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" + ] +} diff --git a/tests/fixtures/scl/mubea_FB_Main.scl b/tests/fixtures/scl/mubea_FB_Main.scl new file mode 100644 index 0000000..efd89fd --- /dev/null +++ b/tests/fixtures/scl/mubea_FB_Main.scl @@ -0,0 +1,861 @@ +// ============================================================ +// FB_Main - GERUEST, erzeugt von lib/scl_skeleton.py +// Quelle : mubea_tro.json +// Erzeugt: +// +// 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 diff --git a/tests/fixtures/scl/mubea_FB_Main_templates.scl b/tests/fixtures/scl/mubea_FB_Main_templates.scl new file mode 100644 index 0000000..fa112bb --- /dev/null +++ b/tests/fixtures/scl/mubea_FB_Main_templates.scl @@ -0,0 +1,872 @@ +// ============================================================ +// FB_Main - GERUEST, erzeugt von lib/scl_skeleton.py +// Quelle : mubea_tro.json +// Erzeugt: +// +// 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 diff --git a/tests/fixtures/scl/mubea_tro.json b/tests/fixtures/scl/mubea_tro.json new file mode 100644 index 0000000..9273618 --- /dev/null +++ b/tests/fixtures/scl/mubea_tro.json @@ -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" + ] +} diff --git a/tests/test_scl_context.py b/tests/test_scl_context.py new file mode 100644 index 0000000..26cd1d2 --- /dev/null +++ b/tests/test_scl_context.py @@ -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") diff --git a/tests/test_scl_skeleton_golden.py b/tests/test_scl_skeleton_golden.py new file mode 100644 index 0000000..e9f25fd --- /dev/null +++ b/tests/test_scl_skeleton_golden.py @@ -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/_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/_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: " + + +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 _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 _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 diff --git a/tests/test_scl_templates.py b/tests/test_scl_templates.py new file mode 100644 index 0000000..1a86955 --- /dev/null +++ b/tests/test_scl_templates.py @@ -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)