Actualización del script x0_main.py y mejora en la gestión de logs
- Se implementó un nuevo sistema de argumentos para permitir el procesamiento de múltiples PLCs desde un directorio de trabajo. - Se mejoró la lógica de búsqueda de archivos XML, eliminando la dependencia de un subdirectorio específico. - Se actualizaron los logs de ejecución para reflejar el estado exitoso del procesamiento y se añadieron detalles sobre los archivos encontrados y procesados. - Se generaron nuevos archivos de salida en formato Markdown y se mejoró la estructura de los logs para facilitar la comprensión del proceso.
This commit is contained in:
parent
04084e7289
commit
e70852ecf1
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -162,72 +162,116 @@ def check_skip_status(
|
||||||
|
|
||||||
# --- Bloque Principal ---
|
# --- Bloque Principal ---
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# 1. Analizar argumentos de línea de comandos
|
||||||
|
# --plc-dir : ruta al PLC a procesar directamente (modo interno)
|
||||||
|
# Si NO se pasa el flag, el script actuará como "orquestador" detectando
|
||||||
|
# todos los PLCs bajo el working_directory y lanzándose a sí mismo para
|
||||||
|
# cada uno de ellos.
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
arg_parser = argparse.ArgumentParser(description="Convertidor XML→SCL (multi-PLC)")
|
||||||
|
arg_parser.add_argument("--plc-dir", dest="plc_dir", help="Ruta del PLC a procesar (uso interno).", default=None)
|
||||||
|
cli_args, _ = arg_parser.parse_known_args()
|
||||||
|
|
||||||
|
# Cargar configuración
|
||||||
configs = load_configuration()
|
configs = load_configuration()
|
||||||
working_directory = configs.get("working_directory")
|
working_directory = configs.get("working_directory")
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# 2. Si NO se indicó --plc-dir ⇒ modo ORQUESTADOR
|
||||||
|
# Detecta todos los PLC (subdirectorios con al menos un .xml) y lanza
|
||||||
|
# este mismo script para cada uno con el flag --plc-dir.
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
if cli_args.plc_dir is None:
|
||||||
|
if not working_directory or not os.path.isdir(working_directory):
|
||||||
|
print("Error: 'working_directory' inválido en la configuración.", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Detectar PLCs como subdirectorios que contengan al menos un XML
|
||||||
|
detected_plc_dirs = []
|
||||||
|
for entry in os.listdir(working_directory):
|
||||||
|
cand_path = os.path.join(working_directory, entry)
|
||||||
|
if os.path.isdir(cand_path):
|
||||||
|
if glob.glob(os.path.join(cand_path, "**", "*.xml"), recursive=True):
|
||||||
|
detected_plc_dirs.append(cand_path)
|
||||||
|
|
||||||
|
# Si no se encontró ningún PLC (quizás el working_directory ya ES el PLC)
|
||||||
|
if not detected_plc_dirs:
|
||||||
|
detected_plc_dirs = [working_directory]
|
||||||
|
|
||||||
|
# Ejecutar secuencialmente el script para cada PLC
|
||||||
|
overall_exit_code = 0
|
||||||
|
for plc_dir in detected_plc_dirs:
|
||||||
|
print(f"\n=== Lanzando procesamiento para PLC: {os.path.basename(plc_dir)} ===")
|
||||||
|
ret = subprocess.call([sys.executable, os.path.abspath(__file__), "--plc-dir", plc_dir])
|
||||||
|
if ret != 0:
|
||||||
|
overall_exit_code = 1 # Registrar fallo global si algún PLC falla
|
||||||
|
|
||||||
|
sys.exit(overall_exit_code)
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# 3. Modo INTERNO (se recibió --plc-dir) ⇒ procesar sólo ese PLC
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
xml_project_dir = os.path.abspath(cli_args.plc_dir)
|
||||||
|
if not os.path.isdir(xml_project_dir):
|
||||||
|
print(f"Error: El directorio PLC especificado no existe: {xml_project_dir}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Usaremos el nombre del PLC para diferenciar los logs
|
||||||
|
plc_name_safe = os.path.basename(xml_project_dir.strip(os.sep))
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
# 3.1 Leer parámetros específicos del grupo para reutilizarlos más abajo
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
xml_parser_config = configs.get("level2", {})
|
xml_parser_config = configs.get("level2", {})
|
||||||
|
|
||||||
# <-- NUEVO: Leer parámetros de configuración para x3, x4, x5 -->
|
|
||||||
# xml_parser_config = configs.get("XML Parser to SCL", {})
|
|
||||||
cfg_scl_output_dirname = xml_parser_config.get("scl_output_dir", "scl_output")
|
cfg_scl_output_dirname = xml_parser_config.get("scl_output_dir", "scl_output")
|
||||||
cfg_xref_output_dirname = xml_parser_config.get("xref_output_dir", "xref_output")
|
cfg_xref_output_dirname = xml_parser_config.get("xref_output_dir", "xref_output")
|
||||||
cfg_xref_source_subdir = xml_parser_config.get("xref_source_subdir", "source")
|
cfg_xref_source_subdir = xml_parser_config.get("xref_source_subdir", "source")
|
||||||
cfg_call_xref_filename = xml_parser_config.get("call_xref_filename", "xref_calls_tree.md")
|
cfg_call_xref_filename = xml_parser_config.get("call_xref_filename", "xref_calls_tree.md")
|
||||||
cfg_db_usage_xref_filename = xml_parser_config.get("db_usage_xref_filename", "xref_db_usage_summary.md")
|
cfg_db_usage_xref_filename = xml_parser_config.get("db_usage_xref_filename", "xref_db_usage_summary.md")
|
||||||
cfg_plc_tag_xref_filename = xml_parser_config.get("plc_tag_xref_filename", "xref_plc_tags_summary.md")
|
cfg_plc_tag_xref_filename = xml_parser_config.get("plc_tag_xref_filename", "xref_plc_tags_summary.md")
|
||||||
|
|
||||||
# Ensure max_call_depth is an integer
|
# Conversión de enteros con control de errores
|
||||||
try:
|
try:
|
||||||
cfg_max_call_depth = int(xml_parser_config.get("max_call_depth", 5))
|
cfg_max_call_depth = int(xml_parser_config.get("max_call_depth", 5))
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
print("Advertencia: Valor inválido para 'max_call_depth' en la configuración. Usando valor por defecto 5.", file=sys.stderr)
|
print("Advertencia: Valor inválido para 'max_call_depth' en la configuración. Usando valor por defecto 5.", file=sys.stderr)
|
||||||
cfg_max_call_depth = 5
|
cfg_max_call_depth = 5
|
||||||
|
|
||||||
# Ensure max_users_list is an integer
|
|
||||||
try:
|
try:
|
||||||
cfg_max_users_list = int(xml_parser_config.get("max_users_list", 20))
|
cfg_max_users_list = int(xml_parser_config.get("max_users_list", 20))
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
print("Advertencia: Valor inválido para 'max_users_list' en la configuración. Usando valor por defecto 20.", file=sys.stderr)
|
print("Advertencia: Valor inválido para 'max_users_list' en la configuración. Usando valor por defecto 20.", file=sys.stderr)
|
||||||
cfg_max_users_list = 20
|
cfg_max_users_list = 20
|
||||||
|
|
||||||
cfg_aggregated_filename = xml_parser_config.get("aggregated_filename", "full_project_representation.md")
|
cfg_aggregated_filename = xml_parser_config.get("aggregated_filename", "full_project_representation.md")
|
||||||
# <-- FIN NUEVO -->
|
|
||||||
|
# Generar un nombre de log específico por PLC
|
||||||
|
log_filename_dynamic = f"log_{plc_name_safe}.txt"
|
||||||
|
log_filepath = os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)), log_filename_dynamic
|
||||||
|
)
|
||||||
|
|
||||||
# Directorio donde se encuentra este script (x0_main.py)
|
# Directorio donde se encuentra este script (x0_main.py)
|
||||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
# <-- MODIFICADO: Abrir archivo log -->
|
# <-- MODIFICADO: Abrir archivo log -->
|
||||||
log_filepath = os.path.join(
|
|
||||||
os.path.dirname(os.path.abspath(__file__)), LOG_FILENAME
|
|
||||||
)
|
|
||||||
with open(
|
with open(
|
||||||
log_filepath, "w", encoding="utf-8"
|
log_filepath, "w", encoding="utf-8"
|
||||||
) as log_f: # Usar 'a' para añadir al log
|
) as log_f: # Usar 'a' para añadir al log
|
||||||
log_message("=" * 40 + " LOG START " + "=" * 40, log_f)
|
log_message("=" * 40 + " LOG START " + "=" * 40, log_f)
|
||||||
|
|
||||||
# --- PARTE 1: BUSCAR ARCHIVOS ---
|
# --- PARTE 1: BUSCAR ARCHIVOS ---
|
||||||
# <-- MODIFICADO: Apuntar al subdirectorio 'PLC' dentro del working_directory -->
|
# Se trabaja exclusivamente dentro del PLC indicado.
|
||||||
plc_subdir_name = "PLC" # Nombre estándar del subdirectorio de TIA Portal
|
|
||||||
xml_project_dir = os.path.join(working_directory, plc_subdir_name)
|
|
||||||
|
|
||||||
log_message(
|
log_message(
|
||||||
f"Directorio de trabajo base configurado: '{working_directory}'", log_f
|
f"Directorio de trabajo base configurado: '{working_directory}'", log_f
|
||||||
)
|
)
|
||||||
log_message(
|
log_message(
|
||||||
f"Buscando archivos XML recursivamente en el subdirectorio: '{xml_project_dir}'", log_f
|
f"Buscando archivos XML recursivamente en: '{xml_project_dir}'", log_f
|
||||||
)
|
)
|
||||||
|
|
||||||
# Verificar si el directorio PLC existe
|
# Patrón de búsqueda global para todos los PLC
|
||||||
if not os.path.isdir(xml_project_dir):
|
|
||||||
log_message(
|
|
||||||
f"Error: El subdirectorio '{plc_subdir_name}' no existe dentro de '{working_directory}'. "
|
|
||||||
f"Se esperaba encontrar la estructura del proyecto TIA Portal en '{xml_project_dir}'.",
|
|
||||||
log_f,
|
|
||||||
also_print=False,
|
|
||||||
)
|
|
||||||
print(
|
|
||||||
f"Error: El subdirectorio '{plc_subdir_name}' no existe dentro de '{working_directory}'. "
|
|
||||||
f"Asegúrese de que la ruta del directorio de trabajo apunte a la carpeta que *contiene* la carpeta '{plc_subdir_name}'.", file=sys.stderr
|
|
||||||
)
|
|
||||||
sys.exit(1)
|
|
||||||
search_pattern = os.path.join(xml_project_dir, "**", "*.xml")
|
search_pattern = os.path.join(xml_project_dir, "**", "*.xml")
|
||||||
xml_files_found = glob.glob(search_pattern, recursive=True)
|
xml_files_found = glob.glob(search_pattern, recursive=True)
|
||||||
if not xml_files_found:
|
if not xml_files_found:
|
||||||
|
@ -423,7 +467,7 @@ if __name__ == "__main__":
|
||||||
log_message(f"Se encontraron {len(filtered_scl_files)} archivos .scl existentes para copiar:", log_f)
|
log_message(f"Se encontraron {len(filtered_scl_files)} archivos .scl existentes para copiar:", log_f)
|
||||||
for src_scl_path in filtered_scl_files:
|
for src_scl_path in filtered_scl_files:
|
||||||
relative_scl_path = os.path.relpath(src_scl_path, xml_project_dir)
|
relative_scl_path = os.path.relpath(src_scl_path, xml_project_dir)
|
||||||
dest_scl_path = os.path.join(scl_output_dir, os.path.basename(src_scl_path)) # Copy directly into scl_output_dir
|
dest_scl_path = os.path.join(scl_output_dir, os.path.basename(src_scl_path)) # Copia directa al scl_output del PLC
|
||||||
|
|
||||||
# Check if a file with the same name was already generated from XML
|
# Check if a file with the same name was already generated from XML
|
||||||
if os.path.exists(dest_scl_path):
|
if os.path.exists(dest_scl_path):
|
||||||
|
@ -513,7 +557,8 @@ if __name__ == "__main__":
|
||||||
run_x5 = False
|
run_x5 = False
|
||||||
|
|
||||||
if run_x5:
|
if run_x5:
|
||||||
output_agg_file = os.path.join(working_directory, cfg_aggregated_filename) # Usar valor de config
|
# El archivo agregado se guarda dentro del PLC para mantener salidas separadas
|
||||||
|
output_agg_file = os.path.join(xml_project_dir, cfg_aggregated_filename)
|
||||||
log_message(
|
log_message(
|
||||||
f"Ejecutando x5 (aggregate_outputs) sobre: {xml_project_dir}, salida agregada en: {output_agg_file}",
|
f"Ejecutando x5 (aggregate_outputs) sobre: {xml_project_dir}, salida agregada en: {output_agg_file}",
|
||||||
log_f
|
log_f
|
||||||
|
@ -590,7 +635,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
log_message(final_console_message, log_f) # Loguear mensaje final
|
log_message(final_console_message, log_f) # Loguear mensaje final
|
||||||
print(
|
print(
|
||||||
f"\n{final_console_message} Consulta '{LOG_FILENAME}' para detalles."
|
f"\n{final_console_message} Consulta '{log_filename_dynamic}' para detalles."
|
||||||
) # Mostrar mensaje en consola
|
) # Mostrar mensaje en consola
|
||||||
log_message("="*41 + " LOG END " + "="*42, log_f)
|
log_message("="*41 + " LOG END " + "="*42, log_f)
|
||||||
|
|
||||||
|
|
14975
data/log.txt
14975
data/log.txt
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue