FUNCTION_BLOCK "FB_ESTOPhandling"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      tInPeriodicTime : Time := T#500ms;   // BlinkTime LED Output
      sInAlarmFunction : String[20];   // Alarm Function Name
      sInAlarmDevice : String[16];   // Alarm Prefix
      sInAlarmSuffix : String[16];   // Alarm Suffix
      sInAlarmMessage : String;   // Alarm Message
      xInAckReqLocal : Bool;   // Info from F-CPU: ESTOP.ACK_REQ
      xInEstopOkLocal : Bool;   // Info from F-CPU: ESTOP.Q Safety is Enabled
      xInAckReqGlobal : Bool;   // Sum-Info from Local ESTOP
      xInSafetyNotOkGlobal : Bool;   // Sum-Info from Local ESTOP
      xInMainCabinet : Bool := false;   // Activate Main Cabinet and global reset
      wInTextListId_Message : Word;
      wInTextListId_Function : Word;
      wInTextListId_Prefix : Word;
      wInTextListId_Suffix : Word;
   END_VAR

   VAR_OUTPUT 
      xOutLed : Bool;   // PushButton LED Output
      xOutSafetyNotOk : Bool;   // Info Output for MainCabinet
      xOutAckReq : Bool;   // Info Output for MainCabinet
   END_VAR

   VAR_IN_OUT 
      stInOutControlUnitCabinet : "UDT_MainState";   // MachineState of FB_StateMain
      stInOutHmiEstopPanel : "UDT_Panel_EmergencyStop";
   END_VAR

   VAR 
      FB_Blinker : "FB_Blinker";
      fbMonitoringEStop : "FB_Monitoring";
   END_VAR


BEGIN
	REGION Blinker 
	    // #FB_Blinker(tInPeriodicTime := #tInPeriodicTime,
	    //             xInActivate := 1);
	END_REGION
	
	REGION Logic
	    
	    // Local
	    IF NOT #xInMainCabinet THEN                  
	        
	        IF NOT #xInEstopOkLocal AND #xInAckReqLocal THEN
	            // Button not pressed but not Acknowledged 
	            #xOutLed := "Clock_1Hz"(* #FB_Blinker.xOutput *);
	            #xOutSafetyNotOk := FALSE;
	            #xOutAckReq := TRUE;
	            
	        ELSIF NOT #xInEstopOkLocal AND NOT #xInAckReqLocal THEN
	            // Button pressed
	            #xOutLed := TRUE;
	            #xOutSafetyNotOk := TRUE;
	            #xOutAckReq := FALSE;
	            
	        ELSIF #xInEstopOkLocal AND NOT #xInAckReqLocal THEN
	            // ESTOP Activated
	            #xOutLed := FALSE;
	            #xOutSafetyNotOk := FALSE;
	            #xOutAckReq := FALSE;
	            
	        ELSE
	            // Button pressed or Hardware-Error
	            #xOutLed := TRUE;
	            #xOutSafetyNotOk := TRUE;
	            #xOutAckReq := FALSE;
	            
	        END_IF;
	        
	    ELSE    // Global, Main Cabinet
	        
	        IF ((NOT #xInEstopOkLocal AND #xInAckReqLocal AND NOT #xInAckReqGlobal) OR
	            (#xInEstopOkLocal AND NOT #xInAckReqLocal AND #xInAckReqGlobal) OR
	            (NOT #xInEstopOkLocal AND #xInAckReqLocal AND #xInAckReqGlobal))
	            AND NOT #xInSafetyNotOkGlobal THEN
	            #xOutLed := "Clock_1Hz"(* #FB_Blinker.xOutput *);
	        ELSIF (NOT #xInEstopOkLocal AND NOT #xInAckReqLocal) OR #xInSafetyNotOkGlobal THEN
	            #xOutLed := true;
	        ELSIF #xInEstopOkLocal AND NOT #xInAckReqLocal THEN
	            #xOutLed := false;
	        ELSE
	            #xOutLed := true;
	        END_IF;
	        
	    END_IF;
	END_REGION
	
	REGION Monitoring
	
	    #fbMonitoringEStop.stSettings.nErrorType := 1;
	    #fbMonitoringEStop.stSettings.xErrLedIfMachineIsOff := TRUE;
	    #fbMonitoringEStop.stSettings.xSelfQuit := TRUE;
	    #fbMonitoringEStop(sInFctnName := #sInAlarmFunction,
	                       sInPrefix := #sInAlarmDevice,
	                       sInSuffix := #sInAlarmSuffix,
	                       InOutMachineState := #stInOutControlUnitCabinet,
	                       xInQuitError := #stInOutControlUnitCabinet.xQuitError,
	                       xInSignal := #xInEstopOkLocal,
	                       wInTextListId_Message := 0,
	                       wInTextListId_Function := #wInTextListId_Function,
	                       wInTextListId_Prefix := #wInTextListId_Prefix,
	                       wInTextListId_Suffix := #wInTextListId_Suffix,
	                       sInAlarmMessage := #sInAlarmMessage);
	         
	END_REGION
	
	REGION HMI  
	    #stInOutHmiEstopPanel.sPanelName := #sInAlarmDevice;
	    #stInOutHmiEstopPanel.sBMKEStop := #sInAlarmSuffix;
	    
	    #stInOutHmiEstopPanel.sBMKResetButton := '';
	    #stInOutHmiEstopPanel.sBMKResetLED := '';
	    
	    #stInOutHmiEstopPanel.xEStopActive := NOT #xInEstopOkLocal;
	    #stInOutHmiEstopPanel.xReset := #xOutLed;
	END_REGION
END_FUNCTION_BLOCK

