FUNCTION "HWtoVP_Ziel_FC" : Void
TITLE = Ziel-FC: HW>VP_OmniFahren
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : AE
FAMILY : Module
NAME : Ziel
//SCL-Portierung des AWL-Bausteins FC181 "HWtoVP_Ziel_FC" (verhaltensgleich).
//
//Der Baustein hatte im AWL-Original die Bausteineigenschaft "Parameterversorgung
//ueber Register" (ParameterPassing) aktiv und wurde per "UC FC[..]" indirekt aus
//AWL aufgerufen -> aus SCL nicht compilierbar. Er liest ausschliesslich globale
//Merker (MW190 = Schleusen-Nr, MW194 = angefordertes Weichen-Ziel, MD182 = ShopGroup,
//MB-/BG-Merker) und ruft die Zielbausteine voll qualifiziert auf -> keine echte
//Registerabhaengigkeit. Als SCL-Baustein entfaellt die Register-Option und er ist
//direkt aus SCL aufrufbar (CASE 181 in MHMOmniSchleuse).
//
//Der indirekte Dispatch (AWL: je Netzwerk "L MW190 / L <Schleuse> / NE_I / JC <Ende>")
//ist als CASE ueber die Schleusen-Nr (MW190) ausgefuehrt. Da die Schleusen-Nrn
//paarweise verschieden sind, kann pro Aufruf hoechstens ein Zweig zutreffen; ein
//AWL-BEU/BEC im getroffenen Zweig ist daher als RETURN bzw. "IF <RLO> THEN RETURN;"
//umgesetzt (verhaltensgleich, da nach dem Dispatch nur noch das Bausteinende folgt).
//Die Merker-Schnittstelle (MW190/MW194 vom Aufrufer gelesen, MW198 = Weichenziel
//ausgegeben, M180.6 = Weiterfahrt-Freigabe) bleibt erhalten.
//
//ABWEICHUNGEN ZUM AWL-ORIGINAL (bei Inbetriebnahme pruefen!):
//  - NW7 (Schleuse 3141): Der STL-Export enthaelt im Ziel-/Telegramm-Check das
//    nicht-standardisierte Token "CAC" (Akku-Restore, bringt den Endziel-Wert MW194
//    fuer den zweiten Vergleich zurueck in den Akku). Semantisch werden BEIDE
//    Vergleiche gegen MW194 gefuehrt (MW194 = 16#3130 bzw. 16#3127); genau so
//    umgesetzt. UNBEDINGT PRUEFEN!
//  - NW7 (Schleuse 3141): Im CALL "Daten_in_SendFIFO_speichern" steht als StationsNr
//    die Konstante 3143 (LineComment "3141") -> vermutlich Copy-Paste-Fehler im
//    Original; Wert 3143 1:1 uebernommen. PRUEFEN!
//  - NW9 (Schleuse 3136): Der Ziel-Check liest die Temp-Variable "EndZiel", die im
//    gesamten Baustein NIE beschrieben wird (im AWL undefinierter Akku-/L-Stack-Wert).
//    Verhalten 1:1 uebernommen -> Wert ist undefiniert. UNBEDINGT PRUEFEN!
//  - Der Temp-Member "Error.Bit" traegt im Interface einen Punkt im Namen; er ist als
//    gequoteter Bezeichner "Error.Bit" uebernommen (separater Member neben "Error").
//  - Wort-Merker (MW194/MW198) und die Word-Temp "EndZiel" werden gegen Word-Konstanten
//    (W#16#..) direkt verglichen; MW190 wird fuer den CASE ueber WORD_TO_INT in Int
//    gewandelt (AWL: NE_I gegen dezimale Konstante). TypedConstant DINT#-1/DINT#0 1:1.
//  - CALL "Daten_in_SendFIFO_speichern": Ausgangsparameter (Ret_Val_FIFO_IN, Error) mit
//    "=>" versorgt; nicht versorgte Parameter (ohne Zugriff im XML) weggelassen.
//  - DB-Zugriffe: DB-Name gequotet, Member-Pfad wie im Original.
   VAR_TEMP
      Ziel_hex : Word;
      Ziel_int : Int;
      Zielebene : Word;
      Error : Byte;
      Position : Int;
      Lager_DB : Int;
      Lager_DW : Int;
      AR1Zeiger : DWord;   // Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes)
      AR1Start : DInt;   // Startwert mit Offset 0
      SSDW : Int;
      EndZiel : Word;
      Variante : Int;
      AbrufID : DInt;
      Fahrlisten_TrolleyID : DInt;
      Fahrlisten_AbrufID : DInt;
      Fahrlisten_Lager : Int;
      Trolley_unbekannt : Bool;   // Trolley ist nicht in DL
      Express_Abruf : Bool;
      "Error.Bit" : Bool;
   END_VAR

