{
    S7_Author := "ABH";
    S7_BlockComment := "MLC_3m2";
    S7_BlockNumber := "15995";
    S7_BlockTitle := "MLC_4LA";
    S7_EditorMode := "SCL";
    S7_Family := "ZeusControl";
    S7_IECCheck := "TRUE";
    S7_Optimized := "TRUE";
    S7_Version := "1.0"
}
FUNCTION_BLOCK "FB15995_ZC_BUSCAR_DIR"
    VAR
        { S7_MLC := "MLC_3f4" }
        s_Buscar : Bool;
    END_VAR
    VAR RETAIN
        s_EntradaDigital : STRUCT
            Habilitar : Bool;
            Encontrada : Bool;
            NumeroByte : Int;
            NumeroBit : Int;
            Dispositivo : String;
        END_STRUCT;
        s_Salidadigital : STRUCT
            Habilitar : Bool;
            Encontrada : Bool;
            NumeroByte : Int;
            NumeroBit : Int;
            Dispositivo : String;
        END_STRUCT;
        s_EntradaAnalogica : STRUCT
            Habilitar : Bool;
            Encontrada : Bool;
            NumeroByte : Int;
            Dispositivo : String;
        END_STRUCT;
        s_SalidaAnalogica : STRUCT
            Habilitar : Bool;
            Encontrada : Bool;
            NumeroByte : Int;
            Dispositivo : String;
        END_STRUCT;
    END_VAR
    VAR_TEMP
        for_i : Int;
        t_N_MAX_ED : Int;
        t_N_MAX_EA : Int;
        t_N_MAX_SD : Int;
        t_N_MAX_SA : Int;
        t_N_MAX_V : Int;
        t_N_MAX_M : Int;
        t_N_MAX_M_VF : Int;
        t_N_MAX_TOT : Int;
    END_VAR
    VAR CONSTANT
        DISP_ED : String := 'ED-';
        DISP_EA : String := 'EA-';
        DISP_SD : String := 'SD-';
        DISP_SA : String := 'SA-';
        DISP_V : String := 'V-';
        DISP_M : String := 'M-';
        DISP_M_VF : String := 'M-VF-';
        DISP_TOT : String := 'TOT-';
    END_VAR

    { S7_Language := "SCL" }
    NETWORK
        REGION DESCRIPCION
        //=======================================================================
        // (C)Copyright ZeusControl 2023 - 2026
        //=======================================================================
        (*
        ### Información del Sistema
        | Hardware Compatible | Entorno de Ingeniería |
        |---------------------|-----------------------|
        | PLC serie 1200/1500 | TIA Portal 18         |
        
        ---
        ### Descripción Funcional
        El bloque implementa un buscador de direccionamiento de E/S que, a partir de una dirección física (byte/bit para digitales o byte para analógicas), localiza todos los dispositivos del proyecto que la utilizan y devuelve una cadena de texto con la relación de los mismos. Es una herramienta de trazabilidad y diagnóstico que facilita al ingeniero la identificación rápida del uso de cada punto de E/S.
        
        Funcionalidades principales:
        - Búsqueda de entradas digitales (`s_EntradaDigital`): se le indica un byte y un bit, y el bloque recorre los dispositivos `ED` (Entradas Digitales), `V` (Válvulas), `M` (Motores), `M_VF` (Motores con Variador de Frecuencia) y `TOT` (Totalizados) comparando el byte/bit configurado en cada uno con el solicitado. Para las válvulas y motores también coteja los retornos de reposo y trabajo, así como el retorno de confirmación de marcha y térmico.
        - Búsqueda de entradas analógicas (`s_EntradaAnalogica`): se le indica un byte y el bloque recorre los dispositivos `EA` (Entradas Analógicas) comparando la dirección de entrada configurada.
        - Búsqueda de salidas digitales (`s_Salidadigital`): se le indica un byte y un bit, y el bloque recorre los dispositivos `SD` (Salidas Digitales), `V` (Válvulas), `M` (Motores) y `M_VF` (Motores con Variador de Frecuencia) comparando el byte/bit de salida configurado.
        - Búsqueda de salidas analógicas (`s_SalidaAnalogica`): se le indica un byte y el bloque recorre los dispositivos `SA` (Salidas Analógicas) y `M_VF` (Motores con Variador de Frecuencia, salida analógica de consigna) comparando la dirección de salida configurada.
        - En cada búsqueda se valida el rango del bit (entre 1 y 7) cuando aplica, y se construye la cadena de resultados concatenando el prefijo del tipo de dispositivo (`#DISP_ED`, `#DISP_V`, `#DISP_M`, `#DISP_M_VF`, `#DISP_TOT`, `#DISP_EA`, `#DISP_SD`, `#DISP_SA`) con el índice convertido a texto mediante `FC15001_ZC_INT_TO_STRING`, separando cada coincidencia con el carácter `;`.
        - Activación del flag `Encontrada` cuando existe al menos una coincidencia.
        - Inicialización de la estructura de resultados (`Encontrada := FALSE` y `Dispositivo := ''`) al inicio de cada búsqueda, y reseteo del bit fuera de rango.
        
        > **Restricciones:** Ninguna.
        
        ---
        ### Dependencias Requeridas
        | Tipo | Elementos |
        |------|-----------|
        | FC   | `FC15001_ZC_INT_TO_STRING` |
        | FB   | - |
        | DB   | `DB2000_ED`, `DB2001_EA`, `DB2005_SD`, `DB2006_SA`, `DB2010_V`, `DB2015_M`, `DB2016_M_VF`, `DB2025_TOT` |
        | UDT  | `ZC_DISP_ED`, `ZC_DISP_EA`, `ZC_DISP_SD`, `ZC_DISP_SA`, `ZC_DISP_V`, `ZC_DISP_M`, `ZC_DISP_M_VF`, `ZC_DISP_TOT` |
            
        ---
        ### Historial de Cambios
        | Versión  | Fecha      | Técnico | Cambios |
        |----------|------------|---------|---------|
        | 00.00.01 | 12.09.2023 | (ABH)   | Primera version. |
        | 01.00.00 | 02.07.2026 | (ABH)   | Se añade orden "Buscar" para optimizacion de codigo. |
        *)
        END_REGION DESCRIPCION
        
        
        //  ==========================================================================================================
        REGION GESTION_ORDEN_BUSCAR
            
            //  Si no hay orden de buscar, salimos del bloque
            IF NOT #s_Buscar THEN
                RETURN;
            END_IF;
            
        END_REGION GESTION_ORDEN_BUSCAR
        
        
        //  ==========================================================================================================
        REGION TRASPASO_PARAMETROS_N_MAX
            
            #t_N_MAX_ED := "N_MAX_DISP_ED";
            #t_N_MAX_EA := "N_MAX_DISP_EA";
            #t_N_MAX_SD := "N_MAX_DISP_SD";
            #t_N_MAX_SA := "N_MAX_DISP_SA";
            #t_N_MAX_V := "N_MAX_DISP_V";
            #t_N_MAX_M := "N_MAX_DISP_M";
            #t_N_MAX_M_VF := "N_MAX_DISP_M_VF";
            #t_N_MAX_TOT := "N_MAX_DISP_TOT";
            
        END_REGION TRASPASO_PARAMETROS_N_MAX
        
        
        //  ==========================================================================================================
        REGION BUSQUEDA_ENTRADA_DIGITAL
            
            //  Reinicializacion de valores
            #s_EntradaDigital.Encontrada := FALSE;
            #s_EntradaDigital.Dispositivo := '';
            
            //  Solo buscamos si esta habilitado
            IF #s_EntradaDigital.Habilitar THEN
                
                //  Limite de valores
                IF #s_EntradaDigital.NumeroBit > 7 THEN
                    #s_EntradaDigital.NumeroBit := 7;
                END_IF;
                IF #s_EntradaDigital.NumeroBit < 1 THEN
                    #s_EntradaDigital.NumeroBit := 1;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en salida digital
                IF #t_N_MAX_ED > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_ED DO
                        IF #s_EntradaDigital.NumeroByte = "DB2000_ED".ED[#for_i].Config_DirEntradaByte
                            AND
                            #s_EntradaDigital.NumeroBit = "DB2000_ED".ED[#for_i].Config_DirEntradaBit
                        THEN
                            #s_EntradaDigital.Encontrada := TRUE;
                            #s_EntradaDigital.Dispositivo := CONCAT_STRING(IN1 := #s_EntradaDigital.Dispositivo, IN2 := #DISP_ED, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en valvula
                IF #t_N_MAX_V > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_V DO
                        IF (#s_EntradaDigital.NumeroByte = "DB2010_V".V[#for_i].Config_DireccionRetReposoByte
                            AND
                            #s_EntradaDigital.NumeroBit = "DB2010_V".V[#for_i].Config_DireccionRetReposoBit)
                            OR
                            (#s_EntradaDigital.NumeroByte = "DB2010_V".V[#for_i].Config_DireccionRetTrabajoByte
                            AND
                            #s_EntradaDigital.NumeroBit = "DB2010_V".V[#for_i].Config_DireccionRetTrabajoBit)
                        THEN
                            #s_EntradaDigital.Encontrada := TRUE;
                            #s_EntradaDigital.Dispositivo := CONCAT_STRING(IN1 := #s_EntradaDigital.Dispositivo, IN2 := #DISP_V, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en motor
                IF #t_N_MAX_M > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_M DO
                        IF (#s_EntradaDigital.NumeroByte = "DB2015_M".M[#for_i].Config_DireccionRetConfMarchaByte
                            AND
                            #s_EntradaDigital.NumeroBit = "DB2015_M".M[#for_i].Config_DireccionRetConfMarchaBit)
                            OR
                            (#s_EntradaDigital.NumeroByte = "DB2015_M".M[#for_i].Config_DireccionRetTermicoByte
                            AND
                            #s_EntradaDigital.NumeroBit = "DB2015_M".M[#for_i].Config_DireccionRetTermicoBit)
                        THEN
                            #s_EntradaDigital.Encontrada := TRUE;
                            #s_EntradaDigital.Dispositivo := CONCAT_STRING(IN1 := #s_EntradaDigital.Dispositivo, IN2 := #DISP_M, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en motor variador
                IF #t_N_MAX_M_VF > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_M_VF DO
                        IF (#s_EntradaDigital.NumeroByte = "DB2016_M_VF".M_VF[#for_i].Config_DireccionRetConfMarchaByte
                            AND
                            #s_EntradaDigital.NumeroBit = "DB2016_M_VF".M_VF[#for_i].Config_DireccionRetConfMarchaBit)
                            OR
                            (#s_EntradaDigital.NumeroByte = "DB2016_M_VF".M_VF[#for_i].Config_DireccionRetTermicoByte
                            AND
                            #s_EntradaDigital.NumeroBit = "DB2016_M_VF".M_VF[#for_i].Config_DireccionRetTermicoBit)
                        THEN
                            #s_EntradaDigital.Encontrada := TRUE;
                            #s_EntradaDigital.Dispositivo := CONCAT_STRING(IN1 := #s_EntradaDigital.Dispositivo, IN2 := #DISP_M_VF, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en totalizador
                IF #t_N_MAX_TOT > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_TOT DO
                        IF #s_EntradaDigital.NumeroByte = "DB2025_TOT".TOT[#for_i].Config_DireccionEntradaByte
                            AND
                            #s_EntradaDigital.NumeroBit = "DB2025_TOT".TOT[#for_i].Config_DireccionEntradaBit
                        THEN
                            #s_EntradaDigital.Encontrada := TRUE;
                            #s_EntradaDigital.Dispositivo := CONCAT_STRING(IN1 := #s_EntradaDigital.Dispositivo, IN2 := #DISP_TOT, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
            END_IF;
            
            
        END_REGION BUSQUEDA_ENTRADA_DIGITAL
        
        
        //  ==========================================================================================================
        REGION BUSQUEDA_ENTRADA_ANALOGICA
            
            //  Reinicializacion de valores
            #s_EntradaAnalogica.Encontrada := FALSE;
            #s_EntradaAnalogica.Dispositivo := '';
            
            //  Solo buscamos si esta habilitado
            IF #s_EntradaAnalogica.Habilitar THEN
                
                //  ================================================================================================
                //  Busqueda en entrada analogica
                IF #t_N_MAX_EA > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_EA DO
                        IF #s_EntradaAnalogica.NumeroByte = "DB2001_EA".EA[#for_i].Config_DireccionEntradaByte
                        THEN
                            #s_EntradaAnalogica.Encontrada := TRUE;
                            #s_EntradaAnalogica.Dispositivo := CONCAT_STRING(IN1 := #s_EntradaAnalogica.Dispositivo, IN2 := #DISP_EA, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
            END_IF;
            
            
        END_REGION BUSQUEDA_ENTRADA_ANALOGICA
        
        
        //  ==========================================================================================================
        REGION BUSQUEDA_SALIDA_DIGITAL
            
            //  Reinicializacion de valores
            #s_Salidadigital.Encontrada := FALSE;
            #s_Salidadigital.Dispositivo := '';
            
            //  Solo buscamos si esta habilitado
            IF #s_Salidadigital.Habilitar THEN
                
                //  Limite de valores
                IF #s_Salidadigital.NumeroBit > 7 THEN
                    #s_Salidadigital.NumeroBit := 7;
                END_IF;
                IF #s_Salidadigital.NumeroBit < 1 THEN
                    #s_Salidadigital.NumeroBit := 1;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en salida digital
                IF #t_N_MAX_SD > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_SD DO
                        IF #s_Salidadigital.NumeroByte = "DB2005_SD".SD[#for_i].Config_DireccionSalidaByte
                            AND
                            #s_Salidadigital.NumeroBit = "DB2005_SD".SD[#for_i].Config_DireccionSalidaBit
                        THEN
                            #s_Salidadigital.Encontrada := TRUE;
                            #s_Salidadigital.Dispositivo := CONCAT_STRING(IN1 := #s_Salidadigital.Dispositivo, IN2 := #DISP_SD, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en valvula
                IF #t_N_MAX_V > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_V DO
                        IF #s_Salidadigital.NumeroByte = "DB2010_V".V[#for_i].Config_DireccionSalidaByte
                            AND
                            #s_Salidadigital.NumeroBit = "DB2010_V".V[#for_i].Config_DireccionSalidaBit
                        THEN
                            #s_Salidadigital.Encontrada := TRUE;
                            #s_Salidadigital.Dispositivo := CONCAT_STRING(IN1 := #s_Salidadigital.Dispositivo, IN2 := #DISP_V, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en motor
                IF #t_N_MAX_M > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_M DO
                        IF #s_Salidadigital.NumeroByte = "DB2015_M".M[#for_i].Config_DireccionSalidaByte
                            AND
                            #s_Salidadigital.NumeroBit = "DB2015_M".M[#for_i].Config_DireccionSalidaBit
                        THEN
                            #s_Salidadigital.Encontrada := TRUE;
                            #s_Salidadigital.Dispositivo := CONCAT_STRING(IN1 := #s_Salidadigital.Dispositivo, IN2 := #DISP_M, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                //  ================================================================================================
                //  Busqueda en motor variador
                IF #t_N_MAX_M_VF > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_M_VF DO
                        IF #s_Salidadigital.NumeroByte = "DB2016_M_VF".M_VF[#for_i].Config_DireccionSalidaByte
                            AND
                            #s_Salidadigital.NumeroBit = "DB2016_M_VF".M_VF[#for_i].Config_DireccionSalidaBit
                        THEN
                            #s_Salidadigital.Encontrada := TRUE;
                            #s_Salidadigital.Dispositivo := CONCAT_STRING(IN1 := #s_Salidadigital.Dispositivo, IN2 := #DISP_M_VF, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
            END_IF;
            
            
        END_REGION BUSQUEDA_SALIDA_DIGITAL
        
        
        //  ==========================================================================================================
        REGION BUSQUEDA_SALIDA_ANALOGICA
            
            //  Reinicializacion de valores
            #s_SalidaAnalogica.Encontrada := FALSE;
            #s_SalidaAnalogica.Dispositivo := '';
            
            //  Solo buscamos si esta habilitado
            IF #s_SalidaAnalogica.Habilitar THEN
                
                //  ================================================================================================
                //  Busqueda en salida analogica
                IF #t_N_MAX_SA > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_SA DO
                        IF #s_SalidaAnalogica.NumeroByte = "DB2006_SA".SA[#for_i].Config_DireccionSalidaByte
                        THEN
                            #s_SalidaAnalogica.Encontrada := TRUE;
                            #s_SalidaAnalogica.Dispositivo := CONCAT_STRING(IN1 := #s_SalidaAnalogica.Dispositivo, IN2 := #DISP_SA, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
                //  ================================================================================================
                //  Busqueda en motor variador
                IF #t_N_MAX_M_VF > 0 THEN
                    FOR #for_i := 1 TO #t_N_MAX_M_VF DO
                        IF #s_SalidaAnalogica.NumeroByte = "DB2016_M_VF".M_VF[#for_i].Config_DireccionSalidaAnalogicaByte
                        THEN
                            #s_SalidaAnalogica.Encontrada := TRUE;
                            #s_SalidaAnalogica.Dispositivo := CONCAT_STRING(IN1 := #s_SalidaAnalogica.Dispositivo, IN2 := #DISP_M_VF, IN3 := "FC15001_ZC_INT_TO_STRING"(#for_i), IN4 := ';');
                        END_IF;
                    END_FOR;
                END_IF;
                
            END_IF;
            
        END_REGION BUSQUEDA_SALIDA_ANALOGICA
        
        
        //  ==========================================================================================================
        REGION RESET_ORDENES
            
            //  Reset orden buscar
            #s_Buscar := FALSE;
            
        END_REGION RESET_ORDENES
        
    END_NETWORK
END_FUNCTION_BLOCK
