{
    S7_Author := "ABH";
    S7_BlockComment := "MLC_sX";
    S7_BlockNumber := "15055";
    S7_BlockTitle := "MLC_4FP";
    S7_EditorMode := "SCL";
    S7_Family := "ZeusControl";
    S7_IECCheck := "TRUE";
    S7_Optimized := "TRUE";
    S7_Version := "1.0"
}
FUNCTION_BLOCK "FB15055_ZC_HORAS_MAQUINA"
    VAR_INPUT
        { S7_MLC := "MLC_4SX" }
        Pulso1Seg : Bool;
        { S7_MLC := "MLC_44p" }
        FechaHora : DTL;
        { S7_MLC := "MLC_uf" }
        IniciarTiempoMaquina : Bool;
        { S7_MLC := "MLC_4cM" }
        IniciarTiempoProd : Bool;
        { S7_MLC := "MLC_4tx" }
        IniciarTiempoRecirc : Bool;
        { S7_MLC := "MLC_3nR" }
        IniciarTiempoEnzim : Bool;
        IniciarTiempoCIP : Bool;
        IniciarTiempoPausa : Bool;
        { S7_MLC := "MLC_tt" }
        ResetTiempoEnzim : Bool;
    END_VAR
    VAR_INPUT RETAIN
        { S7_MLC := "MLC_u6" }
        HabilitarMant : Bool;
        { S7_MLC := "MLC_37G" }
        SP_HorasAlarma : UDInt;
        { S7_MLC := "MLC_3Dq" }
        SP_MinutosAlarma : USInt;
    END_VAR
    VAR_INPUT
        { S7_MLC := "MLC_3Nb" }
        ProcesoID : Int;
    END_VAR
    VAR_INPUT RETAIN
        { S7_MLC := "MLC_i4" }
        Usuario : String[25];
    END_VAR
    VAR_OUTPUT
        { S7_MLC := "MLC_4qc" }
        ParoMantenimiento : Bool;
        { S7_MLC := "MLC_Zy" }
        VisTiempoRecirculacion : Bool;
    END_VAR
    VAR RETAIN
        {
            S7_MLC := "MLC_3jQ";
            S7_Setpoint := "False"
        }
        TiempoMaquina : _.UDT_ZC_CONTADOR_TIEMPO;
        {
            S7_MLC := "MLC_Vv";
            S7_Setpoint := "False"
        }
        TiempoMantenimiento : _.UDT_ZC_CONTADOR_TIEMPO;
        TiempoProduccionActual : _.UDT_ZC_CONTADOR_TIEMPO;
        TiempoProduccionTotal : _.UDT_ZC_CONTADOR_TIEMPO;
        TiempoRecirculacion : _.UDT_ZC_CONTADOR_TIEMPO;
        TiempoEnzimatica : _.UDT_ZC_CONTADOR_TIEMPO;
        TiempoLimpieza : _.UDT_ZC_CONTADOR_TIEMPO;
        TiempoPausa : _.UDT_ZC_CONTADOR_TIEMPO;
    END_VAR
    VAR
        { S7_MLC := "MLC_4GX" }
        Pulsador : _.UDT_ZC_PULSADOR;
        { S7_MLC := "MLC_48G" }
        PasswordHMI : UInt;
        {
            S7_Access := "ReadOnly := External";
            S7_MLC := "MLC_3F5";
            S7_Visibility := "Hidden := External"
        }
        s_OldAvisoHoras : Bool;
        { S7_MLC := "MLC_4Ai" }
        s_OldInicioProduccion : Bool;
        s_OldInicioCIP : Bool;
        s_OldInicioPausa : Bool;
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_OldCondicionParo : Bool;
        {
            S7_Access := "ReadOnly := External";
            S7_MLC := "MLC_XJ";
            S7_Visibility := "Hidden := External"
        }
        s_PasswordCalculado : UInt;
    END_VAR
    VAR_TEMP
        { S7_MLC := "MLC_34s" }
        t_OrdenReset : Bool;
        t_CondicionParo : Bool;
        t_ResetProdActual : Bool;
        t_ResetLimpieza : Bool;
        t_ResetPausa : Bool;
    END_VAR

    { S7_Language := "SCL" }
    NETWORK
        REGION DESCRIPCION
        //=======================================================================
        // (C)Copyright ZeusControl 2024 - 2026
        //=======================================================================
        (*
        ### Información del Sistema
        | Hardware Compatible | Entorno de Ingeniería |
        |---------------------|-----------------------|
        | PLC serie 1200/1500 | TIA Portal 18         |
        
        ---
        ### Descripción Funcional
        El bloque `FB15055_ZC_HORAS_MAQUINA` implementa la gestión integral de las horas de funcionamiento de la máquina, llevando el conteo de tiempo acumulado de operación, tiempos de producción (actual y total), mantenimiento, recirculación, limpieza, pausa y tiempo de planta parada con enzimático. Incluye además la gestión del pulsador de reset de mantenimiento protegido por contraseña HMI y la gestión de los avisos por horas alcanzadas.
        
        Funcionalidades principales:
        - Conteo de horas de funcionamiento de la máquina (`TiempoMaquina`) mediante el bloque `FC15025_ZC_CONTADOR_TIEMPO` con estructura `UDT_ZC_CONTADOR_TIEMPO`.
        - Conteo diferenciado de tiempo de producción actual (`TiempoProduccionActual`), producción total (`TiempoProduccionTotal`), tiempo de mantenimiento (`TiempoMantenimiento`), tiempo de recirculación (`TiempoRecirculacion`), tiempo de enzimática (`TiempoEnzimatica`), tiempo de limpieza (`TiempoLimpieza`) y tiempo de pausa (`TiempoPausa`), todos basados en `UDT_ZC_CONTADOR_TIEMPO`.
        - Gestión del pulsador de reset de mantenimiento (`Pulsador` tipo `UDT_ZC_PULSADOR`) con cálculo y verificación de contraseña HMI (`PasswordHMI` / `PasswordCalculado`).
        - Gestión de los flancos de inicio de producción, inicio de CIP e inicio de pausa mediante variables estáticas `s_P_Trig_*` para detección de pulsos de activación.
        - Activación de la alarma y el paro de mantenimiento (`OutputParoMantenimiento`) por horas acumuladas, con flag de aviso (`s_Trig_AvisoHoras`).
        - Señales de visibilidad HMI para los distintos tiempos (`VisTiempoRecirculacion`, etc.) y para el paro de mantenimiento.
        - Orden interna de reset de tiempos (`t_OrdenReset`) que se activa tras la pulsación autorizada del reset de mantenimiento, reinicializando los contadores pertinentes.
        
        > **Restricciones:** Ninguna.
        
        ---
        ### Dependencias Requeridas
        | Tipo | Elementos |
        |------|-----------|
        | FC   | `FC15025_ZC_CONTADOR_TIEMPO` |
        | FB   | - |
        | DB   | - |
        | UDT  | `UDT_ZC_CONTADOR_TIEMPO`, `UDT_ZC_PULSADOR` |
            
        ---
        ### Historial de Cambios
        | Versión  | Fecha      | Técnico | Cambios |
        |----------|------------|---------|---------|
        | 01.00.00 | 28.07.2023 | (HCR/ABH) | Primera versión. Cambio en lógica funcionamiento del bloque. Además de la gestión de alarma mantenimiento, se añade gestión de horas de funcionamiento totales de la máquina. Se añade tiempo de planta parada con enzimático de la máquina. |
        | 01.00.01 | 04.03.2024 | (ABH)   | Se corrige gestión de tiempo total de producción. |
        | 01.00.02 | 23.05.2024 | (HCR)   | Se añade salida visibilidad para tiempo de recirculación. |
        | 01.00.03 | 29.10.2025 | (ABH)   | Se corrige gestión de reset tiempo enzimática. |
        | 01.00.04 | 03.12.2025 | (ABH)   | Se añade tiempo de limpieza y tiempo de pausa. |
        | 01.01.00 | 03.07.2026 | (ABH)   | Cambio a SCL. |
        *)
        END_REGION DESCRIPCION
        
        
        //  ==========================================================================================================
        REGION PULSADORES
            
            //  Pulsador comprobacion contraseña
            "FC15026_ZC_PULSADOR"(Pulso1Seg:=#Pulso1Seg,
                                  SP_Tiempo:=2,
                                  TrazaCategoria:="TRZ_CAT_4_PRO_PUL",
                                  TrazaIdProceso:=#ProcesoID,
                                  TrazaIdPulsador:="TRZ_SYS_PUL_HOR_MAQ_RST",
                                  Usuario:=#Usuario,
                                  FechaHoraActual:=#FechaHora,
                                  Pulsador:=#Pulsador);
            
        END_REGION PULSADORES
        
        
        //  ==========================================================================================================
        REGION PARO_MANTENIMIENTO
            
            //  Condicion de paro por mantenimiento
            #t_CondicionParo :=
            #HabilitarMant AND
            (#TiempoMantenimiento.Hora = #SP_HorasAlarma) AND
            (#FechaHora.MINUTE = #SP_MinutosAlarma);
            
            //  Con paro por mantenimiento, activamos la marca de paro
            IF #t_CondicionParo AND NOT #s_OldCondicionParo THEN
                #s_PasswordCalculado := 0;
                #ParoMantenimiento := TRUE;
            END_IF;
            
            //  Estado anterior condicion paro por mantenimiento
            #s_OldCondicionParo := #t_CondicionParo;
            
            
            //  Ligica de paro y calculo de contraseña
            IF #ParoMantenimiento THEN
                
                //  Calculo de contraseña
                #s_PasswordCalculado := #FechaHora.YEAR + #FechaHora.MONTH + #FechaHora.DAY;
                #Pulsador.Permiso := TRUE;
                #Pulsador.Visibilidad := TRUE;
        
                //  Comprobacion de contraseñas desde HMI
                IF #Pulsador.Plc THEN
                    
                    //  Contraseña correcta, reseteamos todo
                    IF #s_PasswordCalculado = #PasswordHMI THEN
                        #s_PasswordCalculado := 0;
                        #PasswordHMI := 0;
                        #ParoMantenimiento := FALSE;
                        #t_OrdenReset := TRUE;
                        
                    ELSE
                        //  Contraseña incorrecta
                        #PasswordHMI := 0;
                        #t_OrdenReset := FALSE;
                    END_IF;
                    
                ELSE
                    #t_OrdenReset := FALSE;
                END_IF;
        
            ELSE
                //  Reset de estados si no tenemos la señal de paro por mantenimiento
                #Pulsador.Permiso := FALSE;
                #Pulsador.Visibilidad := FALSE;
                #t_OrdenReset := FALSE;
                
            END_IF;
            
            //  Si no esta habilitado el paro por mantenimiento, reseteamos
            IF NOT #HabilitarMant THEN
                #ParoMantenimiento := FALSE;
            END_IF;
            
        END_REGION PARO_MANTENIMIENTO
        
        
        //  ==========================================================================================================
        REGION CONTADORES
            
            // Resolución de flancos en memoria temporal para Clean Code
            #t_ResetProdActual := #IniciarTiempoProd AND NOT #s_OldInicioProduccion;
            #s_OldInicioProduccion := #IniciarTiempoProd;
            
            #t_ResetLimpieza := #IniciarTiempoCIP AND NOT #s_OldInicioCIP;
            #s_OldInicioCIP := #IniciarTiempoCIP;
            
            #t_ResetPausa := #IniciarTiempoPausa AND NOT #s_OldInicioPausa;
            #s_OldInicioPausa := #IniciarTiempoPausa;
            
            
            //  ==========================================================================================================
            //  Contador de tiempo de mantenimiento
            "FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg:=#Pulso1Seg,
                                         Iniciar:=#HabilitarMant AND #IniciarTiempoMaquina,
                                         Reset:=#t_OrdenReset OR NOT #HabilitarMant,
                                         Contador:=#TiempoMantenimiento);
            
            //  ==========================================================================================================
            //  Contador de tiempo total Maquina
            "FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
                                         Iniciar := #IniciarTiempoMaquina,
                                         Reset := FALSE,
                                         Contador := #TiempoMaquina);
        
            //  ==========================================================================================================
            //  Contador de tiempo de produccion actual
            "FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
                                         Iniciar := #IniciarTiempoProd,
                                         Reset := #t_ResetProdActual,
                                         Contador := #TiempoProduccionActual);
            
            //  ==========================================================================================================
            //  Contador de tiempo de produccion total
            "FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
                                         Iniciar := #IniciarTiempoProd,
                                         Reset := FALSE,
                                         Contador := #TiempoProduccionTotal);
            
            //  ==========================================================================================================
            //  Contador de tiempo de recirculacion
            "FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
                                         Iniciar := #IniciarTiempoRecirc,
                                         Reset := NOT #IniciarTiempoRecirc,
                                         Contador := #TiempoRecirculacion);
            //  Visibilidad tiempo recirculacion
            #VisTiempoRecirculacion := #IniciarTiempoRecirc;
            
            //  ==========================================================================================================
            //  Contador de tiempo de planta con enzimatico
            "FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
                                         Iniciar := #IniciarTiempoEnzim,
                                         Reset := #ResetTiempoEnzim,
                                         Contador := #TiempoEnzimatica);
            
            //  ==========================================================================================================
            //  Contador de tiempo de limpieza
            "FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
                                         Iniciar := #IniciarTiempoCIP,
                                         Reset := #t_ResetLimpieza,
                                         Contador := #TiempoLimpieza);
            
            //  ==========================================================================================================
            //  Contador de tiempo en pausa
            "FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
                                         Iniciar := #IniciarTiempoPausa,
                                         Reset := #t_ResetPausa,
                                         Contador := #TiempoPausa);
            
        END_REGION CONTADORES
        
        
    END_NETWORK
END_FUNCTION_BLOCK
