FUNCTION "FC2038_ZC_MEDIA_VOL" : Void
TITLE = FC2038_ZC_MEDIA_VOL
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : ABH
FAMILY : ZeusControl
VERSION : 1.0
//Funcion para gestion de media teniendo en cuenta el volumen/caudal.
   VAR_INPUT 
      Pulso1seg : Bool;   // Pulso de 1 segundo
   END_VAR

   VAR_TEMP 
      for_i : Int;
      t_N_MAX : Int;
      t_NumeroDatos : LReal;
   END_VAR


BEGIN
	REGION DESCRIPCION
	(*
	###### (C)Copyright ZeusControl 2024 - 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 volumen.
	
	Las tareas que realiza son las siguientes:
	
	- Gestionar la activacion y calculo de la media teniendo en cuenta el volumen/caudal.
	
	---
	### Dependencias Requeridas
	| Tipo | Elementos |
	|------|-----------|
	| FC   | - |
	| FB   | - |
	| DB   | - |
	| UDT  | `UDT_ZC_DISP_MEDIA_VOLUMEN` |
	    
	---
	### Historial de Cambios
	| Versión  | Fecha      | Técnico | Cambios |
	|----------|------------|---------|---------|
	| 00.00.01 | 01.02.2024 | (ABH)   | Primera version. |
	| 00.00.02 | 16.02.2024 | (ABH)   | Cambio de tipo de dato auxVolumen de REAL a LREAL. |
	| 01.00.00 | 06.07.2026 | (ABH)   | Cambio a SCL. |
	*)
	END_REGION DESCRIPCION
	
	
	REGION COMPROBACION_N_MAX
	    
	    //  Si no hay dispositivo declarados, salimos del bloque inmediatamente
	    IF "N_MAX_DISP_MEDIA_VOLUMEN" <= 0 THEN
	        RETURN;
	    END_IF;
	    
	    //  Traspaso de N_MAX a variable temporal para evitar fallos de compilacion
	    #t_N_MAX := "N_MAX_DISP_MEDIA_VOLUMEN";
	    
	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 "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].IniciarMedia THEN
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxTiempo := 0;
	            END_IF;
	            
	            //  Reinicializacion de datos al inicializar
	            IF "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].Inicializar AND NOT "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxInicializar THEN
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxAcumulado :=
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxVolumen :=
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxValorMedia :=
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].Media := 0.0;
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxTiempo := 0;
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorMinimo := 9999999.0;
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorMaximo := -9999999.0;
	            END_IF;
	            
	            //  Estado anterior
	            "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxInicializar := "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].Inicializar;
	            
	        END_REGION REINICIALIZACION_DE_DATOS
	        
	        
	        //  ==========================================================================================================
	        REGION TOMA_DE_VALORES
	            
	            IF "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].IniciarMedia AND #Pulso1seg THEN
	                
	                //  Incrementamos el indice de tiempo
	                "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxTiempo += 1;
	                
	                //  En caso de superar el tiempo de muestreo, incrementamos el acumulado, reseteamos el tiempo y aumentamos el indice
	                IF "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxTiempo >= "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].TiempoMuestreo THEN
	                    
	                    "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxValorMedia := ("DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].Volumen - "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxVolumen) * "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorActual;
	                    "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxVolumen := "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].Volumen;
	                    "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxAcumulado := "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxValorMedia + "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxAcumulado;
	                    
	                    "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].Media := "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxAcumulado / "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].Volumen;
	                    
	                    "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].auxTiempo := 0;
	                    
	                END_IF;
	                
	                //  Guardamos el valor minimo alcanzado
	                IF "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorActual < "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorMinimo THEN
	                    "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorMinimo := "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorActual;
	                END_IF;
	                
	                //  Guardamos el valor maximo alcanzado
	                IF "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorActual > "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorMaximo THEN
	                    "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorMaximo := "DB2038_MEDIA_VOL".MEDIA_VOL[#for_i].ValorActual;
	                END_IF;
	                
	            END_IF;
	            
	        END_REGION TOMA_DE_VALORES
	        
	    END_FOR;
	
	    
	END_REGION GESTION_DISPOSITIVO
	
	
END_FUNCTION

