{
    S7_Author := "ABH";
    S7_BlockComment := "MLC_3jM";
    S7_BlockNumber := "15057";
    S7_BlockTitle := "MLC_4he";
    S7_EditorMode := "SCL";
    S7_Family := "ZeusControl";
    S7_IECCheck := "TRUE";
    S7_Optimized := "TRUE";
    S7_Version := "1.0"
}
FUNCTION_BLOCK "FB15057_ZC_CONT_PROD_MEM"
    VAR_INPUT
        { S7_MLC := "MLC_TT" }
        InicioProduccion : Bool;
        { S7_MLC := "MLC_aF" }
        EnProduccion : Bool;
        { S7_MLC := "MLC_5Am" }
        FinProduccion : Bool;
        {
            S7_Access := "ReadOnly := External";
            S7_MLC := "MLC_3Ze";
            S7_Visibility := "Hidden := External"
        }
        FechaHoraActual : DTL;
        { S7_MLC := "MLC_aB" }
        LitrosEntrada : LReal;
        { S7_MLC := "MLC_fh" }
        LitrosConcentrado : LReal;
        { S7_MLC := "MLC_4EB" }
        LitrosPermeado : LReal;
        { S7_MLC := "MLC_4vY" }
        FCV : Real;
        { S7_MLC := "MLC_Zt" }
        Brix : LReal;
        { S7_MLC := "MLC_4ud" }
        TempAlimentacion : LReal;
        { S7_MLC := "MLC_4Yn" }
        TempConcentrado : LReal;
        { S7_MLC := "MLC_sm" }
        TempPermeado : LReal;
        { S7_MLC := "MLC_3ZN" }
        BorrarParcial : Bool;
    END_VAR
    VAR RETAIN
        { S7_Setpoint := "False" }
        Ultima : _.UDT_ZC_CONT_PROD_MEM;
        { S7_Setpoint := "False" }
        Penultima : _.UDT_ZC_CONT_PROD_MEM;
        { S7_Setpoint := "False" }
        Parcial : _.UDT_ZC_CONT_PROD_MEM;
        { S7_Setpoint := "False" }
        Total : _.UDT_ZC_CONT_PROD_MEM;
    END_VAR
    VAR
        { S7_Setpoint := "True" }
        s_OldInicioProd : Bool;
        { S7_Setpoint := "True" }
        s_OldFinProd : Bool;
        { S7_MLC := "MLC_54k" }
        s_InicioProduccion : Bool;
        { S7_MLC := "MLC_PF" }
        s_FinProduccion : 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
        Bloque de funcion que implementa la gestión de los contadores y totalizadores de producción de una máquina de membranas, manteniendo la trazabilidad histórica de la última y penúltima producción, así como los acumulados parciales y totales, junto con el cálculo del factor de conversión volumétrica (FCV) asociado a cada periodo.
        
        Funcionalidades principales:
        - Detección de flanco ascendente en las órdenes `#InicioProduccion` y `#FinProduccion` mediante las variables estáticas `#s_P_Trig_InicioProd` y `#s_P_Trig_FinProd`, generando los pulsos internos `#s_InicioProduccion` y `#s_FinProduccion` para evitar disparos múltiples por nivel mantenido.
        - Inicio de producción: al recibir `#s_InicioProduccion` se trasladan los datos de la última producción a la estructura `#Penultima`, se inicializan a cero los campos analíticos y de fecha de `#Ultima`, y se registra la fecha/hora de inicio en `#Ultima.FechaInicio` mediante la conversión realizada por `FC15005_ZC_DTL_TO_ZC_FECHA`.
        - Datos en curso: mientras `#EnProduccion` está activo, se copian en `#Ultima` las variables de proceso (`LitrosEntrada`, `LitrosConcentrado`, `Brix`, `TempAlimentacion`, `TempConcentrado`, `TempPermeado`), manteniendo actualizada la instantánea de la producción en marcha.
        - Fin de producción: al detectar `#s_FinProduccion` se registra la fecha/hora de fin en `#Ultima.FechaFin` y se acumulan los valores de la producción actual sobre los contadores `#Parcial` y `#Total`, tanto de litros de entrada como de concentrado.
        - Cálculo de litros de permeado por diferencia (`LitrosEntrada - LitrosConcentrado`) para las cuatro estructuras: `#Ultima`, `#Penultima`, `#Parcial` y `#Total`.
        - Cálculo del factor de conversión volumétrica (FCV) para cada estructura con protección frente a división por cero (cuando `#LitrosEntrada` o `#LitrosConcentrado` son menores o iguales a `0.0`, el resultado se fija en `0.0`).
        - Reset de la producción parcial: la entrada `#BorrarParcial` reinicia los litros del contador parcial y actualiza `#Parcial.FechaInicio` con la fecha/hora actual.
        
        > **Restricciones:** Ninguna.
        
        ---
        ### Dependencias Requeridas
        | Tipo | Elementos |
        |------|-----------|
        | FC   | `FC15005_ZC_DTL_TO_ZC_FECHA` |
        | FB   | - |
        | DB   | - |
        | UDT  | `UDT_ZC_CONTADORES_PRODUCCION` |
            
        ---
        ### Historial de Cambios
        | Versión  | Fecha      | Técnico | Cambios |
        |----------|------------|---------|---------|
        | 01.00.00 | 29.09.2023 | (ABH)   | Primera versión. |
        | 01.00.01 | 04.03.2024 | (ABH)   | Se corrige gestión de marca fin de producción. |
        | 01.00.02 | 03.07.2026 | (ABH)   | Cambio a SCL. |
        *)
        END_REGION DESCRIPCION
        
        
        //  ==========================================================================================================
        REGION GESTION_ORDENES
            
            //  Inicio de produccion
            #s_InicioProduccion := #InicioProduccion AND NOT #s_OldInicioProd;
            
            //  Fin de produccion
            #s_FinProduccion := #FinProduccion AND NOT #s_OldFinProd;
            
            //  Estados anteriores
            #s_OldInicioProd := #InicioProduccion;
            #s_OldFinProd := #FinProduccion;
            
        END_REGION GESTION_ORDENES
        
        
        //  ==========================================================================================================
        REGION MOVIMIENTO_DE_DATOS
            
            //  ==========================================================================================================
            REGION INICIO_PRODUCCION
                
                IF #s_InicioProduccion THEN
                    
                    //  =================================================================================================
                    //  Traspaso de datos de ultima produccion a penultima produccion
                    #Penultima.LitrosEntrada := #Ultima.LitrosEntrada;
                    #Penultima.LitrosConcentrado := #Ultima.LitrosConcentrado;
                    #Penultima.Brix := #Ultima.Brix;
                    #Penultima.TempAlimentacion := #Ultima.TempAlimentacion;
                    #Penultima.TempConcentrado := #Ultima.TempConcentrado;
                    #Penultima.FechaInicio := #Ultima.FechaInicio;
                    #Penultima.FechaFin := #Ultima.FechaFin;
                    
                    
                    //  =================================================================================================
                    //  Reset datos ultima produccion
                    #Ultima.LitrosEntrada := 0.0;
                    #Ultima.LitrosConcentrado := 0.0;
                    #Ultima.Brix := 0.0;
                    #Ultima.TempAlimentacion := 0.0;
                    #Ultima.TempConcentrado := 0.0;
                    #Ultima.FechaInicio.Ano := 0;
                    #Ultima.FechaInicio.Mes := 0;
                    #Ultima.FechaInicio.Dia := 0;
                    #Ultima.FechaInicio.Hora := 0;
                    #Ultima.FechaInicio.Minuto := 0;
                    #Ultima.FechaInicio.Segundo := 0;
                    #Ultima.FechaFin.Ano := 0;
                    #Ultima.FechaFin.Mes := 0;
                    #Ultima.FechaFin.Dia := 0;
                    #Ultima.FechaFin.Hora := 0;
                    #Ultima.FechaFin.Minuto := 0;
                    #Ultima.FechaFin.Segundo := 0;
                    
                    
                    //  =================================================================================================
                    //  Guardamos la fecha y hora de inicio de la produccion
                    #Ultima.FechaInicio := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaHoraActual);
                    
                END_IF;
                
            END_REGION INICIO_PRODUCCION
            
            
            //  ==========================================================================================================
            REGION DATOS_DURANTE_PRODUCCION
                
                //  Movimientos de datos durante la produccion
                IF #EnProduccion THEN
                    
                    #Ultima.LitrosEntrada := #LitrosEntrada;
                    #Ultima.LitrosConcentrado := #LitrosConcentrado;
                    #Ultima.Brix := #Brix;
                    #Ultima.TempAlimentacion := #TempAlimentacion;
                    #Ultima.TempConcentrado := #TempConcentrado;
                    #Ultima.TempPermeado := #TempPermeado;
                END_IF;
                
            END_REGION DATOS_DURANTE_PRODUCCION
            
            
            //  ==========================================================================================================
            REGION DATOS_AL_FIN_PRODUCCION
                
                //  Movimiento de datos al finalizar la produccion
                IF #s_FinProduccion THEN
                    
                    //  Fecha fin
                    #Ultima.FechaFin := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaHoraActual);
                    
                    //  Suma de datos parciales y totales
                    #Parcial.LitrosEntrada := #Ultima.LitrosEntrada + #Parcial.LitrosEntrada;
                    #Parcial.LitrosConcentrado := #Ultima.LitrosConcentrado + #Parcial.LitrosConcentrado;
                    #Total.LitrosEntrada := #Ultima.LitrosEntrada + #Total.LitrosEntrada;
                    #Total.LitrosConcentrado := #Ultima.LitrosConcentrado + #Total.LitrosConcentrado;
                    
                END_IF;
                
            END_REGION DATOS_AL_FIN_PRODUCCION
            
            
            
        END_REGION MOVIMIENTO_DE_DATOS
        
        
        //  ==========================================================================================================
        REGION CALCULOS
            
            
            //  ==========================================================================================================
            REGION TOTALIZADORES                
                
                //  Ultima produccion
                #Ultima.LitrosPermeado := #Ultima.LitrosEntrada - #Ultima.LitrosConcentrado;
                
                //  Penultima produccion
                #Penultima.LitrosPermeado := #Penultima.LitrosEntrada - #Penultima.LitrosConcentrado;
                
                //  Produccion parcial
                #Parcial.LitrosPermeado := #Parcial.LitrosEntrada - #Parcial.LitrosConcentrado;
                
                //  Produccion total
                #Total.LitrosPermeado := #Total.LitrosEntrada - #Total.LitrosConcentrado;
                
            END_REGION TOTALIZADORES
            
            
            //  ==========================================================================================================
            REGION FCV
                
                //  FCV Ultima produccion
                IF #Ultima.LitrosEntrada > 0.0 AND #Ultima.LitrosConcentrado > 0.0 THEN
                    #Ultima.FCV := LREAL_TO_REAL(#Ultima.LitrosEntrada / #Ultima.LitrosConcentrado);
                ELSE
                    #Ultima.FCV := 0.0;
                END_IF;
                
                //  FCV Penultima produccion
                IF #Penultima.LitrosEntrada > 0.0 AND #Penultima.LitrosConcentrado > 0.0 THEN
                    #Penultima.FCV := LREAL_TO_REAL(#Penultima.LitrosEntrada / #Penultima.LitrosConcentrado);
                ELSE
                    #Penultima.FCV := 0.0;
                END_IF;
                
                //  FCV Produccion parcial
                IF #Parcial.LitrosEntrada > 0.0 AND #Parcial.LitrosConcentrado > 0.0 THEN
                    #Parcial.FCV := LREAL_TO_REAL(#Parcial.LitrosEntrada / #Parcial.LitrosConcentrado);
                ELSE
                    #Parcial.FCV := 0.0;
                END_IF;
                
                //  FCV Produccion Total
                IF #Total.LitrosEntrada > 0.0 AND #Total.LitrosConcentrado > 0.0 THEN
                    #Total.FCV := LREAL_TO_REAL(#Total.LitrosEntrada / #Total.LitrosConcentrado);
                ELSE
                    #Total.FCV := 0.0;
                END_IF;
                
            END_REGION FCV
            
        END_REGION CALCULOS
        
        
        //  ==========================================================================================================
        REGION RESET_DATOS
            
            //  Reset produccion parcial
            IF #BorrarParcial THEN
                #Parcial.LitrosEntrada := 0.0;
                #Parcial.LitrosConcentrado := 0.0;
                #Parcial.FechaInicio := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaHoraActual);
            END_IF;
            
        END_REGION RESET_DATOS
        
    END_NETWORK
END_FUNCTION_BLOCK
