FUNCTION_BLOCK "FB15051_ZC_INF_CPR"
TITLE = FB15051_ZC_INF_CPR
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : ABH
FAMILY : ZeusControl
VERSION : 1.0
   VAR_INPUT 
      GuardarDatos : Bool;   // Orden guardar datos
      FinGuardarDatos : Bool;   // Orden finalizar guardar datos
      FechaActual {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;   // Fecha y hora actual
      TipoProceso : Int;   // Tipo de proceso
      Destino : Int;   // Destino
      Producto : Int;   // Producto
      Producto1Destino : Int;   // Producto 1 en destino
      Producto2Destino : Int;   // Producto 2 en destino
      Nombre : String[40];   // Nombre
      Matricula : String[10];   // Matricula
      LetraQ : String[10];   // Letra Q
      KilosSP : Real;   // Kilos SP
      KilosDescargados : Real;   // Cantidad
      DensidadMedia : LReal;   // Densidad Media
      TempMediaDescarga : LReal;   // Temperatura media en descarga
      TempMediaEnfriamiento : LReal;   // Temperatura media enfriamiento
      EmpujeRealizado : Bool;   // Empuje realizado
      AclaradoRealizado : Bool;   // Aclarado realizado
   END_VAR

   VAR_OUTPUT 
      GuardarSQL : Bool;
   END_VAR

   VAR_IN_OUT 
      Mux : "UDT_ZC_MUX";   // Variable Mux
      Informe : Array[*] of "UDT_ZC_INF_CPR_PROD";   // Informes de compacto 
   END_VAR

   VAR RETAIN
      s_OrdenGuardarDatos : Bool;   // Orden adquirir datos de informes
      s_OrdenGuardarFechaInicio : Bool;   // Orden guardar fecha de inicio y dezplazar informes
   END_VAR
   VAR 
      s_OrdenGuardarFechaFin : Bool;   // Orden guardar fecha de fin
      s_OrdenBorrarInforme : Bool;   // Orden borrar informe
      s_NumeroBorrado : Int;   // -1= Todos / Valor= Numero de registro
   END_VAR
   VAR RETAIN
      s_P_Trig_TomarFechaInicio : Bool;   // Pulso
      s_P_Trig_TomarFechaFin : Bool;   // Pulso
   END_VAR

   VAR_TEMP 
      for_i : Int;   // Variable para bucles FOR
      t_dummyInt : Int;
      t_IndiceSuperior : Int;   // Indice superior del array
      t_IndiceInferior : Int;   // Indice inferior del array
      t_InformeVacio : "UDT_ZC_INF_CPR_PROD";
   END_VAR

   VAR CONSTANT 
      ACTUAL : Int := 1;
      TIPO_DESCARGA_PARCIAL : Int := 1;   // TIPO DE PROCESO DESCARGA PARCIAL
      TIPO_DESCARGA_TOTAL : Int := 2;   // TIPO DE PROCESO DESCARGA TOTAL
   END_VAR


BEGIN
	REGION DESCRIPCION
	(*
	###### (C)Copyright ZeusControl 2023 - 2026
	
	---
	### Información del Sistema
	| Hardware Compatible | Entorno de Ingeniería |
	|---------------------|-----------------------|
	| PLC serie 1200/1500 | TIA Portal 18         |
	
	---
	> **Restricciones:** Ninguna.
	
	---
	### Descripción Funcional
	
	Bloque de funcion para la gestión de informes de descargas de compacto de recepcion.
	
	En ella se realizan las siguientes acciones:
	
	- Cálculo dinámico de indices de array de informes.
	- Gestion de ordenes de inicio y fin informe.
	- Desplazamiento y captura de datos de informe.
	- Borrado de informes.
	
	---
	### Dependencias Requeridas
	| Tipo | Elementos |
	|------|-----------|
	| FC   | `FC15005_ZC_DTL_TO_ZC_FECHA` |
	| FB   | - |
	| DB   | - |
	| UDT  | `UDT_ZC_MUX`, `UDT_ZC_INF_CPR_PROD` |
	
	---
	### Historial de Cambios
	| Versión  | Fecha      | Técnico | Cambios |
	|----------|------------|---------|---------|
	| 00.00.01 | 01.08.2023 | (HCR)   | Primera version. |
	| 00.00.02 | 16.04.2024 | (ABH)   | Se cambian los nombre a variables para estandarizar. |
	| 01.00.02 | 13.07.2026 | (ABH)   | Cambio a SCL. |
	*)
	END_REGION DESCRIPCION
	
	
	//  ==========================================================================================================
	REGION LIMITES_Y_MULTIPLEXADO
	    
	    //  Calculo limites array de informes
	    #t_IndiceInferior := DINT_TO_INT(LOWER_BOUND(ARR := #Informe, DIM := 1));
	    #t_IndiceSuperior := DINT_TO_INT(UPPER_BOUND(ARR := #Informe, DIM := 1));
	    
	    //  Si no hay informes configurados, salimos inmediatamente.
	    IF #t_IndiceInferior <= 0 THEN
	        #Mux.Index := 0;
	        RETURN;
	    END_IF;
	    
	    //  Limites multiplexado
	    IF #Mux.Index < 1 THEN
	        #Mux.Index := 0;
	    END_IF;
	    IF #Mux.Index > #t_IndiceSuperior THEN
	        #Mux.Index := #t_IndiceSuperior;
	    END_IF;
	    
	END_REGION LIMITES_Y_MULTIPLEXADO
	
	
	//  ==========================================================================================================
	REGION ORDEN_INICIO_FIN
	    
	    //  Orden de inicio
	    IF #GuardarDatos AND NOT #s_P_Trig_TomarFechaInicio THEN
	        #s_OrdenGuardarFechaInicio := TRUE;
	        #s_OrdenGuardarDatos := TRUE;
	    END_IF;
	    
	    //  Orden de fin
	    #GuardarSQL := FALSE;
	    IF #FinGuardarDatos AND NOT #s_P_Trig_TomarFechaFin THEN
	        #s_OrdenGuardarFechaFin := TRUE;
	        #GuardarSQL := TRUE;
	    END_IF;
	    
	    //  Estados anteriores
	    #s_P_Trig_TomarFechaInicio := #GuardarDatos;
	    #s_P_Trig_TomarFechaFin := #FinGuardarDatos;
	    
	END_REGION ORDEN_INICIO_FIN
	
	
	//  ==========================================================================================================
	REGION ADQUISICION_DE_DATOS
	    
	    //  Con flanco de guardar datos fecha de inicio, desplazamos los registros y almacenamos la fecha de inicio
	    IF #s_OrdenGuardarFechaInicio THEN
	        
	        //  Desplazamiento de datos
	        #t_dummyInt := MOVE_BLK_VARIANT(SRC := #Informe, COUNT := INT_TO_UDINT(#t_IndiceSuperior - 1), SRC_INDEX := 0, DEST_INDEX := 1, DEST => #Informe);
	        
	        //  Tomar valor de fecha de inicio
	        #Informe[#ACTUAL].FechaInicio := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaActual);
	        #s_OrdenGuardarFechaInicio := FALSE;
	    END_IF;
	    
	    //  Tomar datos 
	    IF #s_OrdenGuardarDatos THEN
	        #Informe[#ACTUAL].Descarga.TipoProceso := #TipoProceso;
	        #Informe[#ACTUAL].Descarga.Destino := #Destino;
	        IF #TipoProceso = #TIPO_DESCARGA_PARCIAL OR #TipoProceso = #TIPO_DESCARGA_TOTAL THEN
	            #Informe[#ACTUAL].Descarga.Producto := #Producto;
	            #Informe[#ACTUAL].Descarga.Producto1Destino := #Producto1Destino;
	            #Informe[#ACTUAL].Descarga.Producto2Destino := #Producto2Destino;
	            #Informe[#ACTUAL].Descarga.KilosSP := #KilosSP;
	            #Informe[#ACTUAL].Descarga.KilosDescargados := #KilosDescargados;
	            #Informe[#ACTUAL].Descarga.DensidadMedia := #DensidadMedia;
	            #Informe[#ACTUAL].Descarga.TemperaturaMediaDescarga := #TempMediaDescarga;
	            #Informe[#ACTUAL].Descarga.TemperaturaMediaEnfriamiento := #TempMediaEnfriamiento;
	            #Informe[#ACTUAL].Descarga.Nombre := #Nombre;
	            #Informe[#ACTUAL].Descarga.Matricula := #Matricula;
	            #Informe[#ACTUAL].Descarga.LetraQ := #LetraQ;
	        END_IF;
	        #Informe[#ACTUAL].Descarga.EmpujeRealizado := #EmpujeRealizado;
	        #Informe[#ACTUAL].Descarga.AclaradoRealizado := #AclaradoRealizado;
	    END_IF;
	    
	    //  Con flanco de guardar datos fecha de fin almacenamos la fecha de fin y resetemos guardar datos
	    IF #s_OrdenGuardarFechaFin THEN
	        #Informe[#ACTUAL].FechaFin := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaActual);
	        #s_OrdenGuardarDatos := FALSE;
	        #s_OrdenGuardarFechaFin := FALSE;
	    END_IF;
	    
	END_REGION ADQUISICION_DE_DATOS
	
	
	//  ==========================================================================================================
	REGION BORRADO_INFORMES
	    
	    //  Borrado de todos los registros
	    IF #s_OrdenBorrarInforme THEN
	        IF #s_NumeroBorrado = -1 OR #s_NumeroBorrado = 0 THEN
	            
	            //  Borrado total
	            FOR #for_i := 1 TO #t_IndiceSuperior DO
	                #Informe[#for_i] := #t_InformeVacio;
	            END_FOR;
	            
	        ELSIF #s_NumeroBorrado >= 1 AND #s_NumeroBorrado < #t_IndiceSuperior THEN
	            
	            //  Borrado registro especifico
	            #Informe[#s_NumeroBorrado] := #t_InformeVacio;
	            
	            //  Desplazamiento de datos
	            #t_dummyInt := MOVE_BLK_VARIANT(SRC := #Informe,
	                                            COUNT := INT_TO_UDINT(#t_IndiceSuperior - #s_NumeroBorrado),
	                                            SRC_INDEX := #s_NumeroBorrado,
	                                            DEST_INDEX := #s_NumeroBorrado - 1,
	                                            DEST => #Informe);
	            
	            //  Borrado del ultimo registro
	            #Informe[#t_IndiceSuperior] := #t_InformeVacio;
	            
	        ELSIF #s_NumeroBorrado = #t_IndiceSuperior THEN
	            
	            //  Borrado de ultimo registro
	            #Informe[#s_NumeroBorrado] := #t_InformeVacio;
	            
	        END_IF;
	        
	        #s_OrdenBorrarInforme := FALSE;
	        
	    END_IF;
	    
	    
	END_REGION BORRADO_INFORMES
	
END_FUNCTION_BLOCK

