FUNCTION "FC2010_ZC_V" : Void
TITLE = FC2010_V
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : ABH
FAMILY : ZeusControl
VERSION : 1.0
//Modelo de dispositivo vlvula
   VAR_INPUT 
      Pulso1seg : Bool;   // Pulso de 1 segundo
      Simulacion : Bool;   // Simulacion
      Arranque : Bool;   // Primer arranque
      Ack : Bool;   // Acuse general
      SeguridadesOK : Bool;   // Seguridades OK
      UsuarioActual : String;   // Usuario actual
      FechaHoraActual {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;   // Fecha y hora actual
   END_VAR

   VAR_TEMP 
      for_i : Int;
      t_N_MAX : Int;
      t_Activar : Bool;
      t_ErrorReposo : Bool;
      t_ErrorTrabajo : Bool;
      t_ErrorDoble : Bool;
   END_VAR

   VAR CONSTANT 
      TIPO_ACCESO_INDIRECTO : SInt := 0;
      TIPO_ACCESO_PLC : SInt := 1;
   END_VAR


BEGIN
	REGION DESCRIPCION
	(*
	###### (C)Copyright ZeusControl 2020 - 2026
	
	---
	### Información del Sistema
	| Hardware Compatible | Entorno de Ingeniería |
	|---------------------|-----------------------|
	| PLC serie 1200/1500 | TIA Portal 18         |
	
	---
	> **Restricciones:** Ninguna.
	
	---
	### Descripción Funcional
	
	Funcion para la gestion de dispositivo de tipo Valvula.
	
	En ella se realizan las siguientes acciones:
	
	- Se gestiona el multiplexado de los dispositivos para su uso en sistemas HMI/SCADA.
	- Se gestiona el estado del dispositivo
	- Se gestiona el numero de activaciones
	- Se gestiona la orden de escritura
	- Se gestiona la trazabilidad de las manualizaciones del dispositivo
	
	---
	### Dependencias Requeridas
	| Tipo | Elementos |
	|------|-----------|
	| FC   | `FC8_ZC_TRAZA_REGISTRO` |
	| FB   | - |
	| DB   | `DB1_SYS`, `DB2010_V` |
	| UDT  | - |
	
	---
	### Historial de Cambios
	| Versión  | Fecha      | Técnico | Cambios |
	|----------|------------|---------|---------|
	| 00.00.01  | 15.10.2020 | (ABH)   | Primera version. |
	| 00.00.02  | 28.11.2020 | (ABH)   | Añadidas alarmas mantenimiento |
	| 00.00.03  | 28.07.2021 | (ABH)   | Añadidas alarmas en doble posicion / ninguna posicion |
	| 00.00.04  | 22.12.2021 | (ABH)   | Añadido bit de visibilidad, a traves de variable CFG_Hmi_ |
	| 00.00.05  | 26.04.2022 | (HCR)   | Cambio UDT |
	| 00.00.06  | 26.04.2022 | (HCR)   | BITs de visibilidad para HMI, quitar enclavamiento para orden manual |
	| 00.00.07  | 27.04.2022 | (HCR)   | Si no esta habilitado se quita orden manual y se quita el estado manual. Se agrega Ack para alarma de confirmación de marcha. Se mantiene el estado de válvula cuando se pasa a manual. Cambio en lógica de errores. Cambio en la escritura de la salida                                             |
	| 00.00.08  | 08.11.2022 | (ABH)   | Se añade trazabilidad manualizaciones  |
	| 00.00.09  | 08.11.2022 | (HCR)   | Se añade trazabilidad de activación manual |
	| 00.00.10  | 08.11.2022 | (HCR)   | Cambio lógica enclavamiento |
	| 00.00.11  | 22.02.2024 | (ABH)   | Se añade gestion multiplexado para Scada (no indexado) |
	| 00.00.12  | 08.01.2025 | (ABH)   | Se añade entrada de primer arranque del PLC para resetear indices de multiplexado. Se añade movimiento de V[0] a multiplexado en caso de que el indice sea 0.  |
	| 00.00.13  | 24.01.2025 | (ABH)   | Se modifica la logica del multiplexado, la asignacion de oldindex se cambia de sitio ya que de vez en cuando (dependiendo de cuando el HMI realiza la comunicacion asincrona con el PLC) no detectaba el cambio y se machacaban valores. |
	| 00.00.14  | 26.03.2025 | (ABH)   | Se añade variable grupo de alarma para separar los nuevos avisos por cuadro. |
	| 00.00.15  | 24.04.2025 | (HCR)   | Se añade gestion de idioma  |
	| 00.00.16  | 11.09.2025 | (ABH)   | Se eliminan las constantes de idioma dentro del FC. Se utilizan constantes globales para facilitar su traduccion. |
	| 00.00.17  | 17.12.2025 | (ABH)   | Se eliminan los idiomas. Se utiliza codigos para trazabilidad. Se elimina entrada "Idioma". Se elimina nombre de UDT. Se elimina nombre de UDT. Se añade indexHMI para lista de texto en sistemas de supervision. |
	| 01.00.00  | 18.05.2026 | (ABH)   | Se añade variable `Config_TipoAcceso` para uso de direccionamiento indirecto o uso directo en PLC. |
	| 01.01.00  | 09.07.2026 | (ABH)   | Se extrae el multiplexado a FC independiente. |
	*)
	END_REGION DESCRIPCION
	
	
	REGION LOGICA_DEL_DISPOSITIVO
	    
	    // =============================================================================
	    // Resetear todas las alarmas para que se vuelvan a generar
	    FOR #for_i := 0 TO "N_MAX_DISP_AGRUP" DO
	        "DB2010_V".Agrup[#for_i].AlgunaAlarma := FALSE;
	        "DB2010_V".Agrup[#for_i].AlgunaEnManual := FALSE;
	    END_FOR;
	    
	    //  Numero maximo de dispositivos para limitar en HMI/Scada
	    "DB2010_V".Mux.NumDispositivos := "N_MAX_DISP_V";
	    
	    REGION COMPROBACION_N_MAX
	        
	        //  Si no hay dispositivos declarados, salimos del bloque inmediatamente
	        IF "N_MAX_DISP_V" <= 0 THEN
	            RETURN;
	        END_IF;
	        
	        //  Traspaso de N_MAX a variable temporal para evitar fallos de compilacion
	        #t_N_MAX := "N_MAX_DISP_V";
	        
	    END_REGION COMPROBACION_N_MAX
	    
	    FOR #for_i := 1 TO #t_N_MAX DO
	        
	        // =============================================================================
	        // DISPOSITIVO HABILITADO
	        // =============================================================================
	        IF "DB2010_V".V[#for_i].Config_Habilitar THEN
	            
	            REGION LIMITE_GRUPO_ALARMA
	                
	                IF "DB2010_V".V[#for_i].Config_GrupoAlarma < 0 THEN
	                    "DB2010_V".V[#for_i].Config_GrupoAlarma := 0;
	                END_IF;
	                IF "DB2010_V".V[#for_i].Config_GrupoAlarma > "N_MAX_DISP_AGRUP" THEN
	                    "DB2010_V".V[#for_i].Config_GrupoAlarma := "N_MAX_DISP_AGRUP";
	                END_IF;
	                
	            END_REGION LIMITE_GRUPO_ALARMA
	            
	            // =============================================================================
	            //  PUESTA A CERO DE LA SALIDA
	            #t_Activar := FALSE;
	            
	            REGION LECTURA_VALORES
	                
	                CASE "DB2010_V".V[#for_i].Config_TipoAcceso OF
	                        
	                    #TIPO_ACCESO_INDIRECTO:
	                        (* AREA: Pueden seleccionarse las siguientes áreas: 16#81: Input, 16#82: Output, 16#83: Marcas, 16#84: DB, 16#1: Entrada de periferia (solo S7-1500)
	                        DBNUMBER: Número del bloque de datos si AREA = DB, de lo contrario "0"
	                        BYTEOFFSET: Dirección en la que se lee. Solo se utilizan los 16 bits menos significativos.*)
	                        
	                        // =============================================================================
	                        // RETORNO REPOSO
	                        IF "DB2010_V".V[#for_i].Config_DireccionRetReposoByte >= 0 THEN
	                            
	                            "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo := PEEK_BOOL(area := 16#81,
	                                                                                          dbNumber := 0,
	                                                                                          byteOffset := "DB2010_V".V[#for_i].Config_DireccionRetReposoByte,
	                                                                                          bitOffset := "DB2010_V".V[#for_i].Config_DireccionRetReposoBit);
	                            
	                            IF "DB2010_V".V[#for_i].Config_HabilitarInvertirReposo THEN
	                                "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo := NOT (PEEK_BOOL(area := 16#81,
	                                                                                                   dbNumber := 0,
	                                                                                                   byteOffset := "DB2010_V".V[#for_i].Config_DireccionRetReposoByte,
	                                                                                                   bitOffset := "DB2010_V".V[#for_i].Config_DireccionRetReposoBit));
	                            END_IF;
	                            
	                        END_IF;
	                        
	                        // =============================================================================
	                        // RETORNO TRABAJO
	                        IF "DB2010_V".V[#for_i].Config_DireccionRetTrabajoByte >= 0 THEN
	                            "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo := PEEK_BOOL(area := 16#81,
	                                                                                           dbNumber := 0,
	                                                                                           byteOffset := "DB2010_V".V[#for_i].Config_DireccionRetTrabajoByte,
	                                                                                           bitOffset := "DB2010_V".V[#for_i].Config_DireccionRetTrabajoBit);
	                            IF "DB2010_V".V[#for_i].Config_HabilitarInvertirTrabajo THEN
	                                "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo := NOT (PEEK_BOOL(area := 16#81,
	                                                                                                    dbNumber := 0,
	                                                                                                    byteOffset := "DB2010_V".V[#for_i].Config_DireccionRetTrabajoByte,
	                                                                                                    bitOffset := "DB2010_V".V[#for_i].Config_DireccionRetTrabajoBit));
	                            END_IF;
	                            
	                        END_IF;
	                        
	                        
	                    #TIPO_ACCESO_PLC:
	                        ;
	                        
	                END_CASE;
	                
	            END_REGION LECTURA_VALORES
	            
	            
	            REGION MODOS_DE_TRABAJO
	                
	                // =============================================================================
	                //  MODO MANUAL
	                IF "DB2010_V".V[#for_i].Estado_AutoMan THEN
	                    "DB2010_V".Agrup["DB2010_V".V[#for_i].Config_GrupoAlarma].AlgunaEnManual := TRUE;
	                    IF "DB2010_V".V[#for_i].Orden_ActivarManual AND #SeguridadesOK AND "DB2010_V".V[#for_i].Estado_SeguridadOk THEN // En caso de enclavar válvula en manual AND NOT "DB2035_TMF1_DISP_V".V[#i].Estado_Enclavado
	                        #t_Activar := TRUE;
	                    ELSE
	                        #t_Activar := FALSE;
	                        "DB2010_V".V[#for_i].Orden_ActivarManual := FALSE;
	                    END_IF;
	                ELSE
	                    "DB2010_V".V[#for_i].Orden_ActivarManual := FALSE;
	                END_IF;
	                
	                // =============================================================================
	                //  MODO AUTO
	                IF NOT "DB2010_V".V[#for_i].Estado_AutoMan THEN
	                    IF "DB2010_V".V[#for_i].Orden_ActivarAuto AND NOT "DB2010_V".V[#for_i].Estado_Enclavado AND #SeguridadesOK AND "DB2010_V".V[#for_i].Estado_SeguridadOk THEN
	                        #t_Activar := TRUE;
	                    ELSE
	                        #t_Activar := FALSE;
	                    END_IF;
	                    "DB2010_V".V[#for_i].Orden_ActivarManual := "DB2010_V".V[#for_i].Estado_Activado;
	                END_IF;
	                
	            END_REGION MODOS_DE_TRABAJO
	            
	            
	            REGION ESTADO_DEL_DISPOSITIVO
	                
	                // =============================================================================
	                //  VÁLVULA SIMULADA
	                IF #Simulacion THEN
	                    
	                    IF #t_Activar THEN
	                        "DB2010_V".V[#for_i].Estado_Activado := TRUE;
	                    ELSE
	                        "DB2010_V".V[#for_i].Estado_Activado := FALSE;
	                    END_IF;
	                    
	                END_IF;
	                
	                // =============================================================================
	                // VÁLVULA 2 RETORNOS (REPOSO + TRABAJO)
	                IF NOT #Simulacion AND
	                    "DB2010_V".V[#for_i].Config_HabilitarRetornoReposo AND "DB2010_V".V[#for_i].Config_HabilitarRetornoTrabajo
	                THEN
	                    
	                    IF "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo AND NOT "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo AND #t_Activar THEN
	                        "DB2010_V".V[#for_i].Estado_Activado := TRUE;
	                    END_IF;
	                    
	                    IF "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo AND NOT "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo AND NOT #t_Activar THEN
	                        "DB2010_V".V[#for_i].Estado_Activado := FALSE;
	                    END_IF;
	                    
	                END_IF;
	                
	                // =============================================================================
	                // VÁLVULA SOLO RETORNO REPOSO
	                IF NOT #Simulacion AND
	                    "DB2010_V".V[#for_i].Config_HabilitarRetornoReposo AND NOT "DB2010_V".V[#for_i].Config_HabilitarRetornoTrabajo
	                THEN
	                    
	                    IF NOT "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo THEN
	                        "DB2010_V".V[#for_i].Estado_Activado := TRUE;
	                    ELSE
	                        "DB2010_V".V[#for_i].Estado_Activado := FALSE;
	                    END_IF;
	                    
	                END_IF;
	                
	                // =============================================================================
	                // VÁLVULA SOLO RETORNO TRABAJO
	                IF NOT #Simulacion AND
	                    NOT "DB2010_V".V[#for_i].Config_HabilitarRetornoReposo AND "DB2010_V".V[#for_i].Config_HabilitarRetornoTrabajo
	                THEN
	                    
	                    IF "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo THEN
	                        "DB2010_V".V[#for_i].Estado_Activado := TRUE;
	                    ELSE
	                        "DB2010_V".V[#for_i].Estado_Activado := FALSE;
	                    END_IF;
	                    
	                END_IF;
	                
	                // =============================================================================
	                // VÁLVULA SIN RETORNOS
	                IF NOT #Simulacion AND
	                    NOT "DB2010_V".V[#for_i].Config_HabilitarRetornoReposo AND NOT "DB2010_V".V[#for_i].Config_HabilitarRetornoTrabajo
	                THEN
	                    
	                    IF #t_Activar THEN
	                        "DB2010_V".V[#for_i].Estado_Activado := TRUE;
	                    ELSE
	                        "DB2010_V".V[#for_i].Estado_Activado := FALSE;
	                    END_IF;
	                    
	                END_IF;
	                
	            END_REGION ESTADO_DEL_DISPOSITIVO
	            
	            
	            REGION ERRORES
	                
	                // =============================================================================
	                // CHEQUEO RETORNO REPOSO
	                IF NOT #Simulacion AND
	                    "DB2010_V".V[#for_i].Config_HabilitarRetornoReposo AND
	                    (
	                    (#t_Activar AND "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo)
	                    OR
	                    (NOT #t_Activar AND NOT "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo)
	                    )
	                THEN
	                    #t_ErrorReposo := TRUE;
	                ELSE
	                    #t_ErrorReposo := FALSE;
	                END_IF;
	                
	                // =============================================================================
	                // CHEQUEO RETORNO TRABAJO
	                IF NOT #Simulacion AND
	                    "DB2010_V".V[#for_i].Config_HabilitarRetornoTrabajo AND
	                    (
	                    (#t_Activar AND NOT "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo)
	                    OR
	                    (NOT #t_Activar AND "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo)
	                    )
	                THEN
	                    #t_ErrorTrabajo := TRUE;
	                ELSE
	                    #t_ErrorTrabajo := FALSE;
	                END_IF;
	                
	                
	                // =============================================================================
	                // CHEQUEO DOBLE RETORNO EN DOS POSICIONES O EN NINGUNA POSICION
	                IF NOT #Simulacion AND
	                    ("DB2010_V".V[#for_i].Config_HabilitarRetornoReposo AND "DB2010_V".V[#for_i].Config_HabilitarRetornoTrabajo)
	                    AND
	                    (
	                    (NOT "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo AND NOT "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo)
	                    OR
	                    ("DB2010_V".V[#for_i].Estado_EntradaRetornoReposo AND "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo)
	                    )
	                THEN
	                    #t_ErrorDoble := TRUE;
	                ELSE
	                    #t_ErrorDoble := FALSE;
	                END_IF;
	                
	                
	                
	                // =============================================================================
	                // TEMPORIZADO DE ERRORES
	                IF (
	                    ("DB2010_V".V[#for_i].Config_HabilitarRetornoReposo AND #t_ErrorReposo AND NOT "DB2010_V".V[#for_i].Alarmas_Reposo)
	                    OR
	                    ("DB2010_V".V[#for_i].Config_HabilitarRetornoTrabajo AND #t_ErrorTrabajo AND NOT "DB2010_V".V[#for_i].Alarmas_Trabajo)
	                    OR
	                    ("DB2010_V".V[#for_i].Config_HabilitarRetornoReposo AND "DB2010_V".V[#for_i].Config_HabilitarRetornoTrabajo AND #t_ErrorDoble AND NOT "DB2010_V".V[#for_i].Alarmas_Doble)
	                    )
	                THEN
	                    IF #Pulso1seg AND NOT #Simulacion THEN
	                        "DB2010_V".V[#for_i].Tiempos_Alarma += 1;
	                    END_IF;
	                ELSE
	                    "DB2010_V".V[#for_i].Tiempos_Alarma := 0;
	                END_IF;
	                
	                
	                // =============================================================================
	                // ERROR REPOSO
	                IF "DB2010_V".V[#for_i].Tiempos_Alarma >= "DB2010_V".V[#for_i].Tiempos_SetPointTiempoAlarma AND #t_ErrorReposo THEN
	                    "DB2010_V".V[#for_i].Alarmas_Reposo := TRUE;
	                END_IF;
	                IF NOT #t_ErrorReposo THEN
	                    "DB2010_V".V[#for_i].Alarmas_Reposo := FALSE;
	                END_IF;
	                
	                
	                // =============================================================================
	                // ERROR TRABAJO
	                IF "DB2010_V".V[#for_i].Tiempos_Alarma >= "DB2010_V".V[#for_i].Tiempos_SetPointTiempoAlarma AND #t_ErrorTrabajo THEN
	                    "DB2010_V".V[#for_i].Alarmas_Trabajo := TRUE;
	                END_IF;
	                IF NOT #t_ErrorTrabajo THEN
	                    "DB2010_V".V[#for_i].Alarmas_Trabajo := FALSE;
	                END_IF;
	                
	                
	                // =============================================================================
	                // ERROR DOBLE
	                IF "DB2010_V".V[#for_i].Tiempos_Alarma >= "DB2010_V".V[#for_i].Tiempos_SetPointTiempoAlarma AND #t_ErrorDoble THEN
	                    "DB2010_V".V[#for_i].Alarmas_Doble := TRUE;
	                END_IF;
	                IF NOT #t_ErrorDoble THEN
	                    "DB2010_V".V[#for_i].Alarmas_Doble := FALSE;
	                END_IF;
	                
	                // =============================================================================
	                // ERROR GLOBAL
	                IF "DB2010_V".V[#for_i].Alarmas_Reposo OR
	                    "DB2010_V".V[#for_i].Alarmas_Trabajo OR
	                    "DB2010_V".V[#for_i].Alarmas_Doble
	                THEN
	                    "DB2010_V".V[#for_i].Alarmas_General := TRUE;
	                END_IF;
	                IF #Ack AND
	                    NOT "DB2010_V".V[#for_i].Alarmas_Reposo AND
	                    NOT "DB2010_V".V[#for_i].Alarmas_Trabajo AND
	                    NOT "DB2010_V".V[#for_i].Alarmas_Doble
	                THEN
	                    "DB2010_V".V[#for_i].Alarmas_General := FALSE;
	                END_IF;
	                
	                //"DB2010_V".V[#for_i].Alarmas_General := "DB2010_V".V[#for_i].Alarmas_Reposo OR "DB2010_V".V[#for_i].Alarmas_Trabajo OR "DB2010_V".V[#for_i].Alarmas_Doble;
	                
	                IF "DB2010_V".V[#for_i].Alarmas_General THEN
	                    "DB2010_V".Agrup["DB2010_V".V[#for_i].Config_GrupoAlarma].AlgunaAlarma := TRUE;
	                END_IF;
	                
	            END_REGION ERRORES
	            
	            
	            REGION DIAGNOSIS
	                
	                // =============================================================================
	                // CONTADOR DE CICLOS DE ACTIVACIÓN DE LA VÁLVULA
	                IF ("DB2010_V".V[#for_i].Estado_Activado AND NOT "DB2010_V".V[#for_i].Aux_oldActivado)
	                    OR
	                    (NOT "DB2010_V".V[#for_i].Estado_Activado AND "DB2010_V".V[#for_i].Aux_oldActivado)
	                THEN
	                    "DB2010_V".V[#for_i].Tiempos_Ciclos += 1;
	                END_IF;
	                
	                IF "DB2010_V".V[#for_i].Orden_ResetCiclos THEN
	                    "DB2010_V".V[#for_i].Tiempos_Ciclos := 0;
	                    "DB2010_V".V[#for_i].Orden_ResetCiclos := FALSE;
	                END_IF;
	                
	                // =============================================================================
	                //  ALARMA CICLOS PARA MANTENIMIENTO ALCANZADOS
	                "DB2010_V".V[#for_i].Alarmas_Mantenimiento := FALSE;
	                IF "DB2010_V".V[#for_i].Config_HabilitarMantenimiento AND ("DB2010_V".V[#for_i].Tiempos_Ciclos > "DB2010_V".V[#for_i].Tiempos_SetPointCiclos) THEN
	                    "DB2010_V".V[#for_i].Alarmas_Mantenimiento := TRUE;
	                END_IF;
	                
	                
	                
	            END_REGION DIAGNOSIS
	            
	            
	            REGION ESCRITURA_SALIDA
	                
	                CASE "DB2010_V".V[#for_i].Config_TipoAcceso OF
	                        
	                    #TIPO_ACCESO_INDIRECTO:
	                        // =============================================================================
	                        // ESCRITURA SALIDA
	                        (* AREA: Pueden seleccionarse las siguientes áreas:16#81: Input, 16#82: Output, 16#83: Marcas, 16#84: DB, 16#2: Salida de periferia (solo S7-1500)      
	                        DBNUMBER: Número del bloque de datos si AREA = DB, de lo contrario "0"
	                        BYTEOFFSET: Dirección que se escribe, Solo se utilizan los 16 bits menos significativos. 
	                        BITOFFSET: Bit que se escribe, 
	                        VALUE: Valor que se escribe *)
	                        
	                        IF "DB2010_V".V[#for_i].Config_DireccionSalidaByte >= 0 THEN
	                            
	                            IF #t_Activar AND NOT "DB2010_V".V[#for_i].Alarmas_General THEN
	                                
	                                "DB2010_V".V[#for_i].Estado_Salida := TRUE;
	                                POKE_BOOL(area := 16#82,
	                                          dbNumber := 0,
	                                          byteOffset := "DB2010_V".V[#for_i].Config_DireccionSalidaByte,
	                                          bitOffset := "DB2010_V".V[#for_i].Config_DireccionSalidaBit,
	                                          value := TRUE);
	                            ELSE
	                                
	                                "DB2010_V".V[#for_i].Estado_Salida := FALSE;
	                                POKE_BOOL(area := 16#82,
	                                          dbNumber := 0,
	                                          byteOffset := "DB2010_V".V[#for_i].Config_DireccionSalidaByte,
	                                          bitOffset := "DB2010_V".V[#for_i].Config_DireccionSalidaBit,
	                                          value := FALSE);
	                            END_IF;
	                        END_IF;
	                        
	                    #TIPO_ACCESO_PLC:
	                        IF #t_Activar AND NOT "DB2010_V".V[#for_i].Alarmas_General THEN
	                            "DB2010_V".V[#for_i].Estado_Salida := TRUE;
	                        ELSE
	                            "DB2010_V".V[#for_i].Estado_Salida := FALSE;
	                        END_IF;
	                        
	                END_CASE;
	                
	            END_REGION
	            
	            
	            // =============================================================================
	            //  RESET ORDEN ACTIVAR EN AUTO
	            "DB2010_V".V[#for_i].Orden_ActivarAuto := FALSE;
	            "DB2010_V".V[#for_i].Estado_Enclavado := FALSE;
	            
	            
	            REGION TRAZABILIDAD_MANUALIZACION
	                
	                IF "DB2010_V".V[#for_i].Estado_AutoMan AND NOT "DB2010_V".V[#for_i].Aux_oldAutoMan THEN
	                    "FC8_ZC_TRZ_REGISTRO"(FechaHora := #FechaHoraActual,
	                                            Registrar := 1,
	                                            Categoria := "TRZ_CAT_14_DISP_V",
	                                            User := #UsuarioActual,
	                                            CodInt_1 := "TRZ_SYS_DISP_TIPO_V",
	                                            CodInt_2 := #for_i,
	                                            CodInt_3 := "TRZ_SYS_DISP_ACC_MAN",
	                                            CodInt_4 := 0,
	                                            CodInt_5 := 0,
	                                            CodReal_1 := 0.0,
	                                            CodReal_2 := 0.0);
	                END_IF;
	                
	                IF NOT "DB2010_V".V[#for_i].Estado_AutoMan AND "DB2010_V".V[#for_i].Aux_oldAutoMan THEN
	                    "FC8_ZC_TRZ_REGISTRO"(FechaHora := #FechaHoraActual,
	                                            Registrar := 1,
	                                            Categoria := "TRZ_CAT_14_DISP_V",
	                                            User := #UsuarioActual,
	                                            CodInt_1 := "TRZ_SYS_DISP_TIPO_V",
	                                            CodInt_2 := #for_i,
	                                            CodInt_3 := "TRZ_SYS_DISP_ACC_AUTO",
	                                            CodInt_4 := 0,
	                                            CodInt_5 := 0,
	                                            CodReal_1 := 0.0,
	                                            CodReal_2 := 0.0);
	                END_IF;
	                
	                IF "DB2010_V".V[#for_i].Estado_AutoMan AND "DB2010_V".V[#for_i].Estado_Activado AND NOT "DB2010_V".V[#for_i].Aux_oldActivado THEN
	                    "FC8_ZC_TRZ_REGISTRO"(FechaHora := #FechaHoraActual,
	                                            Registrar := 1,
	                                            Categoria := "TRZ_CAT_14_DISP_V",
	                                            User := #UsuarioActual,
	                                            CodInt_1 := "TRZ_SYS_DISP_TIPO_V",
	                                            CodInt_2 := #for_i,
	                                            CodInt_3 := "TRZ_SYS_DISP_ACC_MAN_ON",
	                                            CodInt_4 := 0,
	                                            CodInt_5 := 0,
	                                            CodReal_1 := 0.0,
	                                            CodReal_2 := 0.0);
	                END_IF;
	                
	                IF "DB2010_V".V[#for_i].Estado_AutoMan AND NOT "DB2010_V".V[#for_i].Estado_Activado AND "DB2010_V".V[#for_i].Aux_oldActivado THEN
	                    "FC8_ZC_TRZ_REGISTRO"(FechaHora := #FechaHoraActual,
	                                            Registrar := 1,
	                                            Categoria := "TRZ_CAT_14_DISP_V",
	                                            User := #UsuarioActual,
	                                            CodInt_1 := "TRZ_SYS_DISP_TIPO_V",
	                                            CodInt_2 := #for_i,
	                                            CodInt_3 := "TRZ_SYS_DISP_ACC_MAN_OFF",
	                                            CodInt_4 := 0,
	                                            CodInt_5 := 0,
	                                            CodReal_1 := 0.0,
	                                            CodReal_2 := 0.0);
	                END_IF;
	                
	            END_REGION TRAZABILIDAD_MANUALIZACION
	            
	            // =============================================================================
	            //  Estado anterior manual/automatico
	            "DB2010_V".V[#for_i].Aux_oldActivado := "DB2010_V".V[#for_i].Estado_Activado;
	            "DB2010_V".V[#for_i].Aux_oldAutoMan := "DB2010_V".V[#for_i].Estado_AutoMan;
	            
	        ELSE
	            
	            // =============================================================================
	            // DISPOSITIVO NO HABILITADO
	            // =============================================================================
	            "DB2010_V".V[#for_i].Alarmas_General := FALSE;
	            "DB2010_V".V[#for_i].Alarmas_Reposo := FALSE;
	            "DB2010_V".V[#for_i].Alarmas_Trabajo := FALSE;
	            "DB2010_V".V[#for_i].Alarmas_Doble := FALSE;
	            "DB2010_V".V[#for_i].Alarmas_Mantenimiento := FALSE;
	            "DB2010_V".V[#for_i].Estado_EntradaRetornoTrabajo := FALSE;
	            "DB2010_V".V[#for_i].Estado_EntradaRetornoReposo := FALSE;
	            "DB2010_V".V[#for_i].Estado_Enclavado := FALSE;
	            "DB2010_V".V[#for_i].Estado_Salida := FALSE;
	            "DB2010_V".V[#for_i].Orden_ActivarAuto := FALSE;
	            "DB2010_V".V[#for_i].Estado_Activado := FALSE;
	            "DB2010_V".V[#for_i].Tiempos_Alarma := 0;
	            "DB2010_V".V[#for_i].Orden_ActivarManual := FALSE;
	            "DB2010_V".V[#for_i].Estado_AutoMan := FALSE;
	            
	        END_IF;
	        
	        
	        REGION GESTION_HMI
	            
	            // =============================================================================
	            //  GESTION BITS PARA VISUALIZACION
	            //  Bit     0   Habilitacion
	            //  Bit     1   ManualAutomatico
	            //  Bit     2   Enclavado
	            //  Bit     3   Activado 1
	            //  Bit     4   Activado 2
	            //  Bit     5   Reserva
	            //  Bit     6   Reserva
	            //  Bit     7   Reserva
	            //  Bit     8   Alarma General
	            //  Bit     9   Alarma 1
	            //  Bit     10  Alarma 2
	            //  Bit     11  Alarma 3
	            //  Bit     12  Alarma 4
	            //  Bit     13  Alarma Mantenimiento
	            //  Bit     14  Reserva
	            //  Bit     15  Reserva
	            "DB2010_V".V[#for_i].Hmi_Estado.%X0 := "DB2010_V".V[#for_i].Config_Habilitar;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X1 := "DB2010_V".V[#for_i].Estado_AutoMan;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X2 := "DB2010_V".V[#for_i].Estado_Enclavado;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X3 := "DB2010_V".V[#for_i].Estado_Activado;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X4 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X5 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X6 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X7 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X8 := "DB2010_V".V[#for_i].Alarmas_General;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X9 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X10 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X11 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X12 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X13 := "DB2010_V".V[#for_i].Alarmas_Mantenimiento;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X14 := FALSE;
	            "DB2010_V".V[#for_i].Hmi_Estado.%X15 := FALSE;
	            
	        END_REGION GESTION_HMI
	        
	        REGION GESTION_NUEVA_ALARMA
	            
	            // =============================================================================
	            //  DETECCION DE NUEVA ALARMA
	            IF "DB2010_V".V[#for_i].Alarmas_General AND NOT "DB2010_V".V[#for_i].Aux_oldAlarma THEN
	                "DB2010_V".Agrup["DB2010_V".V[#for_i].Config_GrupoAlarma].NuevaAlarma := TRUE;
	            END_IF;
	            
	            //  Estado anterior de las alarmas
	            "DB2010_V".V[#for_i].Aux_oldAlarma := "DB2010_V".V[#for_i].Alarmas_General;
	            
	        END_REGION GESTION_NUEVA_ALARMA
	        
	        
	    END_FOR;
	    
	    
	    // =============================================================================
	    //  ACUSE DE NUEVAS ALARMAS
	    IF #Ack THEN
	        FOR #for_i := 0 TO "N_MAX_DISP_AGRUP" DO
	            "DB2010_V".Agrup[#for_i].NuevaAlarma := FALSE;
	        END_FOR;
	    END_IF;
	    
	END_REGION LOGICA_DEL_DISPOSITIVO
	
END_FUNCTION

