FUNCTION_BLOCK "FB_OffsetCorrection"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      xInStart : Bool;
      xInCarousel : Bool;
      stInSettings : Struct
         nJamCount : Int;
         tWaitForEmpty : Time := T#10s;
      END_STRUCT;
   END_VAR

   VAR_OUTPUT 
      xOutTrigger : Bool;
      xOutActive : Bool;
   END_VAR

   VAR_IN_OUT 
      stInOutSepDataAct : "UDT_HMI_Separator";   // Wo Fehler entdeckt wurde
      stInOutJamDataAct : "UDT_HMI_JamData";   // Wo Fehler entdeckt wurde
      stInOutSepDataSource1 : "UDT_HMI_Separator";   // Wo zuvor Carrier herkamen 1
      stInOutJamDataSource1 : "UDT_HMI_JamData";   // Wo zuvor Carrier herkamen 1
      stInOutSepDataSource2 : "UDT_HMI_Separator";   // Wo zuvor Carrier herkamen 2
      stInOutJamDataSource2 : "UDT_HMI_JamData";   // Wo zuvor Carrier herkamen 2
   END_VAR

   VAR RETAIN
      xJamEntryLockedAct : Bool;   // Merken dass hier gesperrt wurde um mit Jam Status abzugleichen
      xJamExitLockedSource1 : Bool;   // Merken dass hier gesperrt wurde um mit Jam Status abzugleichen
      xJamExitLockedSource2 : Bool;   // Merken dass hier gesperrt wurde um mit Jam Status abzugleichen
      xSepOverrideSource1 : Bool;   // Merken dass hier Override gestartet wurde um mit Sep Status abzugleichen
      xSepOverrideSource2 : Bool;   // Merken dass hier Override gestartet wurde um mit Sep Status abzugleichen
   END_VAR
   VAR 
      nState : Int;
      fbStateManager { S7_SetPoint := 'False'} : "FB_StateManager";
      sStateText : String;
   END_VAR

   VAR CONSTANT 
      c0000_StepOff : Int := 0;
      c0100_StepUndefined : Int := 100;
      c1000_StepIdle : Int := 1000;
      c1500_StepStart : Int := 1500;
      c2000_StepWaitForEmpty : Int := 2000;
      c5000_StepCheckState : Int := 5000;
      c6000_StepOverrideSource : Int := 6000;
   END_VAR


BEGIN
	REGION Schrittkette
	    
	    CASE #nState OF
	        #c0000_StepOff:
	            REGION 0000: Off
	                // akt. Zustand
	                #sStateText := 'OFF';
	                #xOutActive := FALSE;
	                
	                // SCHRITT 0 WIRD GEBRAUCHT!
	                //STATE MANAGER KÜMMERT SICH UM TRANSITION!
	            END_REGION
	            
	        #c0100_StepUndefined:
	            REGION 0100: Undefined
	                // akt. Zustand
	                #sStateText := 'Undefined';
	                #xOutActive := FALSE;
	                
	                #nState := #c1000_StepIdle;
	            END_REGION
	            
	        #c1000_StepIdle:
	            REGION 1000: Idle
	                // akt. Zustand
	                #sStateText := 'Idle';
	                #xOutActive := FALSE;
	                
	                IF #xInStart THEN
	                    #nState := #c1500_StepStart;
	                END_IF;
	
	            END_REGION
	            
	        #c1500_StepStart:
	            REGION 1500: Start
	                // akt. Zustand
	                #sStateText := 'Start';
	                #xOutActive := TRUE;
	                
	                #stInOutJamDataAct.stStatus.bByte.%X2 := TRUE; //Jam Act Entry sperren
	                #xJamEntryLockedAct := TRUE;
	                
	                IF #fbStateManager.tOutTimeInStep > T#2000ms AND #xInCarousel THEN
	                    #nState := #c2000_StepWaitForEmpty;
	                END_IF;
	
	            END_REGION
	            
	        #c2000_StepWaitForEmpty:
	            REGION 2000: Wait for Empty
	                // akt. Zustand
	                #sStateText := 'Wait for empty';
	                #xOutActive := TRUE;
	                
	                IF #stInOutJamDataAct.stStatus.bByte.%X0 OR //Jam Act leer
	                    (NOT #stInOutSepDataAct.InSensor.xDbncdSensor AND #stInOutSepDataAct.InSensor.tDirectChangeLast > #stInSettings.tWaitForEmpty) THEN
	                    #nState := #c5000_StepCheckState;
	                END_IF;
	                
	            END_REGION
	            
	        #c5000_StepCheckState:
	            REGION 5000: Check Jam State
	                // akt. Zustand
	                #sStateText := 'Check Jam State';
	                #xOutActive := TRUE;
	                
	                IF #stInOutJamDataAct.stStatus.bByte.%X0 AND //Jam Act leer
	                    NOT #stInOutSepDataAct.InSensor.xDbncdSensor THEN
	                    #stInOutJamDataAct.stStatus.bByte.%X2 := FALSE; //Jam Act Entry freigeben
	                    #nState := #c1000_StepIdle;
	                ELSIF NOT #stInOutJamDataAct.stStatus.bByte.%X0 AND //Jam Act NOT leer
	                    NOT #stInOutSepDataAct.InSensor.xDbncdSensor THEN
	                    //aslkalksfjhaskfjaölkjflöaksg
	                    #nState := #c6000_StepOverrideSource;
	                END_IF;
	                
	            END_REGION
	            
	        #c6000_StepOverrideSource:
	            REGION 6000: Override Source
	                // akt. Zustand
	                #sStateText := 'Override Source';
	                #xOutActive := TRUE;
	                
	            END_REGION
	            
	    END_CASE;
	    
	    
	END_REGION
	
	REGION Tracen der Sources
	    //STRO Sep nState = 140 bedeutet das gebucht wird für einen Zyklus
	    IF #stInOutSepDataSource1.stStatus.nState = 140 THEN
	        // Statement section IF
	        ;
	    END_IF;
	    
	    // #stInOutSepDataSource1.stStatus.nState = 140 // wenn das passiert, dann diese Source merken in Ringpuffer. Wenn JamAct einen rauslässt, den entsprechenden Eintrag löschen und rest nachrücken
	    // hier weiter
	END_REGION
	
	
	
	REGION State Manager
	    #fbStateManager.stInSettings.nStartState := #c0100_StepUndefined;
	    #fbStateManager.stInSettings.nStartStateTestMode := #c0000_StepOff;
	    #fbStateManager.stInSettings.xActUnivTOn := TRUE;
	    #fbStateManager.stInSettings.xRestartAtStartState := FALSE;
	    #fbStateManager(xInFunctionEnabled := TRUE,
	                     // xInReset := (* #stInMfr.xCancel OR *)#xInCancel,
	                     // xInRunUnivTOn := #tmpActUnivTon,
	                     // xInTestMode := #xInTestMode,
	                     nInOutState := #nState);
	END_REGION
END_FUNCTION_BLOCK

