# SCL-Export — AWL→SCL-Pilotkonvertierung

Pilotbausteine der AWL→SCL-Konvertierung, bereit zum Test in TIA Portal V20.
Je Station ein Ordner; die Dateien sind **externe Quellen** (Import über
*Externe Quellen → Quelle hinzufügen → Bausteine aus Quelle generieren*).

## Inhalt

| Baustein | Original | Kategorie | Datei |
|---|---|---|---|
| MZylinder | FB 92, AWL, 11 Netzwerke | A — Verknüpfungslogik | `MZylinder.scl` |
| FifoIn | FC 80, AWL, Pointer/BLKMOV | C — Pointerzugriffe | `FifoIn.scl` |
| DatenOut | FC 86, AWL, Pointer/indirekte Aufrufe | C — Pointerzugriffe | `DatenOut.scl` |
| MHMOmniSchleuse | FB 1274, AWL, Schrittkette 52 NW | B — Ablaufsteuerung | `MHMOmniSchleuse.scl` |

Die Bausteine sind zwischen UH06 und UH07 identisch (FifoIn: nur Kommentare
verschieden) — **Ausnahme `MHMOmniSchleuse`**: die CASE-Verteiler für die
indirekten FC-Aufrufe (Leser-/Ziel-/Draussen-FC) enthalten die
stationsspezifischen FC-Nummern:
- UH06: 181/1181/2181 (Ziel), 1180 (Leser), 1182 (Draussen)
- UH07: 181..6181 (Ziel), 180..6180 (Leser), 182..6182 (Draussen)

## WICHTIG: Nicht direkt ins Produktivprojekt!

`DatenOut` und `FifoIn` haben geänderte Schnittstellen
(`POINTER`/`ANY` → `VARIANT`, S7-1500-konform). Die **bestehenden
AWL-Aufrufer** übergeben `P#M...`-Pointer und kompilieren nach dem Ersetzen
u.U. nicht mehr, bis sie angepasst sind. Daher:

1. **Projektkopie** anlegen (oder eigenes Test-Projekt mit PLCSIM).
2. Quellen importieren und **einzeln generieren** — Reihenfolge:
   `DatenOut` → `MHMOmniSchleuse` (Aufrufer von DatenOut); `MZylinder` und
   `FifoIn` sind unabhängig.
3. Kompilieren; Fehlerliste prüfen (erwartbar: Aufrufer von DatenOut/FifoIn,
   die noch AWL-Pointer übergeben).

`MZylinder` ist schnittstellengleich und kann den AWL-Baustein direkt
ersetzen (Aufrufer und Instanz-DBs bleiben gültig, neu übersetzen genügt).

## Voraussetzungen (im Projekt bereits vorhanden)

- UDTs: `UZylinder`, `UDLHMOmniSchleuse`, `USk_ILS`, `UErrHMOmniSchleuse`, `UTrolley`
- Bausteine: `TEST_DB_TO_ATTR_DB` (SCL), `BCD (4stellig)_to_INT`,
  `Wandel_FC_für_DB1000`, `Trolley_DL_Neue_Pos`, die Leser-/Ziel-/Draussen-FCs,
  DB `TrolleyDL_OutDaten` (DB1011)
- PLC-Variablen: `MW2`, `MW4`, `100ms-Impuls`, `1s-Impuls`, `MW200`,
  `M200.0..M201.7`, `MW190..MW198`, `MD182`, `MD192`, `M180.x`, `M199.0`,
  `MW248..MW254`
- Nicht-optimierte DBs (Standard-Zugriff) — die Bausteine arbeiten mit
  PEEK/POKE auf absolute Byte-Offsets, Layouts unverändert.

## Umsetzungs-Konventionen (gelten auch für die Massenkonvertierung)

- AWL-Netzwerke → `REGION NW<x>: <Titel>`; Sprünge → `IF`/`CASE`/`GOTO`
  (GOTO nur für die gemeinsamen Fehler-/Verwaltungs-Enden, wie im AWL).
- `OPN DB[n]` + `DBW[AR1,..]` → `PEEK/POKE (area:=16#84, dbNumber:=…, byteOffset:=…)`.
- `BLKMOV` über ANY-Pointer → `Serialize`/`Deserialize` mit `VARIANT`-Parametern.
- BR-Bit (`SAVE`/`JBI`/`BEC`) → `ENO := …;` bzw. Auswertung von RE_VAL-Bit 7.
- Indirekte Aufrufe `UC FC[n]` → `CASE n OF` mit den projektierten FC-Nummern.
- 16-Bit-Semantik (`+I`, `*I`) bleibt `Int`; keine stille Aufweitung auf DInt.

## Bekannte, dokumentierte Abweichungen (Kopf der jeweiligen Datei!)

- **FifoIn**: `INDATEN` jetzt `Variant` (statt `POINTER`); Kopier-Fehler des
  alten SFC20 werden über eigene Bereichsprüfungen nachgebildet.
- **DatenOut**: `SEARCHDATEN`/`OUTDATEN` jetzt `Variant`; die DB-Prüfungen des
  Such-/Out-DB (AWL NW5/NW8) entfallen (Fehlerbit 5 wird nicht mehr erzeugt);
  `OUTDATEN`-Ziel sollte exakt Datensatzlänge×2 Bytes groß sein;
  `Position` wird mit 0 initialisiert (AWL: undefiniert).
- **MHMOmniSchleuse**: Merker-Scratch (MW200-Suchdaten, M220-OutDaten, MB199)
  durch lokale Puffer ersetzt; Merker-Schnittstellen zu Fremd-FCs
  (MW190–MW198, MD182/192, M180.x, Fehlerwort MW200/M200.x/M201.x) bleiben.
  NW21 war im Original tot (CLR+JU) und entfällt. In Schritt 10 („NoLesung")
  verglich das AWL gegen einen **undefinierten Akku-Altwert** — umgesetzt ist
  die beabsichtigte Prüfung `TrolleyID_Input <> 0`. **Bei IBN prüfen!**

## Empfohlener Vergleichstest (PLCSIM)

1. AWL-Original umbenennen (z.B. `DatenOut` → `DatenOut_AWL`), SCL-Baustein
   generieren.
2. Test-FC schreiben, der beide mit identischen Eingangsdaten aufruft
   (getrennte Kopien des Ziel-DB!) und RE_VAL/ENO/DB-Inhalte vergleicht.
3. Für `MHMOmniSchleuse`: Instanz-DBs beider Varianten nach jedem Zyklus
   vergleichen (Watch-Tabelle bzw. Vergleichs-FC über die Static-Bereiche).

## Werkzeug

`lib/stlxml2awl.py` (Projektwurzel) wandelt die SimaticML-XML-Exporte
(`StatementList`) in lesbaren AWL-Text um, inkl. Interface, Netzwerktitel,
Sprungmarken und Kommentaren — Grundlage für die Massenkonvertierung der
restlichen ~230 Bausteine. Aufruf über `bin/xmls2awl.bat`:

```
bin\xmls2awl.bat <baustein.xml> [<baustein2.xml> ...]   REM einzelne Dateien
bin\xmls2awl.bat --dir <verzeichnis>                     REM rekursiv alle .xml -> .awl
```

Je `.xml` wird die `.awl` daneben abgelegt. Nicht-Baustein-Exporte (UDTs,
Tag-Tabellen) werden übersprungen. Zusätzlich schätzt das Skript pro Baustein
anhand von Sprung-/Label-Anzahl, registerindirekten Zugriffen und bekannten
Namensmustern eine der drei Aufwandskategorien (A/B/C, siehe oben) und
schreibt ein Log (`log/stlxml2awl_<Zeitstempel>.log`, mit `--log <pfad>`
überschreibbar) mit allen Bausteinen der Kategorien B/C sowie Fehlern — das
ist die Priorisierungsliste für die manuelle Nacharbeit.
