FUNCTION_BLOCK "FB_AMR_Management_V2"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      udtIn_DataMES : "UDT_Telegram_GOHDRespM";
      str_InCapacityTrigger : Struct
         str_4002 : Struct
            n_4002_1 : USInt;
            n_4022_2 : USInt;
         END_STRUCT;
         str_4003 : Struct
            n_4003_1 : USInt;
            n_4003_2 : USInt;
            n_4003_3 : USInt;
            n_4003_4 : USInt;
            n_4003_5 : USInt;
            n_4003_6 : USInt;
            n_4003_7 : USInt;
         END_STRUCT;
         str_4004 : Struct
            n_4004_1 : USInt;
         END_STRUCT;
         str_4005 : Struct
            n_4005_1 : USInt;
         END_STRUCT;
         str_4006 : Struct
            n_4006_1 : USInt;
         END_STRUCT;
         str_4007 : Struct
            n_4007_1 : USInt;
         END_STRUCT;
         str_4008 : Struct
            n_4008_1 : USInt;
         END_STRUCT;
         str_4009 : Struct
            n_4009_1 : USInt;
         END_STRUCT;
         str_4010 : Struct
            n_4010_1 : USInt;
            n_4010_2 : USInt;
         END_STRUCT;
      END_STRUCT;
      udt_InTro406Scan : "UDT_MFRScanResult";
      udt_InTro407Scan : "UDT_MFRScanResult";
      udt_InTro410Scan : "UDT_MFRScanResult";
      udt_InTro413Scan : "UDT_MFRScanResult";
      udt_InTro417Scan : "UDT_MFRScanResult";
      t_InTRO407Watchdog : Time;
      t_InTRO410Watchdog : Time;
      t_InTRO413Watchdog : Time;
      tInMaxWaitTimeRequeue : Time;
   END_VAR

   VAR_OUTPUT 
      xOutStopFeed : Bool;
   END_VAR

   VAR_IN_OUT 
      stInOutJam4002_1 : Struct
         arCarrier : Array[1.."cJam4002_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4002_2 : Struct
         arCarrier : Array[1.."cJam4002_2"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4003_1 : Struct
         arCarrier : Array[1.."cJam4003_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4003_2 : Struct
         arCarrier : Array[1.."cJam4003_2"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4003_3 : Struct
         arCarrier : Array[1.."cJam4003_3"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4003_4 : Struct
         arCarrier : Array[1.."cJam4003_4"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4003_5 : Struct
         arCarrier : Array[1.."cJam4003_5"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4003_6 : Struct
         arCarrier : Array[1.."cJam4003_6"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4003_7 : Struct
         arCarrier : Array[1.."cJam4003_7"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4004_1 : Struct
         arCarrier : Array[1.."cJam4004_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4005_1 : Struct
         arCarrier : Array[1.."cJam4005_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4006_1 : Struct
         arCarrier : Array[1.."cJam4006_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4007_1 : Struct
         arCarrier : Array[1.."cJam4007_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4008_1 : Struct
         arCarrier : Array[1.."cJam4008_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4009_1 : Struct
         arCarrier : Array[1.."cJam4009_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4010_1 : Struct
         arCarrier : Array[1.."cJam4010_1"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      stInOutJam4010_2 : Struct
         arCarrier : Array[1.."cJam4010_2"] of "stCarrier";
         stData : "stJamData";
      END_STRUCT;
      udt_InOut_MultiPurposeStation1 : "UDT_Workstation";
      udt_InOut_MultiPurposeStation2 : "UDT_Workstation";
      udt_InOut_MultiPurposeStation3 : "UDT_Workstation";
      udt_TRO406 : "udt_MFR_TRO";
      udt_TRO407 : "udt_MFR_TRO";
      udt_TRO410 : "udt_MFR_TRO";
      udt_TRO413 : "udt_MFR_TRO";
      udt_InOut_HandshakeDataMES : "udt_HandshakeMessageFromMES";
      arrudt_InOutCarrierBuffer : Array[*] of "UDT_Telegram_GOHDRespM";
      arrudt_InOutJam : Array[*] of "stCarrier";
   END_VAR

   VAR 
      udt_DeleteBuffer : "UDT_Telegram_GOHDRespM";
      udt_DataMESSave { S7_SetPoint := 'False'} : "UDT_Payload_GOHDRespM";
      xWaitingForRelease : Bool;
      x_Release : Bool;
      xCarrierFound : Bool;
      n_IDXSearchData { S7_SetPoint := 'True'} : USInt;
      n_UpperBound : USInt;
      n_LowerBound : USInt;
      n_UpperBoundBuffer : USInt;
      n_LowerBoundBuffer : USInt;
      n_DatenBufferIDX : USInt;
      nSearchCarrierIDX : Int;
      nSearchCarrierIDestination : Int;
      n_DatenJamArea : USInt;
      nIDWithoutDest : DInt;
      n_ScanBarcode : DInt;
      st_JamAreaCarrier : Struct
         st_Data { S7_SetPoint := 'False'} : "stCarrier";
         str_Type { S7_SetPoint := 'True'} : String;
      END_STRUCT;
      lfb_TRO407Scan { S7_SetPoint := 'False'} : "FB_ScanMonitor";
      lfb_TRO410Scan : "FB_ScanMonitor";
      lfb_TRO413Scan : "FB_ScanMonitor";
      lfb_TRO407Handshake : "FB_TROHandshakeAMR";
      lfb_TRO410Handshake : "FB_TROHandshakeAMR";
      lfb_TRO413Handshake : "FB_TROHandshakeAMR";
      x_TRO407NewDestination { S7_SetPoint := 'True'} : Bool;
      x_TRO410NewDestination : Bool;
      x_TRO413NewDestination : Bool;
      n_StepBufferMES : Int;
      n_EmptyElementIDX : USInt;
      n_EmptyElementIDXSave : Int;
      LtonMaxWait {InstructionName := 'TON_TIME'; LibVersion := '1.0'; S7_SetPoint := 'False'} : TON_TIME;
      xRequeueDone : Bool;
      nLastBarcode : DInt;
      xNewCarrierAtScan : Bool;
      xBarcodeValid : Bool;
      xRisingBarcode : Bool;
      xBarcodeValidLast : Bool;
      nFoundIndex : Int;
   END_VAR

   VAR_TEMP 
      str_FillingLevel : Struct
         n_temp4002_1 : USInt;
         n_temp4002_2 : USInt;
         n_temp4003_1 : USInt;
         n_temp4003_2 : USInt;
         n_temp4003_3 : USInt;
         n_temp4003_4 : USInt;
         n_temp4003_5 : USInt;
         n_temp4003_6 : USInt;
         n_temp4003_7 : USInt;
         n_temp4004_1 : USInt;
         n_temp4005_1 : USInt;
         n_temp4006_1 : USInt;
         n_temp4007_1 : USInt;
         n_temp4008_1 : USInt;
         n_temp4009_1 : USInt;
         n_temp4010_1 : USInt;
         n_temp4010_2 : USInt;
      END_STRUCT;
   END_VAR

   VAR CONSTANT 
      cMultiPurposeStation1 : Int := 1;
      cMultiPurposeStation2 : Int := 2;
      cMultiPurposeStation3 : Int := 3;
      cStationActive : Int := 1;
      cScanPosJam4003_3 : Int := 1;
      cDestinationJam4003_7 : Int;
      cScanPosJam4003_5 : Int := 1;
      cScanPosJam4003_6 : Int := 1;
      cLoopDestination : DInt := 40037;
      "~~~~~~~~BufferSequence~~~~~~~~" : Int;
      c000_Wait : Int;
      c010_NewData : Int := 10;
      c020_SearchEmptyElement : Int := 20;
      c030_Finish : Int := 30;
      c040_Reset : Int := 40;
   END_VAR


BEGIN
	REGION Info
	(* Company: Schönenberger Systeme GmbH / (C) Copyright (2022). All rights reserved.
	-----------------------------------------------------------------------------------------
	Title: FB_AMR_Management
	Comment/Function: manages carrier way finding in area AMR
	Library/Family: -
	Author: department: "Automatisierung" ; person in charge / contact: C.Nottelmann (Automated Intelligence)
	Target System: CPU 1518F-4 PN/DP
	Engineering: TIA Portal V20
	Restrictions: -
	Requirements: -
	-----------------------------------------------------------------------------------------
	Change log table:
	Version     | Date       | Signature (Safety) | Expert in charge | Changes applied
	------------|------------|--------------------|------------------|-----------------------
	001.000.000 | 2025-03-08 | -                  | Nottelmann       | Initial, Header added on 08.03.2025
	002.000.000 | 2025-12-05 | -                  | Yüksel           |    
	                                                                   
	*)
	END_REGION
	
	REGION ToDo
	    (*
	    - theoretisch mehrere Actions berücksichtigen! Aktuell wird nur auf die erste geschaut                
	    *)
	END_REGION
	
	REGION check Array size
	    // Conv
	    #n_LowerBound := DINT_TO_USINT(LOWER_BOUND(ARR := #arrudt_InOutJam, DIM := 1));
	    #n_UpperBound := DINT_TO_USINT(UPPER_BOUND(ARR := #arrudt_InOutJam, DIM := 1));
	    
	    // MES Message Buffer
	    #n_LowerBoundBuffer := DINT_TO_USINT(LOWER_BOUND(ARR := #arrudt_InOutCarrierBuffer, DIM := 1));
	    #n_UpperBoundBuffer := DINT_TO_USINT(UPPER_BOUND(ARR := #arrudt_InOutCarrierBuffer, DIM := 1));
	    
	END_REGION
	
	REGION Buffer MES Message
	    
	    CASE #n_StepBufferMES OF
	        #c000_Wait:
	            REGION c000_Wait
	                //Action
	                
	                //Transition
	                IF #udt_InOut_HandshakeDataMES.str_Ctrl.xNewDataAvaible
	                THEN
	                    #n_StepBufferMES := #c010_NewData;
	                END_IF;
	            END_REGION
	            
	        #c010_NewData:
	            REGION c010_NewData
	                //Action
	                #udt_DataMESSave := #udtIn_DataMES.stPayload;
	                #udt_InOut_HandshakeDataMES.str_Status.xReadingNewData := True;
	                //Transition
	                IF #udt_DataMESSave.nBarcode > 0
	                THEN
	                    #n_StepBufferMES := #c020_SearchEmptyElement;
	                    //Else Error
	                END_IF;
	            END_REGION
	            
	        #c020_SearchEmptyElement:
	            
	            REGION c020_SearchEmptyElement
	                //Action
	                FOR #n_EmptyElementIDX := #n_LowerBoundBuffer TO #n_UpperBoundBuffer DO
	                    IF #arrudt_InOutCarrierBuffer[#n_EmptyElementIDX].stPayload.nBarcode = 0
	                    THEN
	                        #n_EmptyElementIDXSave := #n_EmptyElementIDX;
	                        #arrudt_InOutCarrierBuffer[#n_EmptyElementIDX].stPayload := #udt_DataMESSave;
	                        #udt_InOut_HandshakeDataMES.str_Status.xNewDataSaved := True;
	                        #udt_InOut_HandshakeDataMES.str_Status.xReadingNewData := False;
	                        EXIT;
	                    END_IF;
	                    
	                END_FOR;
	                
	                //Transition
	              //  IF #udtIn_DataMES.stPayload.nBarcode > 0
	                IF  #udt_InOut_HandshakeDataMES.str_Status.xNewDataSaved THEN
	                    #n_StepBufferMES := #c030_Finish;
	                END_IF;
	            END_REGION
	            
	        #c030_Finish:
	            REGION c030_Finish
	                // Action
	                
	                //Transition
	                IF NOT #udt_InOut_HandshakeDataMES.str_Ctrl.xNewDataAvaible
	                THEN
	                    #n_StepBufferMES := #c040_Reset;
	                END_IF;
	            END_REGION
	            
	        #c040_Reset:
	            REGION c040_Reset
	                //Action
	                #udt_InOut_HandshakeDataMES.str_Status.xReadingNewData := False;
	                #udt_InOut_HandshakeDataMES.str_Status.xNewDataSaved := False;
	                #udt_InOut_HandshakeDataMES.str_Status.xDataIncorrect := False;
	                #n_EmptyElementIDXSave := 0;
	                
	                //Transition
	                #n_StepBufferMES := #c000_Wait;
	            END_REGION
	    END_CASE;
	END_REGION
	
	REGION Daten aus Buffer übertragen
	    FOR #n_DatenBufferIDX := #n_LowerBoundBuffer TO #n_UpperBoundBuffer DO
	        FOR #n_DatenJamArea := #n_LowerBound TO #n_UpperBound DO
	            IF #n_DatenJamArea >= #n_LowerBound AND #n_DatenJamArea <= #n_UpperBound
	                AND #n_DatenBufferIDX >= #n_LowerBoundBuffer AND #n_DatenBufferIDX <= #n_UpperBoundBuffer
	            THEN
	                IF #arrudt_InOutCarrierBuffer[#n_DatenBufferIDX].stPayload.nBarcode = #arrudt_InOutJam[#n_DatenJamArea].nBarcode
	                //    AND #arrudt_InOutJam[#n_DatenJamArea].bStatus.%X1 //Carrier beladen
	                THEN
	                    #arrudt_InOutJam[#n_DatenJamArea].nDestination := STRING_TO_INT(#arrudt_InOutCarrierBuffer[#n_DatenBufferIDX].stPayload.arActions[0]);
	                    #arrudt_InOutCarrierBuffer[#n_DatenBufferIDX] := #udt_DeleteBuffer;
	                END_IF;
	            END_IF;
	        END_FOR;
	    END_FOR;
	END_REGION
	
	REGION Einfahrt AMR Feed stoppen
	    //wenn wir zu viele Rotierer haben, dann aufhören neue Carrier reinzuschicken. Anzahl rotierer?...
	    
	    IF "DB_Statistics".nRecircCount + #stInOutJam4003_2.stData.Status.nCount >= #stInOutJam4003_2.stData.Config.nCapacitySet
	    THEN
	        #xOutStopFeed := TRUE;
	    ELSE
	        #xOutStopFeed := FALSE;
	    END_IF;
	END_REGION
	
	REGION Kapazitaeten ermitteln
	    
	    REGION 4002
	        #str_FillingLevel.n_temp4002_1 := UINT_TO_USINT(#stInOutJam4002_1.stData.Status.nCount * 100 / "cJam4002_1");
	        #str_FillingLevel.n_temp4002_2 := UINT_TO_USINT(#stInOutJam4002_2.stData.Status.nCount * 100 / "cJam4002_2");
	        
	    END_REGION
	    
	    REGION 4003
	        #str_FillingLevel.n_temp4003_1 := UINT_TO_USINT(#stInOutJam4003_1.stData.Status.nCount * 100 / "cJam4003_1");
	        #str_FillingLevel.n_temp4003_2 := UINT_TO_USINT(#stInOutJam4003_2.stData.Status.nCount * 100 / "cJam4003_2");
	        #str_FillingLevel.n_temp4003_3 := UINT_TO_USINT(#stInOutJam4003_3.stData.Status.nCount * 100 / "cJam4003_3");
	        #str_FillingLevel.n_temp4003_4 := UINT_TO_USINT(#stInOutJam4003_4.stData.Status.nCount * 100 / "cJam4003_4");
	        #str_FillingLevel.n_temp4003_5 := UINT_TO_USINT(#stInOutJam4003_5.stData.Status.nCount * 100 / "cJam4003_5");
	        #str_FillingLevel.n_temp4003_6 := UINT_TO_USINT(#stInOutJam4003_6.stData.Status.nCount * 100 / "cJam4003_6");
	        #str_FillingLevel.n_temp4003_7 := UINT_TO_USINT(#stInOutJam4003_7.stData.Status.nCount * 100 / "cJam4003_7");
	    END_REGION
	    
	    REGION 4004
	        #str_FillingLevel.n_temp4004_1 := UINT_TO_USINT(#stInOutJam4004_1.stData.Status.nCount * 100 / "cJam4004_1");
	        
	        
	    END_REGION
	    
	    REGION 4005
	        #str_FillingLevel.n_temp4005_1 := UINT_TO_USINT(#stInOutJam4005_1.stData.Status.nCount * 100 / "cJam4005_1");
	        
	    END_REGION
	    
	    REGION 4006
	        #str_FillingLevel.n_temp4006_1 := UINT_TO_USINT(#stInOutJam4006_1.stData.Status.nCount * 100 / "cJam4006_1");
	        
	    END_REGION
	    
	    REGION 4007
	        #str_FillingLevel.n_temp4007_1 := UINT_TO_USINT(#stInOutJam4007_1.stData.Status.nCount * 100 / "cJam4007_1");
	        
	    END_REGION
	    
	    REGION 4008
	        #str_FillingLevel.n_temp4008_1 := UINT_TO_USINT(#stInOutJam4008_1.stData.Status.nCount * 100 / "cJam4008_1");
	        
	    END_REGION
	    
	    REGION 4009
	        #str_FillingLevel.n_temp4009_1 := UINT_TO_USINT(#stInOutJam4009_1.stData.Status.nCount * 100 / "cJam4009_1");
	        
	    END_REGION
	    
	    REGION 4010
	        #str_FillingLevel.n_temp4010_1 := UINT_TO_USINT(#stInOutJam4010_1.stData.Status.nCount * 100 / "cJam4010_1");
	        #str_FillingLevel.n_temp4010_2 := UINT_TO_USINT(#stInOutJam4010_2.stData.Status.nCount * 100 / "cJam4010_2");
	    END_REGION
	    
	END_REGION
	
	REGION Release Carrier to Destination Cycle
	(*    
	    // ---------------------------------------------------------
	    // NEW: Neue Scanner-Ankunft erkennen (Barcode-Wechsel)
	    //      => Retry/Timer pro Ankunft sauber zurücksetzen
	    // ---------------------------------------------------------
	    // detect new valid barcode (rising-edge)
	    #xBarcodeValid := #udt_InTro406Scan.nBarcode <> 0;
	    #xRisingBarcode := #xBarcodeValid AND NOT #xBarcodeValidLast;
	    #xBarcodeValidLast := #xBarcodeValid;
	    
	    IF #xRisingBarcode AND (#udt_InTro406Scan.nBarcode <> #nLastBarcode) THEN
	        #nLastBarcode := #udt_InTro406Scan.nBarcode;
	        #xRequeueDone := FALSE;
	        #xCarrierFound := FALSE;
	        #xWaitingForRelease := FALSE;
	        #x_Release := FALSE;
	        #LtonMaxWait(IN := FALSE,
	                     PT := #tInMaxWaitTimeRequeue);
	    END_IF;
	    
	    IF NOT #xWaitingForRelease
	    THEN
	        //Barcode am Scanner in der Datenbank suchen um das Ziel auszulesen
	        IF NOT #xCarrierFound THEN
	            #nFoundIndex := 0;
	            FOR #nSearchCarrierIDX := 1 TO "cJam4003_2" DO
	                IF #udt_InTro406Scan.nBarcode = #stInOutJam4003_2.arCarrier[#nSearchCarrierIDX].nBarcode
	                THEN
	                    #nFoundIndex := #nSearchCarrierIDX;
	                    #nSearchCarrierIDestination := #stInOutJam4003_2.arCarrier[#nSearchCarrierIDX].nDestination;
	                    #xCarrierFound := True;
	                    EXIT;
	                END_IF;
	            END_FOR;
	        END_IF;
	        
	        //Timer läuft nur wenn ein Carrier identifiziert ist
	        IF #xCarrierFound THEN
	            #LtonMaxWait(IN := TRUE,
	                         PT := #tInMaxWaitTimeRequeue);
	        ELSE
	            #LtonMaxWait(IN := FALSE,
	                         PT := #tInMaxWaitTimeRequeue);
	        END_IF;
	        
	        CASE #nSearchCarrierIDestination OF
	            #cMultiPurposeStation1:
	                IF (* #str_FillingLevel.n_temp4003_3 > #str_InCapacityTrigger.str_4003.n_4003_3
	                    AND #str_FillingLevel.n_temp4003_4 > #str_InCapacityTrigger.str_4003.n_4003_4
	                    AND #str_FillingLevel.n_temp4003_5 > #str_InCapacityTrigger.str_4003.n_4003_5
	                    AND #str_FillingLevel.n_temp4008_1 > #str_InCapacityTrigger.str_4008.n_4008_1 *)
	                    
	                    #stInOutJam4003_3.stData.Status.nCount < #stInOutJam4003_3.stData.Config.nCapacitySet
	                    AND #stInOutJam4003_4.stData.Status.nCount < #stInOutJam4003_4.stData.Config.nCapacitySet
	                    AND #stInOutJam4003_5.stData.Status.nCount < #stInOutJam4003_5.stData.Config.nCapacitySet
	                    AND #udt_InOut_MultiPurposeStation1.nCountTotal < #stInOutJam4008_1.stData.Config.nCapacitySet
	                    
	                    AND #udt_InOut_MultiPurposeStation1.nActivationStatus = #cStationActive
	                THEN
	                    #x_Release := True;
	                    #xWaitingForRelease := True;
	                    // NEW
	                    #LtonMaxWait(IN := FALSE,
	                                 PT := #tInMaxWaitTimeRequeue);
	                END_IF;
	            #cMultiPurposeStation2:
	                IF (* #str_FillingLevel.n_temp4003_3 > #str_InCapacityTrigger.str_4003.n_4003_3
	                    AND #str_FillingLevel.n_temp4003_4 > #str_InCapacityTrigger.str_4003.n_4003_4
	                    AND #str_FillingLevel.n_temp4006_1 > #str_InCapacityTrigger.str_4006.n_4006_1 *)
	                    
	                    
	                    #stInOutJam4003_3.stData.Status.nCount < #stInOutJam4003_3.stData.Config.nCapacitySet
	                    AND #stInOutJam4003_4.stData.Status.nCount < #stInOutJam4003_4.stData.Config.nCapacitySet
	                    AND #udt_InOut_MultiPurposeStation2.nCountTotal < #stInOutJam4006_1.stData.Config.nCapacitySet
	                    
	                    AND #udt_InOut_MultiPurposeStation2.nActivationStatus = #cStationActive
	                THEN
	                    #x_Release := True;
	                    #xWaitingForRelease := True;
	                    // NEW
	                    #LtonMaxWait(IN := FALSE,
	                                 PT := #tInMaxWaitTimeRequeue);
	                END_IF;
	            #cMultiPurposeStation3:
	                IF (* #str_FillingLevel.n_temp4003_3 > #str_InCapacityTrigger.str_4003.n_4003_3
	                    AND #str_FillingLevel.n_temp4004_1 > #str_InCapacityTrigger.str_4004.n_4004_1 *)
	                    
	                    #stInOutJam4003_3.stData.Status.nCount < #stInOutJam4003_3.stData.Config.nCapacitySet
	                    AND #udt_InOut_MultiPurposeStation3.nCountTotal < #stInOutJam4004_1.stData.Config.nCapacitySet + "DB_JamArea4004".stJam4004_2.stData.Config.nCapacitySet
	                    
	                    AND #udt_InOut_MultiPurposeStation3.nActivationStatus = #cStationActive
	                THEN
	                    #x_Release := True;
	                    #xWaitingForRelease := True;
	                    // NEW
	                    #LtonMaxWait(IN := FALSE,
	                                 PT := #tInMaxWaitTimeRequeue);
	                END_IF;
	                
	        END_CASE;
	        
	        // ---------------------------------------------------------
	        // NEW: Timeout -> Destination auf "Kreis/Requeue" setzen
	        //      und EINMAL pro Scanner-Ankunft releasen
	        // ---------------------------------------------------------
	        IF #LtonMaxWait.Q AND NOT #xWaitingForRelease THEN
	            IF NOT #xRequeueDone THEN
	                IF #nFoundIndex <> 0 THEN
	                    // auf Kreis-Ziel umbiegen
	                    #stInOutJam4003_2.arCarrier[#nFoundIndex].nDestination := "cDestStayAmr";
	                    
	                    // nur einmal pro Ankunft
	                    #xRequeueDone := TRUE;
	                    
	                    // releasen => fährt Kreis und stellt sich hinten an
	                    #x_Release := TRUE;
	                    #xWaitingForRelease := TRUE;
	                    
	                    // Timer reset
	                    #LtonMaxWait(IN := FALSE,
	                                 PT := #tInMaxWaitTimeRequeue);
	                END_IF;
	            END_IF;
	        END_IF;
	        
	        
	    END_IF;
	    
	    IF (* #udt_TRO406.udt_State.xReady AND *)#x_Release
	    THEN
	        #udt_TRO406.udt_Ctrl.xStop := False;
	    ELSE
	        // #x_Release := False;
	        // #xWaitingForRelease := False;
	        #udt_TRO406.udt_Ctrl.xStop := True;
	    END_IF;
	    
	    *)
	END_REGION
	
	REGION Seperator Monitoring
	    
	 (*   #lfb_TRO407Scan(t_InNoProgressTime := #t_InTRO407Watchdog,
	                    x_OutAssignNewDest => #x_TRO407NewDestination,
	                    udt_Scan_Result := #udt_TRO407.udt_Scan_Result);
	    
	    
	    
	    
	    #lfb_TRO410Scan(t_InNoProgressTime := #t_InTRO410Watchdog,
	                    x_OutAssignNewDest => #x_TRO410NewDestination,
	                    udt_Scan_Result := #udt_TRO410.udt_Scan_Result);
	    
	    
	    
	    #lfb_TRO413Scan(t_InNoProgressTime := #t_InTRO413Watchdog,
	                    x_OutAssignNewDest => #x_TRO413NewDestination,
	                    udt_Scan_Result := #udt_TRO413.udt_Scan_Result);
	    
	    
	    // Bei Zieländerung stop und reset an TRO -> Ready vom TRO fällt weg -> reset wird zurückgesetzt -> Ready wieder da -> Stop zurücksetzen
	    
	    
	    
	    
	    #lfb_TRO407Handshake(xInNewDestination := #x_TRO407NewDestination,
	                         nInDestination := #cDestinationJam4003_7,
	                         udt_InOutTRO := #udt_TRO407,
	                         st_InOutJamDestData := #stInOutJam4003_4.stData,
	                         arCarrier := #stInOutJam4003_3.arCarrier);
	    
	    #lfb_TRO410Handshake(xInNewDestination := #x_TRO410NewDestination,
	                         nInDestination := #cDestinationJam4003_7,
	                         udt_InOutTRO := #udt_TRO410,
	                         st_InOutJamDestData := #stInOutJam4003_5.stData,
	                         arCarrier := #stInOutJam4003_4.arCarrier);
	    
	    #lfb_TRO413Handshake(xInNewDestination := #x_TRO413NewDestination,
	                         nInDestination := #cDestinationJam4003_7,
	                         udt_InOutTRO := #udt_TRO413,
	                         st_InOutJamDestData := #stInOutJam4003_6.stData,
	                         arCarrier := #stInOutJam4003_5.arCarrier); *)
	END_REGION
END_FUNCTION_BLOCK

