scl_templates: Aufruf-Template FB_ILS_MTRO_2Sep2Swi (ohne Referenz-Aufrufstelle)

Mubea wird damit vollstaendig aus Templates erzeugt. Der FB existiert noch
nicht in der ILSLib; die Schnittstelle ist aus 2Sep1Swi (Separatoren) und
1Sep2Swi (Weichen) angenommen und steht im Template-Kopf - mit den
SPS-Kollegen abzustimmen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Michael StanglandClaude Opus 5.5 committed 2026-10-28 23:13:02 +01:00
1 parent dd955999a9
commit 25ab362c0a
7 files changed
+207 -44

No files matched your search

+6 -3
View File
@@ -180,9 +180,12 @@ Inside the SCL output, `lib/scl_context.py` (TRO-JSON → render context, all de
sits between `model.py` and `scl_skeleton.py` (context → text only). With `--templates`
(opt-in) REGIONs come from Jinja2 templates in `lib/scl_templates/<fbType>.scl.j2`
(all 7 types with a reference call site: `1Sep`, `1Sep1Swi`, `1Sep2Swi`, `1Sep_SSCC`,
`Vario`, `Vario_workStation`, `PinStore_Auto`; `2Sep1Swi`, `EmptyCarrBuffer`, `LoadingBoom`,
`2Sep2Swi` stay generic until a call site exists), each round-trip tested against its reference call site
in `doc/TRO_Katalog/scl_templates/` (`tests/test_scl_templates.py`); every line holding a
`Vario`, `Vario_workStation`, `PinStore_Auto`; `2Sep1Swi`, `EmptyCarrBuffer`, `LoadingBoom`
stay generic until a call site exists), each round-trip tested against its reference call site
in `doc/TRO_Katalog/scl_templates/` (`tests/test_scl_templates.py`). Exception: `2Sep2Swi`
has a template WITHOUT reference call site (the FB does not exist in the ILSLib yet - its
interface is assumed from `2Sep1Swi` + `1Sep2Swi`, see the template header; only covered by
rendering the real plants and the golden file); 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.
+9 -4
View File
@@ -626,8 +626,10 @@ with a real reference call site (`1Sep`, `1Sep1Swi`, `1Sep2Swi`, `1Sep_SSCC`,
`Vario`, `Vario_workStation`, `PinStore_Auto`); each follows its call site in
`doc/TRO_Katalog/scl_templates/` line for line, and every value that is still
open carries `TODO(E-Planung)`. The line decisions are proposals to be confirmed
by a PLC engineer (`doc/SCL_Templates.md` §6). `2Sep1Swi`, `EmptyCarrBuffer`,
`LoadingBoom` and `2Sep2Swi` have no call site yet and stay generic. `--strict` stops (exit `1`, no SCL) if any FB type has no
by a PLC engineer (`doc/SCL_Templates.md` §6). `2Sep1Swi`, `EmptyCarrBuffer` and
`LoadingBoom` have no call site yet and stay generic. `2Sep2Swi` has a template without
a call site (FB not yet in the ILSLib, interface assumed from `2Sep1Swi` + `1Sep2Swi`).
`--strict` stops (exit `1`, no SCL) if any FB type has no
template. Without `--templates` the output is unchanged.
**Names from the plant JSON (stage 4, `--json <csv>_anlage.json`).** The
@@ -975,8 +977,11 @@ verified against `data/*.scl` where the source is vendored locally, and against
> Kreisel2/Kreisel1 touch as a single control object with 2 separators,
> 2 scanners and 2 switches. **`FB_ILS_MTRO_2Sep2Swi` does not exist** in this
> repository or in `doc/TRO_Katalog/scl_templates/`, and has to be created in
> the ILSLib — otherwise a future SCL generator will emit a call to a missing
> block. The closest verified type is `2Sep1Swi` (2 separators, 2 scanners,
> the ILSLib — otherwise the generated FB_Main calls a missing block. Since
> 2026-10-28 there is a call-site template `lib/scl_templates/FB_ILS_MTRO_2Sep2Swi.scl.j2`
> whose header lists the assumed interface (separators as in `2Sep1Swi`, switches
> as in `1Sep2Swi`) - the FB has to be created to match it, or the template
> adjusted. The closest verified type is `2Sep1Swi` (2 separators, 2 scanners,
> **1** switch), which matches the hardware actually present in that export.
> `3Sep2Swi` (3 separators, 3 scanners, 2 switches) was added on 2026-10-14
> for the test plant `data/export.csv`, where one Kreisel pulley touches two
+13 -8
View File
@@ -66,10 +66,12 @@ Coverage per catalog type (`lib/tro_catalog.py`):
| `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) |
| `2Sep2Swi` | `FB_ILS_MTRO_2Sep2Swi` | **no** | **no** | ✅ done WITHOUT reference (2026-10-28) — FB does not exist yet (Mubea needs it); interface assumed from `2Sep1Swi` (separators) + `1Sep2Swi` (switches), see template header |
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).
interface until someone supplies a real call site. `2Sep2Swi` has a template that is only
covered by rendering the real plants and the mubea golden file - the FB has to be created
in the ILSLib to match its assumed interface (or the template adjusted).
---
@@ -410,14 +412,15 @@ as `carousel_run` from connection kinds).
| 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 (e.g. `2Sep1Swi`) | 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:
`Namensregeln` line follows with step 4. Real output for mubea before the `2Sep2Swi`
template (since 2026-10-28 mubea is fully rendered from templates):
```
Templates = 4 von 5 Typen (generisch: FB_ILS_MTRO_2Sep2Swi)
@@ -452,9 +455,9 @@ Each step ends with all tests green and is usable on its own.
| 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 (`1Sep`, `Vario`, `1Sep2Swi`, `1Sep_SSCC`, `Vario_workStation`, `PinStore_Auto`), each with round trip against its reference (`PinStore_Auto`: the parts the reference abbreviates are left out of the comparison); decisions in §6 — **still to be confirmed by a PLC engineer**. Interface check (§8.2) for `Vario_workStation` still open | every round trip passes; HundM05 fully from templates, mubea except `2Sep2Swi` |
| 5 ✅ | Remaining call-site templates (`1Sep`, `Vario`, `1Sep2Swi`, `1Sep_SSCC`, `Vario_workStation`, `PinStore_Auto`), each with round trip against its reference (`PinStore_Auto`: the parts the reference abbreviates are left out of the comparison); decisions in §6 — **still to be confirmed by a PLC engineer**. Interface check (§8.2) for `Vario_workStation` still open | every round trip passes; HundM05 fully from templates, mubea too since the `2Sep2Swi` template (2026-10-28, no reference) |
| 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 |
| 7 | Remove `emit_*` once every type in use has a template (`2Sep2Swi` has one, but without call site - confirm it once the FB exists) | 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.
@@ -511,8 +514,10 @@ jam-area DBs) until an E-Planung export exists, and the `pruefen` timings.
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?
6. `FB_ILS_MTRO_2Sep2Swi` (Mubea): to be created in the ILSLib (decided 2026-10-28,
the two transfer points stay one TRO). Its call site is drafted in
`lib/scl_templates/FB_ILS_MTRO_2Sep2Swi.scl.j2`; open: the assumed interface
(`bSep<n>Type`, `stInOutCognexInterface1/2`, priority manager, `xNewSwitch`).
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.
@@ -0,0 +1,115 @@
{#-
FB_ILS_MTRO_2Sep2Swi - Aufrufstelle in FB_Main
ACHTUNG: KEINE Referenz-Aufrufstelle. Der Baustein existiert noch nicht in der
ILSLib (Anlass: Mubea 500573, Beruehrpunkt Kreisel2/Kreisel1 - zwei
Separatoren laufen auf Ausschleuselement und Kreisel-Weiche zu). Darum gibt es
hier keinen Rundlauf-Test wie bei den anderen Templates, nur das Rendern fuer
die echten Anlagen (tests/test_scl_templates.py) und die Golden-Datei.
Die Schnittstelle ist aus den beiden Nachbarbausteinen ZUSAMMENGESETZT und
muss beim Anlegen des FB so (oder geaendert hier) umgesetzt werden:
zwei Separatoren wie FB_ILS_MTRO_2Sep1Swi (Quelle data/): stInSeparator1/2,
stInSettings.bSep1Type/bSep2Type, arInOutJamEntr1/2,
stInBarcodeReader1/2, stInOutCognexInterface1/2,
xOutStopper1/2
zwei Weichen wie FB_ILS_MTRO_1Sep2Swi (Referenz TRO 267): stInSwitch1/2
mit xNewSwitch, stInSenJam<n> und arInOutJamExit<n> je
Ausgang, xInCarouselRun1/2, xOutSw1ExTo3/xOutSw2ExTo3
Entscheidungen zu den ortsgebundenen Zeilen (doc/SCL_Templates.md §6):
Separatorzeiten 100/50 ms wie die anderen Templates (m.separator), "pruefen"
nSwitchNo fuer BEIDE Weichen (FC_Direction braucht die Nummer;
in TRO 267 fehlt sie bei Weiche 2 - dort offen, Frage 9)
nTo1Destinations Aufteilung der Abgaenge auf die Weichen offen
bSep<n>Type.%X2 TRUE wie bSepType.%X2 in TRO 267, Bedeutung klaeren
xInCarouselRun<n> je Weiche einer - hier sitzen beide an je einem Kreisel
Vorfahrtsregelung nicht verdrahtet: 2Sep1Swi hat stInPriorityManagerDir1..4,
1Sep2Swi ein einzelnes stInPriorityManager - offen
FC_Direction je Weiche einer, Ziel nInDirection1/2
Alle noch mit den SPS-Kollegen zu bestaetigen.
-#}
{% import "_macros.scl.j2" as m %}
REGION {{ t.region_title }}
{{ m.kopf(t) }}
// ACHTUNG: FB_ILS_MTRO_2Sep2Swi existiert noch nicht in der ILSLib - Schnittstelle
// angenommen (2Sep1Swi + 1Sep2Swi), mit den SPS-Kollegen abzustimmen.
{% for s in t.separators %}
{{ m.separator(t, s) }}
{% if not loop.last %}
{% endif %}
{% endfor %}
{{ m.jam_sensors(t) }}
{% for w in t.switches %}
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.nSwitchNo := "{{ w.no.value }}";{{ m.todo(w.no) }}
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.xPluggedExSen3 := FALSE;
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.xPluggedExSen4 := FALSE;
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.xNewSwitch := TRUE;
{% if w.to1_destinations is not none %}
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.nTo1Destinations := {{ w.to1_destinations }}; // Info noetig fuer HMI - {{ TODO }}: pruefen
{% else %}
#{{ t.id }}.stInSwitch{{ w.n }}.Settings.nTo1Destinations := _; // {{ TODO }}: {{ t.successors|length }} Abgaenge auf {{ t.switches|length }} Weichen - Aufteilung festlegen
{% endif %}
{% endfor %}
{{ m.ziele(t) }}
{% for sc in t.scanners %}
#{{ t.id }}.stInBarcodeReader{{ sc.n }}.Settings.xActivateCheckASCI := TRUE;
#{{ t.id }}.stInBarcodeReader{{ sc.n }}.Settings.tTimeout := T#5s;
{{ m.cognex_in(m.cognex(sc), sc) }}
{% endfor %}
// Vorfahrtsregelung: nicht verdrahtet - {{ TODO }}: Schnittstelle des FB klaeren
{% for s in t.separators %}
#{{ t.id }}.stInSettings.bSep{{ s.n }}Type.%X2 := TRUE; // {{ TODO }}: pruefen (Bedeutung)
{% endfor %}
{% set z = [] %}
{% 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(('xInCancel := "cTodoFalse"', "")) %}
{% set _ = z.append(("xInRelease := " ~ t.release, "")) %}
{% for w in t.switches %}
{% set _ = z.append(("xInCarouselRun" ~ w.n ~ " := " ~ t.carousel_run.value, m.note(t.carousel_run, "Kreisel an Weiche " ~ w.n))) %}
{% endfor %}
{% set _ = z.append(("stInOutMachineState := " ~ t.machine_state.value, m.note(t.machine_state, "Schaltschrank"))) %}
{% for s in t.separators %}
{% if t.scanners|length >= s.n %}
{% set sc = t.scanners[s.n - 1] %}
{% set _ = z.append(("stInOutCognexInterface" ~ s.n ~ " := " ~ m.cognex(sc), m.note(sc.interface))) %}
{% else %}
{% set _ = z.append(("stInOutCognexInterface" ~ s.n ~ " := #stCognexInterfaceDummy", "")) %}
{% endif %}
{% endfor %}
{% for j in t.jam_entries %}
{% set _ = z.append(("arInOutJamEntr" ~ j.n ~ " := " ~ j.carriers.value, m.note(j.carriers, j.title ~ " von " ~ j.neighbour))) %}
{% set _ = z.append(("stInOutJamEntr" ~ j.n ~ " := " ~ j.data.value, m.note(j.data))) %}
{% endfor %}
{% for j in t.jam_exits %}
{% set _ = z.append(("arInOutJamExit" ~ j.n ~ " := " ~ j.carriers.value, m.note(j.carriers, j.title ~ " vor " ~ j.neighbour))) %}
{% set _ = z.append(("stInOutJamExit" ~ j.n ~ " := " ~ j.data.value, m.note(j.data))) %}
{% endfor %}
{% 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 %}
{% 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))) %}
{{ m.call(t, z) }}
{% for sc in t.scanners %}
{{ m.cognex_out(m.cognex(sc), sc) }}
{% if not loop.last %}
{% endif %}
{% endfor %}
{{ m.direction(t) }}
END_REGION
+2 -1
View File
@@ -613,7 +613,8 @@ TRO_CATALOG: tuple[TroDefinition, ...] = (
# Der Baustein FB_ILS_MTRO_2Sep2Swi existiert in diesem Repository nicht
# und ist auch in doc/TRO_Katalog/scl_templates/ nicht hinterlegt - er muss
# in der ILSLib angelegt werden, sonst erzeugt ein spaeterer
# SCL-Generator einen Aufruf auf einen fehlenden Baustein.
# SCL-Generator einen Aufruf auf einen fehlenden Baustein. Die angenommene
# Schnittstelle steht im Kopf von lib/scl_templates/FB_ILS_MTRO_2Sep2Swi.scl.j2.
TroDefinition("2Sep2Swi", "FB_ILS_MTRO_2Sep2Swi", {
TroItem.SEPARATOR: 2,
TroItem.SWITCH: 2,
+55 -26
View File
@@ -16,8 +16,8 @@
// Reihenfolge der REGIONs = Materialfluss.
// Anfang bei TRO03: Materialeingang ueber SYS1.
//
// Aus Template : FB_ILS_MTRO_1Sep, FB_ILS_MTRO_1Sep1Swi, FB_ILS_MTRO_PinStore_Auto, FB_ILS_MTRO_Vario
// Generisch : FB_ILS_MTRO_2Sep2Swi (kein Template - von Hand pruefen)
// Aus Template : FB_ILS_MTRO_1Sep, FB_ILS_MTRO_1Sep1Swi, FB_ILS_MTRO_2Sep2Swi, FB_ILS_MTRO_PinStore_Auto, FB_ILS_MTRO_Vario
// Generisch : - (kein Template - von Hand pruefen)
// ============================================================
FUNCTION_BLOCK "FB_Main"
@@ -514,42 +514,46 @@ REGION TRO10 (2Sep2Swi) Sep 0005, 0036
// Vorgaenger: TRO01, TRO06, TRO18
// Nachfolger: TRO01, TRO02, TRO11
// Einstufung: hoch
// Aufbau nach Template FB_ILS_MTRO_2Sep2Swi.scl.j2 (Referenz: doc/TRO_Katalog/scl_templates)
// ACHTUNG: FB_ILS_MTRO_2Sep2Swi existiert noch nicht in der ILSLib - Schnittstelle
// angenommen (2Sep1Swi + 1Sep2Swi), mit den SPS-Kollegen abzustimmen.
// 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.tTrailingTime := t#100ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator1.Settings.tHandlingTime := t#50ms; // 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.tTrailingTime := t#100ms; // TODO(E-Planung): pruefen
#TRO10.stInSeparator2.Settings.tHandlingTime := t#50ms; // 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.stInSenJam2 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInSenJam3 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#TRO10.stInSenJam4 := "DB_Inputs".Sensors["cInBG____"]; // TODO(E-Planung)
#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.stInSwitch1.Settings.xNewSwitch := TRUE;
#TRO10.stInSwitch1.Settings.nTo1Destinations := _; // TODO(E-Planung): 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
#TRO10.stInSwitch2.Settings.xNewSwitch := TRUE;
#TRO10.stInSwitch2.Settings.nTo1Destinations := _; // TODO(E-Planung): 3 Abgaenge auf 2 Weichen - Aufteilung festlegen
// Zielliste je Abgang (aus dem TRO-Graphen berechnet) -
// Grundlage fuer die Zuordnung Ziel -> Richtung in FC_Direction:
@@ -558,31 +562,47 @@ REGION TRO10 (2Sep2Swi) Sep 0005, 0036
// 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.stInBarcodeReader1.Settings.tTimeout := T#5s;
#arCognexInterface["cScanner____"].xInCamTriggerReady := "bx____-TriggerReady"; // TODO(E-Planung)
#arCognexInterface["cScanner____"].xInCamTriggerAck := "bx____-TriggerAck"; // TODO(E-Planung)
#arCognexInterface["cScanner____"].xInCamResultsAvailable := "bx____-Results Available"; // TODO(E-Planung)
#arCognexInterface["cScanner____"].xInCamGeneralFault := "bx____-General Fault"; // TODO(E-Planung)
#arCognexInterface["cScanner____"].hwInCamInspectionResults := "BX____~Ergebnisse_–_64_Bytes_1"; // TODO(E-Planung)
#TRO10.stInBarcodeReader2.Settings.xActivateCheckASCI := TRUE;
#TRO10.stInBarcodeReader2.Settings.tTimeout := T#3000ms;
// TODO(E-Planung): Cognex-Interface verdrahten (#arCognexInterface["cScanner____"])
#TRO10.stInBarcodeReader2.Settings.tTimeout := T#5s;
#TRO10.stInPriorityManager.xReleaseOk := TRUE;
#arCognexInterface["cScanner____"].xInCamTriggerReady := "bx____-TriggerReady"; // TODO(E-Planung)
#arCognexInterface["cScanner____"].xInCamTriggerAck := "bx____-TriggerAck"; // TODO(E-Planung)
#arCognexInterface["cScanner____"].xInCamResultsAvailable := "bx____-Results Available"; // TODO(E-Planung)
#arCognexInterface["cScanner____"].xInCamGeneralFault := "bx____-General Fault"; // TODO(E-Planung)
#arCognexInterface["cScanner____"].hwInCamInspectionResults := "BX____~Ergebnisse_–_64_Bytes_1"; // TODO(E-Planung)
// Vorfahrtsregelung: nicht verdrahtet - TODO(E-Planung): Schnittstelle des FB klaeren
#TRO10.stInSettings.bSep1Type.%X2 := TRUE; // TODO(E-Planung): pruefen (Bedeutung)
#TRO10.stInSettings.bSep2Type.%X2 := TRUE; // TODO(E-Planung): pruefen (Bedeutung)
#TRO10(nInMainTroNo := "cMainTro____", // TODO(E-Planung)
xInSftyOk := "DB_InterfaceSafety".stFromSafety.EStopMain.Q, // TODO(E-Planung)
xInAllRdyToStart := TRUE,
xInCancel := "cTodoFalse",
xInRelease := "DB_TRO_TEST".TRO10,
stInOutMachineState := #stInOutControlUnitCabinet,
stInOutCognexInterface := #stCognexInterfaceDummy,
xInCarouselRun1 := #fbCarousel____.xOutConveyorFullSpeed, // TODO(E-Planung) - Kreisel an Weiche 1
xInCarouselRun2 := #fbCarousel____.xOutConveyorFullSpeed, // TODO(E-Planung) - Kreisel an Weiche 2
stInOutMachineState := #stInOutControlUnitCabinet, // TODO(E-Planung) - Schaltschrank
stInOutCognexInterface1 := #arCognexInterface["cScanner____"], // TODO(E-Planung)
stInOutCognexInterface2 := #arCognexInterface["cScanner____"], // TODO(E-Planung)
arInOutJamEntr1 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich J0005 von TRO01, TRO06, TRO18 (Aufteilung der Vorgaenger auf die Eingaenge offen)
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData,
stInOutJamEntr1 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
arInOutJamEntr2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich J0036 von - (Aufteilung der Vorgaenger auf die Eingaenge offen)
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData,
stInOutJamEntr2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
arInOutJamExit2 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich J0040 vor TRO01
stInOutJamExit2 := "DB_JamArea____".stJam____.stData,
stInOutJamExit2 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
arInOutJamExit3 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich J0012 vor TRO02
stInOutJamExit3 := "DB_JamArea____".stJam____.stData,
stInOutJamExit3 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
arInOutJamExit4 := "DB_JamArea____".stJam____.arCarrier, // TODO(E-Planung) - Staubereich J0058 vor TRO11
stInOutJamExit4 := "DB_JamArea____".stJam____.stData,
stInOutJamExit4 := "DB_JamArea____".stJam____.stData, // TODO(E-Planung)
xOutStopper1 => "MB____", // TODO(E-Planung)
xOutStopper2 => "MB____", // TODO(E-Planung)
xOutSw1ExTo3 => "MB____", // TODO(E-Planung)
@@ -590,14 +610,23 @@ REGION TRO10 (2Sep2Swi) Sep 0005, 0036
stInOutHMI := "DB_Interface_HMI".stTRO.TRO10,
nOutStateLast => "DB_GLOB_TroState".arTroState["cMainTro____"]); // TODO(E-Planung)
"bx____-TriggerEnable" := #arCognexInterface["cScanner____"].xOutCamTriggerEnable; // TODO(E-Planung)
"bx____-Trigger" := #arCognexInterface["cScanner____"].xOutCamTrigger; // TODO(E-Planung)
"bx____-ResultsAck" := #arCognexInterface["cScanner____"].xOutCamResultsAck; // TODO(E-Planung)
"bx____-TriggerEnable" := #arCognexInterface["cScanner____"].xOutCamTriggerEnable; // TODO(E-Planung)
"bx____-Trigger" := #arCognexInterface["cScanner____"].xOutCamTrigger; // TODO(E-Planung)
"bx____-ResultsAck" := #arCognexInterface["cScanner____"].xOutCamResultsAck; // TODO(E-Planung)
REGION Direction
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO10.nInDirection1,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]); // TODO(E-Planung)
"FC_Direction"(nInSwitchNo := "cSwi_____", // TODO(E-Planung)
nOutDirection => #TRO10.nInDirection2,
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]);
InOutCarrier := "DB_JamArea____".stJam____.arCarrier[1]); // TODO(E-Planung)
END_REGION
END_REGION
+7 -2
View File
@@ -17,6 +17,7 @@ Diff pruefen, dann die Referenzen neu schreiben mit
import os
import re
import shutil
from pathlib import Path
import pytest
@@ -101,7 +102,7 @@ def test_cli_schreibt_referenz(name: str, tmp_path: Path, monkeypatch) -> None:
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."""
ein FB-Typ der Anlage kein Template hat (hier: Template-Ordner ohne 2Sep2Swi)."""
if _aktualisieren():
pytest.skip("Referenzen werden nur ueber die render-Tests geschrieben")
monkeypatch.setenv("SKEL_RESULTS", str(tmp_path))
@@ -113,7 +114,11 @@ def test_cli_templates_und_strict(tmp_path: Path, monkeypatch) -> None:
assert _maskiert(ist) == soll
(tmp_path / "mubea_FB_Main.scl").unlink()
assert scl_skeleton.main(["--json", json_file, "--templates", "--strict"]) == 1
ohne_2sep2swi = tmp_path / "templates"
shutil.copytree(scl_skeleton.TEMPLATE_DIR, ohne_2sep2swi)
(ohne_2sep2swi / "FB_ILS_MTRO_2Sep2Swi.scl.j2").unlink()
assert scl_skeleton.main(["--json", json_file, "--templates", str(ohne_2sep2swi),
"--strict"]) == 1
assert not (tmp_path / "mubea_FB_Main.scl").exists()
assert scl_skeleton.main(["--json", json_file, "--templates",