BEGIN
   // NW1: Rueckmeldung - Rueckmeldungen erst mal resetten (Weiterfahrt von Ziel-FC erlaubt)
   "M180.6" := FALSE;

   // AWL: UC FC181 dispatcht ueber MW190 (Schleusen-Nr, vom Aufrufer gesetzt)
   CASE WORD_TO_INT("MW190") OF

      3731:   // Schleuse 3731: (BST 2)
         // AWL: SET / S M180.6 -> Weiterfahrt bedingungslos erlaubt
         "M180.6" := TRUE;

      4203:   // Bereich 4203: Weiterfahren erlaubt ? (AFS von BST)
         // AWL: SET / S M180.6 -> Weiterfahrt bedingungslos erlaubt
         "M180.6" := TRUE;

      4207:   // Schleuse 4207: (Vor BypPass von LP)
         // Quell-Steuerung:
         IF ("DLPtoHW_OmniFahren".Weiche_4223.Dyn.Weichen_Ziel = W#16#4211)   // Fahren Trolleys zu BG4211?
            OR "MB4223"                                                        // Weiche ist auf Abzweig
            OR "DLPtoHW_OmniFahren".Weiche_4223.Dyn.Status.Reset_aktiv THEN
            RETURN;   // Warten!
         END_IF;
         // Ziel-Check:
         IF     NOT "MB4223"                                                   // Weiche Einfahrt ByPass
            AND NOT "MB4210"
            AND NOT "DHWtoVP_Sensoren".Stau_BG4210.Stat.B_Akt
            AND NOT "DHWtoVP_Sensoren".Stau_BG4211.Stat.B_Akt THEN
            "M180.6" := TRUE;   // Weiterfahrt ist erlaubt
         END_IF;

      3145:   // Bereich 3145: Weiterfahren erlaubt ? (AFS von 1.Ebene)
         // AWL: SET / S M180.6 -> Weiterfahrt bedingungslos erlaubt
         "M180.6" := TRUE;

      3143:   // Schleuse 3143: (Anfrage KontrollPlatz)
         IF "MD182" = DINT#-1 THEN   // ShopGroup = Leer-Trolley?
            "M180.6" := TRUE;   // Weiterfahrt ist erlaubt
            RETURN;   // Kein Telegramm!
         END_IF;
         IF "SGes".Ohne_PC_Fahren THEN   // Also ohne Anfrage
            "M180.6" := TRUE;
            // -> N3143 (Trolleydaten neu anlegen, Telegramm-Block ueberspringen)
         ELSE
            // GOHDReqM an Host senden:
            IF "DHWtoVP_OmniFahren".Schleuse_3143.Status2.Telegramm_gesendet THEN
               "M180.6" := TRUE;
               RETURN;
            END_IF;
            IF "DHWtoVP_OmniFahren".Schleuse_3143.Dyn.TrolleyID_Schleuse = 0 THEN   // Barcode bekannt?
               RETURN;   // Warten!
            END_IF;
            "Daten_für_SendFIFO"(TelegrammKennung[1] := 'G',
                                 TelegrammKennung[2] := 'O',
                                 TelegrammKennung[3] := 'H',
                                 TelegrammKennung[4] := 'D',
                                 TelegrammKennung[5] := 'R',
                                 TelegrammKennung[6] := 'e',
                                 TelegrammKennung[7] := 'q',
                                 TelegrammKennung[8] := 'M',
                                 TrolleyID           := "DHWtoVP_OmniFahren".Schleuse_3143.Dyn.TrolleyID_Schleuse,
                                 StationsNr          := 3143,
                                 Port                := 2,
                                 Ret_Val_FIFO_IN     => "MB199",
                                 Error               => "Error.Bit");
            IF NOT "Error.Bit" THEN
               "DHWtoVP_OmniFahren".Schleuse_3143.Status2.Telegramm_gesendet := TRUE;
            END_IF;
         END_IF;
         // N3143: Trolleydaten neu anlegen (Falls noch als Daten-Leiche vorhanden war):
         "Trolleydaten_neu_anlegen"(Gesamt_Trolley_DL := "DHWtoVP_OmniFahren".Schleuse_3143.Schleuse.Gesamt_Trolley_DL,
                                    TrolleyID         := "DHWtoVP_OmniFahren".Schleuse_3143.Dyn.TrolleyID_Schleuse,
                                    Endziel           := W#16#0000,   // Kein Ziel
                                    ShopGroup         := DINT#0);

      3141:   // Schleuse 3141: (Vor Einfahrt Kontrollplatz)
         // Quell-Steuerung:
         IF ("DHWtoVP_OmniFahren".Schleuse_3136.Dyn.Raus_Trolleys > 0)   // Weiche von 2.Quelle schon belegt
            OR "MB3136" THEN                                             // Andere Quelle aktiv
            RETURN;
         END_IF;
         // Leerer Trolley vom Leerpuffer? / Telegramm schon gesendet? / Ziel-Check:
         IF ("MD182" = DINT#-1)               // Leer-Trolley?
            OR "SGes".Ohne_PC_Fahren THEN      // Also Ziel simulieren -> Kein Telegramm!
            // G3141: gerade fahren (zum VP)
            "MW198" := W#16#3127;   // Weichenziel
            IF NOT "DHWtoVP_Sensoren".Stau_BG3127.Stat.B_Akt THEN
               "M180.6" := TRUE;   // Weiterfahrt ist erlaubt
            END_IF;
         ELSIF ("MW194" <> W#16#3130)          // Endziel sinnvoll? (nochmalige Anfrage)
            AND ("MW194" <> W#16#3127)
            AND NOT "DHWtoVP_OmniFahren".Schleuse_3141.Status2.Telegramm_gesendet THEN
            // T3141: GOHDReqM an Host senden
            IF "DHWtoVP_OmniFahren".Schleuse_3141.Dyn.TrolleyID_Schleuse = 0 THEN   // Barcode bekannt?
               RETURN;   // Warten!
            END_IF;
            "Daten_für_SendFIFO"(TelegrammKennung[1] := 'G',
                                 TelegrammKennung[2] := 'O',
                                 TelegrammKennung[3] := 'H',
                                 TelegrammKennung[4] := 'D',
                                 TelegrammKennung[5] := 'R',
                                 TelegrammKennung[6] := 'e',
                                 TelegrammKennung[7] := 'q',
                                 TelegrammKennung[8] := 'M',
                                 TrolleyID           := "DHWtoVP_OmniFahren".Schleuse_3141.Dyn.TrolleyID_Schleuse,
                                 StationsNr          := 3143,   // LineComment im Original: 3141
                                 Port                := 2,
                                 Ret_Val_FIFO_IN     => "MB199",
                                 Error               => "Error.Bit");
            IF NOT "Error.Bit" THEN
               "DHWtoVP_OmniFahren".Schleuse_3141.Status2.Telegramm_gesendet := TRUE;
            END_IF;
         ELSIF "MW194" = W#16#3130 THEN   // Kontroll-Platz? -> Abzweig fahren
            // A3141:
            "MW198" := W#16#3130;   // Weichenziel
            IF NOT "DHWtoVP_Sensoren".Stau_BG3130.Stat.B_Akt THEN
               "M180.6" := TRUE;   // Weiterfahrt ist erlaubt
            END_IF;
         ELSIF "MW194" = W#16#3127 THEN   // Zum VP?
            // G3141: gerade fahren (zum VP)
            "MW198" := W#16#3127;   // Weichenziel
            IF NOT "DHWtoVP_Sensoren".Stau_BG3127.Stat.B_Akt THEN
               "M180.6" := TRUE;   // Weiterfahrt ist erlaubt
            END_IF;
         ELSE
            IF "10s-Impuls" THEN   // Nach 10s: erneute Anfrage
               "DHWtoVP_OmniFahren".Schleuse_3141.Status2.Telegramm_gesendet := FALSE;
            END_IF;
         END_IF;

      3134:   // Schleuse 3134: (Kontrollplatz)
         // Trolley kann gestartet werden: (Vorerst immer)
         "PF0136" := "BG3134" AND "Clock_2Hz";   // Trolley ist in Schleuse
         // Ausfahren mit Taste:
         IF "SF0136" THEN
            "M180.6" := TRUE;   // Weiterfahrt ist erlaubt
         END_IF;

      3136:   // Schleuse 3136: (Vor Ausfahrt Kontrollplatz)
         // Quell-Steuerung:
         IF ("DHWtoVP_OmniFahren".Schleuse_3141.Dyn.Raus_Trolleys > 0)   // Weiche von 2.Quelle schon belegt
            OR "MB3141" THEN                                             // Andere Quelle aktiv
            RETURN;
         END_IF;
         // Ziel-Check:
         // Hinweis: Temp "EndZiel" wird hier gelesen, aber im Baustein nie gesetzt -> Wert undefiniert (wie AWL)!
         IF "EndZiel" = W#16#BAAA THEN   // Kontroll-Platz? -> Abzweig fahren
            // A3136:
            "MW198" := W#16#3130;   // Weichenziel
            IF NOT "DHWtoVP_Sensoren".Stau_BG3130.Stat.B_Akt THEN
               "M180.6" := TRUE;   // Weiterfahrt ist erlaubt
            END_IF;
         ELSE
            // G3136:
            "MW198" := W#16#3127;   // Weichenziel
            IF NOT "DHWtoVP_Sensoren".Stau_BG3127.Stat.B_Akt THEN
               "M180.6" := TRUE;   // Weiterfahrt ist erlaubt
            END_IF;
         END_IF;

      ELSE
         ;   // unbekannte Schleusen-Nr -> nichts tun
   END_CASE;
END_FUNCTION
