{
    S7_Author := "ABH";
    S7_BlockComment := "MLC_qi";
    S7_BlockNumber := "2037";
    S7_BlockTitle := "MLC_3wJ";
    S7_EditorMode := "SCL";
    S7_Family := "ZeusControl";
    S7_Optimized := "TRUE";
    S7_Version := "1.0"
}
FUNCTION "FC2037_ZC_MEDIA" : Void
    VAR_INPUT
        { S7_MLC := "MLC_344" }
        Pulso1seg : Bool;
    END_VAR
    VAR_TEMP
        for_i : Int;
        t_N_MAX : Int;
        t_NumeroDatos : LReal;
    END_VAR

    { S7_Language := "SCL" }
    NETWORK
        REGION DESCRIPCION
        (*
        ###### (C)Copyright ZeusControl 2022 - 2026
        
        ---
        ### Información del Sistema
        | Hardware Compatible | Entorno de Ingeniería |
        |---------------------|-----------------------|
        | PLC serie 1200/1500 | TIA Portal 18         |
        
        ---
        > **Restricciones:** Ninguna.
        
        ---
        ### Descripción Funcional
        
        Función encargada de gestionar un dispositivo Media.
        
        Las tareas que realiza son las siguientes:
        
        - Gestionar la activacion y calculo de la media.
        
        ---
        ### Dependencias Requeridas
        | Tipo | Elementos |
        |------|-----------|
        | FC   | - |
        | FB   | - |
        | DB   | `DB2037_MEDIA` |
        | UDT  | - |
            
        ---
        ### Historial de Cambios
        | Versión  | Fecha      | Técnico | Cambios |
        |----------|------------|---------|---------|
        | 00.00.01 | 01.02.2022 | (ABH)   | Primera version. |
        | 00.00.02 | 18.09.2023 | (ABH)   | Se añade valor maximo y valor minimo del valor instanteneo de la media cuando esta iniciada la media. |
        | 01.00.00 | 06.07.2026 | (ABH)   | Cambio a SCL. |
        *)
        END_REGION DESCRIPCION
        
        
        REGION COMPROBACION_N_MAX
            
            //  Si no hay dispositivos declarados, salimos del bloque inmediatamente
            IF "N_MAX_DISP_MEDIA" <= 0 THEN
                RETURN;
            END_IF;
            
            //  Traspaso de N_MAX a variable temporal para evitar fallos de compilacion
            #t_N_MAX := "N_MAX_DISP_MEDIA";
            
        END_REGION COMPROBACION_N_MAX
        
        
        //  ==========================================================================================================
        REGION GESTION_DISPOSITIVO
            
            FOR #for_i := 1 TO #t_N_MAX DO
                
                //  ==========================================================================================================
                REGION REINICIALIZACION_DE_DATOS
                    
                    //  Reset temporizador interno si no esta habilitada la media
                    IF NOT "DB2037_MEDIA".MEDIA[#for_i].IniciarMedia THEN
                        "DB2037_MEDIA".MEDIA[#for_i].auxTiempo := 0;
                    END_IF;
                    
                    //  Reinicializacion de datos al inicializar
                    IF "DB2037_MEDIA".MEDIA[#for_i].Inicializar AND NOT "DB2037_MEDIA".MEDIA[#for_i].auxInicializar THEN
                        "DB2037_MEDIA".MEDIA[#for_i].auxAcumulado := 0.0;
                        "DB2037_MEDIA".MEDIA[#for_i].auxIndice := 0;
                        "DB2037_MEDIA".MEDIA[#for_i].auxTiempo := 0;
                        "DB2037_MEDIA".MEDIA[#for_i].ValorMinimo := 9999999.0;
                        "DB2037_MEDIA".MEDIA[#for_i].ValorMaximo := -9999999.0;
                    END_IF;
                    
                    //  Estado anterior
                    "DB2037_MEDIA".MEDIA[#for_i].auxInicializar := "DB2037_MEDIA".MEDIA[#for_i].Inicializar;
                    
                END_REGION REINICIALIZACION_DE_DATOS
                
                
                //  ==========================================================================================================
                REGION TOMA_DE_VALORES
                    
                    IF "DB2037_MEDIA".MEDIA[#for_i].IniciarMedia AND #Pulso1seg THEN
                        
                        //  Incrementamos el indice de tiempo
                        "DB2037_MEDIA".MEDIA[#for_i].auxTiempo += 1;
                        
                        //  En caso de superar el tiempo de muestreo, incrementamos el acumulado, reseteamos el tiempo y aumentamos el indice
                        IF "DB2037_MEDIA".MEDIA[#for_i].auxTiempo >= "DB2037_MEDIA".MEDIA[#for_i].TiempoMuestreo THEN
                            
                            "DB2037_MEDIA".MEDIA[#for_i].auxAcumulado := "DB2037_MEDIA".MEDIA[#for_i].ValorActual + "DB2037_MEDIA".MEDIA[#for_i].auxAcumulado;
                            "DB2037_MEDIA".MEDIA[#for_i].auxIndice += 1;
                            "DB2037_MEDIA".MEDIA[#for_i].auxTiempo := 0;
                            
                        END_IF;
                        
                        //  Guardamos el valor minimo alcanzado
                        IF "DB2037_MEDIA".MEDIA[#for_i].ValorActual < "DB2037_MEDIA".MEDIA[#for_i].ValorMinimo THEN
                            "DB2037_MEDIA".MEDIA[#for_i].ValorMinimo := "DB2037_MEDIA".MEDIA[#for_i].ValorActual;
                        END_IF;
                        
                        //  Guardamos el valor maximo alcanzado
                        IF "DB2037_MEDIA".MEDIA[#for_i].ValorActual > "DB2037_MEDIA".MEDIA[#for_i].ValorMaximo THEN
                            "DB2037_MEDIA".MEDIA[#for_i].ValorMaximo := "DB2037_MEDIA".MEDIA[#for_i].ValorActual;
                        END_IF;
                        
                    END_IF;
                    
                    //  Conversion de indice a REAL para calculos
                    #t_NumeroDatos := DINT_TO_LREAL("DB2037_MEDIA".MEDIA[#for_i].auxIndice);
                    
                END_REGION TOMA_DE_VALORES
                
                
                //  ==========================================================================================================
                REGION CALCULO_MEDIA
                    
                    IF "DB2037_MEDIA".MEDIA[#for_i].auxIndice > 0 THEN
                        "DB2037_MEDIA".MEDIA[#for_i].Media := "DB2037_MEDIA".MEDIA[#for_i].auxAcumulado / #t_NumeroDatos;
                    ELSE
                        "DB2037_MEDIA".MEDIA[#for_i].Media := 0.0;
                    END_IF;
                    
                END_REGION CALCULO_MEDIA
                
            END_FOR;
        
            
        END_REGION GESTION_DISPOSITIVO
        
        
    END_NETWORK
END_FUNCTION
