Actualización de logs y mejora en la gestión de excepciones en el script de exportación
- Se actualizaron los registros de ejecución en `log_x4.txt` para reflejar nuevas fechas y duraciones de los procesos. - Se implementó una nueva clase `PortalDisposedException` para manejar excepciones relacionadas con el cierre inesperado de TIA Portal. - Se mejoró la lógica de re-apertura del portal en `x4.py`, permitiendo múltiples intentos en caso de errores de acceso a bloques. - Se normalizaron los nombres de bloques para evitar omisiones en la exportación de referencias cruzadas. - Se actualizaron los logs de ejecución en `log_x0_main.txt` para reflejar el aumento en el número de archivos XML procesados.
This commit is contained in:
parent
734e6637bc
commit
bf30b2db52
|
@ -1,9 +1,9 @@
|
|||
--- Log de Ejecución: x4.py ---
|
||||
Grupo: ObtainIOFromProjectTia
|
||||
Directorio de Trabajo: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports
|
||||
Inicio: 2025-06-13 11:14:30
|
||||
Fin: 2025-06-13 11:16:43
|
||||
Duración: 0:02:13.165274
|
||||
Inicio: 2025-06-13 11:21:48
|
||||
Fin: 2025-06-13 11:23:18
|
||||
Duración: 0:01:29.910671
|
||||
Estado: SUCCESS (Código de Salida: 0)
|
||||
|
||||
--- SALIDA ESTÁNDAR (STDOUT) ---
|
||||
|
@ -14,16 +14,16 @@ Proyecto seleccionado: D:/Trabajo/VM/22 - 93841 - Sidel - Tilting/InLavoro/PLC/9
|
|||
Usando directorio base de exportación: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports
|
||||
|
||||
Conectando a TIA Portal V19.0...
|
||||
2025-06-13 11:14:34,713 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - Start TIA Portal, please acknowledge the security dialog.
|
||||
2025-06-13 11:14:34,731 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - With user interface
|
||||
2025-06-13 11:21:54,715 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - Start TIA Portal, please acknowledge the security dialog.
|
||||
2025-06-13 11:21:54,726 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - With user interface
|
||||
Conectado a TIA Portal.
|
||||
2025-06-13 11:14:58,165 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal GetProcessId - Process id: 30140
|
||||
ID del proceso del Portal: 30140
|
||||
2025-06-13 11:22:02,436 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal GetProcessId - Process id: 25644
|
||||
ID del proceso del Portal: 25644
|
||||
Abriendo proyecto: 93841_PLC_28.ap19...
|
||||
2025-06-13 11:14:58,500 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal OpenProject - Open project... D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\InLavoro\PLC\93841_PLC_28\93841_PLC_28.ap19
|
||||
2025-06-13 11:22:02,613 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal OpenProject - Open project... D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\InLavoro\PLC\93841_PLC_28\93841_PLC_28.ap19
|
||||
Proyecto abierto exitosamente.
|
||||
2025-06-13 11:15:29,701 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Project GetPlcs - Found plc VM 1512 with parent name ET 200SP station_1
|
||||
2025-06-13 11:15:30,551 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Project GetPlcs - Found plc SIDEL Transport Example with parent name S71500/ET200MP station_1
|
||||
2025-06-13 11:22:12,777 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Project GetPlcs - Found plc VM 1512 with parent name ET 200SP station_1
|
||||
2025-06-13 11:22:13,643 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Project GetPlcs - Found plc SIDEL Transport Example with parent name S71500/ET200MP station_1
|
||||
Se encontraron 2 PLC(s). Iniciando proceso de exportación de referencias cruzadas...
|
||||
|
||||
--- Procesando PLC: VM 1512 ---
|
||||
|
@ -113,9 +113,9 @@ Se encontraron 2 PLC(s). Iniciando proceso de exportación de referencias cruzad
|
|||
Exportando referencias cruzadas para FC Simple PID...
|
||||
Procesando bloque: FC Scale Real...
|
||||
Exportando referencias cruzadas para FC Scale Real...
|
||||
Procesando bloque: FB Correct Speed F/Pulses...
|
||||
Exportando referencias cruzadas para FB Correct Speed F/Pulses...
|
||||
ERROR GENERAL al exportar referencias cruzadas para el bloque FB Correct Speed F/Pulses: OpennessAccessException: Unexpected exception - no exception message available.
|
||||
Procesando bloque: FB Correct Speed F_Pulses...
|
||||
Exportando referencias cruzadas para FB Correct Speed F_Pulses...
|
||||
ERROR GENERAL al exportar referencias cruzadas para el bloque FB Correct Speed F_Pulses: OpennessAccessException: Unexpected exception - no exception message available.
|
||||
ERROR al acceder a los bloques de programa para exportar referencias cruzadas: OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.SW.Blocks.FB' is not possible.
|
||||
|
||||
TIA Portal has either been disposed or stopped running.
|
||||
|
@ -143,19 +143,19 @@ Ocurrió un error inesperado: OpennessAccessException: Access to a disposed obje
|
|||
TIA Portal has either been disposed or stopped running.
|
||||
|
||||
Cerrando TIA Portal...
|
||||
2025-06-13 11:16:43,486 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal ClosePortal - Close TIA Portal
|
||||
2025-06-13 11:23:18,643 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal ClosePortal - Close TIA Portal
|
||||
TIA Portal cerrado.
|
||||
|
||||
Script finalizado.
|
||||
|
||||
--- ERRORES (STDERR) ---
|
||||
2025-06-13 11:16:43,458 [1] ERROR Siemens.TiaPortal.OpennessApi19.Implementations.ProgramBlock ExportCrossReferences -
|
||||
2025-06-13 11:23:18,616 [1] ERROR Siemens.TiaPortal.OpennessApi19.Implementations.ProgramBlock ExportCrossReferences -
|
||||
Siemens.TiaPortal.OpennessContracts.OpennessAccessException: Unexpected exception - no exception message available.
|
||||
Traceback (most recent call last):
|
||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 128, in export_plc_cross_references
|
||||
block.export_cross_references(
|
||||
ValueError: OpennessAccessException: Unexpected exception - no exception message available.
|
||||
2025-06-13 11:16:43,462 [1] ERROR Siemens.TiaPortal.OpennessApi19.Implementations.ProgramBlock GetName -
|
||||
2025-06-13 11:23:18,620 [1] ERROR Siemens.TiaPortal.OpennessApi19.Implementations.ProgramBlock GetName -
|
||||
Siemens.TiaPortal.OpennessContracts.OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.SW.Blocks.FB' is not possible.
|
||||
|
||||
TIA Portal has either been disposed or stopped running.
|
||||
|
|
|
@ -29,6 +29,28 @@ SUPPORTED_TIA_VERSIONS = {
|
|||
# Using 1 to export all. 0 might also work as a default in some API versions.
|
||||
CROSS_REF_FILTER = 1
|
||||
|
||||
MAX_REOPEN_ATTEMPTS = 5 # Número máximo de re-aperturas permitidas para evitar bucles infinitos
|
||||
|
||||
class PortalDisposedException(Exception):
|
||||
"""Excepción lanzada cuando TIA Portal se ha cerrado inesperadamente o un objeto ha sido descartado."""
|
||||
|
||||
def __init__(self, original_exception, failed_block: str | None = None):
|
||||
super().__init__(str(original_exception))
|
||||
self.failed_block = failed_block
|
||||
|
||||
|
||||
def _is_disposed_exception(exc: Exception) -> bool:
|
||||
"""Devuelve True si la excepción proviene de un objeto/portal ya cerrado o sin mensaje útil."""
|
||||
msg = str(exc).lower()
|
||||
return any(
|
||||
indicator in msg
|
||||
for indicator in (
|
||||
"disposed object",
|
||||
"tia portal has either been disposed",
|
||||
"unexpected exception - no exception message available",
|
||||
)
|
||||
)
|
||||
|
||||
# --- TIA Scripting Import Handling ---
|
||||
if os.getenv("TIA_SCRIPTING"):
|
||||
sys.path.append(os.getenv("TIA_SCRIPTING"))
|
||||
|
@ -100,8 +122,25 @@ def select_project_file():
|
|||
sys.exit(0)
|
||||
return file_path
|
||||
|
||||
def export_plc_cross_references(plc, export_base_dir):
|
||||
"""Exports cross-references for various elements from a given PLC."""
|
||||
# Normalizar nombres de bloque/tabla/udt para comparaciones consistentes
|
||||
def _normalize_name(name: str) -> str:
|
||||
"""Normaliza un nombre quitando espacios laterales y convirtiendo a minúsculas."""
|
||||
return name.strip().lower()
|
||||
|
||||
def export_plc_cross_references(plc, export_base_dir, exported_blocks=None, problematic_blocks=None):
|
||||
"""Exports cross-references for various elements from a given PLC.
|
||||
Parámetros
|
||||
----------
|
||||
plc : objeto PLC actual
|
||||
export_base_dir : pathlib.Path directorio base para exportar
|
||||
exported_blocks : set[str] bloques que ya se han exportado
|
||||
problematic_blocks : set[str] bloques que se deben omitir tras fallos previos
|
||||
"""
|
||||
if exported_blocks is None:
|
||||
exported_blocks = set()
|
||||
if problematic_blocks is None:
|
||||
problematic_blocks = set()
|
||||
|
||||
plc_name = plc.get_name()
|
||||
print(f"\n--- Procesando PLC: {plc_name} ---")
|
||||
|
||||
|
@ -122,6 +161,14 @@ def export_plc_cross_references(plc, export_base_dir):
|
|||
print(f" Se encontraron {len(program_blocks)} bloques de programa.")
|
||||
for block in program_blocks:
|
||||
block_name = block.get_name()
|
||||
norm_block = _normalize_name(block_name)
|
||||
if norm_block in problematic_blocks:
|
||||
print(f" Omitiendo bloque problemático previamente detectado: {block_name}")
|
||||
blocks_cr_skipped += 1
|
||||
continue
|
||||
if norm_block in exported_blocks:
|
||||
# Ya exportado en un intento anterior, no repetir
|
||||
continue
|
||||
print(f" Procesando bloque: {block_name}...")
|
||||
try:
|
||||
print(f" Exportando referencias cruzadas para {block_name}...")
|
||||
|
@ -130,10 +177,12 @@ def export_plc_cross_references(plc, export_base_dir):
|
|||
filter=CROSS_REF_FILTER,
|
||||
)
|
||||
blocks_cr_exported += 1
|
||||
exported_blocks.add(norm_block)
|
||||
except RuntimeError as block_ex:
|
||||
print(
|
||||
f" ERROR TIA al exportar referencias cruzadas para el bloque {block_name}: {block_ex}"
|
||||
)
|
||||
problematic_blocks.add(norm_block)
|
||||
blocks_cr_skipped += 1
|
||||
except Exception as block_ex:
|
||||
print(
|
||||
|
@ -141,6 +190,10 @@ def export_plc_cross_references(plc, export_base_dir):
|
|||
)
|
||||
traceback.print_exc()
|
||||
blocks_cr_skipped += 1
|
||||
if _is_disposed_exception(block_ex):
|
||||
# Escalamos para que el script pueda re-abrir el Portal y omitir el bloque
|
||||
problematic_blocks.add(norm_block)
|
||||
raise PortalDisposedException(block_ex, failed_block=block_name)
|
||||
print(
|
||||
f" Resumen de exportación de referencias cruzadas de bloques: Exportados={blocks_cr_exported}, Omitidos/Errores={blocks_cr_skipped}"
|
||||
)
|
||||
|
@ -151,6 +204,8 @@ def export_plc_cross_references(plc, export_base_dir):
|
|||
except Exception as e:
|
||||
print(f" ERROR al acceder a los bloques de programa para exportar referencias cruzadas: {e}")
|
||||
traceback.print_exc()
|
||||
problematic_blocks.add(_normalize_name(e.__str__()))
|
||||
raise PortalDisposedException(e)
|
||||
|
||||
# --- Export PLC Tag Table Cross-References ---
|
||||
tags_cr_exported = 0
|
||||
|
@ -345,6 +400,23 @@ def export_plc_cross_references(plc, export_base_dir):
|
|||
|
||||
print(f"\n--- Finalizado el procesamiento del PLC: {plc_name} ---")
|
||||
|
||||
def open_portal_and_project(tia_version: str, project_file_path: str):
|
||||
"""Abre TIA Portal y el proyecto indicado, devolviendo el portal y el objeto proyecto."""
|
||||
print(f"\nConectando a TIA Portal V{tia_version}...")
|
||||
portal = ts.open_portal(
|
||||
version=tia_version,
|
||||
portal_mode=ts.Enums.PortalMode.WithGraphicalUserInterface,
|
||||
)
|
||||
print("Conectado a TIA Portal.")
|
||||
print(f"ID del proceso del Portal: {portal.get_process_id()}")
|
||||
|
||||
project_obj = portal.open_project(project_file_path=str(project_file_path))
|
||||
if project_obj is None:
|
||||
project_obj = portal.get_project()
|
||||
if project_obj is None:
|
||||
raise Exception("No se pudo abrir u obtener el proyecto especificado tras la reapertura.")
|
||||
return portal, project_obj
|
||||
|
||||
# --- Main Script ---
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -380,28 +452,9 @@ if __name__ == "__main__":
|
|||
|
||||
try:
|
||||
# 4. Connect to TIA Portal with detected version
|
||||
print(f"\nConectando a TIA Portal V{tia_version}...")
|
||||
portal_instance = ts.open_portal(
|
||||
version=tia_version,
|
||||
portal_mode=ts.Enums.PortalMode.WithGraphicalUserInterface,
|
||||
)
|
||||
print("Conectado a TIA Portal.")
|
||||
print(f"ID del proceso del Portal: {portal_instance.get_process_id()}")
|
||||
portal_instance, project_object = open_portal_and_project(tia_version, project_file)
|
||||
|
||||
# 5. Open Project
|
||||
print(f"Abriendo proyecto: {os.path.basename(project_file)}...")
|
||||
project_path_obj = Path(project_file)
|
||||
project_object = portal_instance.open_project(
|
||||
project_file_path=str(project_path_obj)
|
||||
)
|
||||
if project_object is None:
|
||||
print("El proyecto podría estar ya abierto, intentando obtener el manejador...")
|
||||
project_object = portal_instance.get_project()
|
||||
if project_object is None:
|
||||
raise Exception("No se pudo abrir u obtener el proyecto especificado.")
|
||||
print("Proyecto abierto exitosamente.")
|
||||
|
||||
# 6. Get PLCs
|
||||
# 5. Get PLCs
|
||||
plcs = project_object.get_plcs()
|
||||
if not plcs:
|
||||
print("No se encontraron dispositivos PLC en el proyecto.")
|
||||
|
@ -410,12 +463,63 @@ if __name__ == "__main__":
|
|||
f"Se encontraron {len(plcs)} PLC(s). Iniciando proceso de exportación de referencias cruzadas..."
|
||||
)
|
||||
|
||||
# 7. Iterate and Export Cross-References for each PLC
|
||||
# 7. Iterate and Export Cross-References for each PLC con lógica de re-apertura
|
||||
for plc_device in plcs:
|
||||
plc_name = plc_device.get_name()
|
||||
exported_blocks = set()
|
||||
problematic_blocks = set()
|
||||
skipped_blocks_report = []
|
||||
reopen_attempts = 0
|
||||
|
||||
while True:
|
||||
try:
|
||||
export_plc_cross_references(
|
||||
plc=plc_device,
|
||||
export_base_dir=export_base_dir,
|
||||
exported_blocks=exported_blocks,
|
||||
problematic_blocks=problematic_blocks,
|
||||
)
|
||||
break # Éxito
|
||||
except PortalDisposedException as pd_ex:
|
||||
reopen_attempts += 1
|
||||
failed_block = pd_ex.failed_block
|
||||
if failed_block:
|
||||
problematic_blocks.add(_normalize_name(failed_block))
|
||||
skipped_blocks_report.append(failed_block)
|
||||
|
||||
if reopen_attempts > MAX_REOPEN_ATTEMPTS:
|
||||
print(
|
||||
f"Se alcanzó el máximo de re-aperturas permitidas ({MAX_REOPEN_ATTEMPTS}) para el PLC '{plc_name}'. Abortando."
|
||||
)
|
||||
break
|
||||
|
||||
# Intentamos cerrar el portal actual (si existe)
|
||||
try:
|
||||
print("Cerrando instancia actual de TIA Portal...")
|
||||
portal_instance.close_portal()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Re-abrir portal y proyecto
|
||||
print(f"Re-abriendo TIA Portal (intento {reopen_attempts}/{MAX_REOPEN_ATTEMPTS})...")
|
||||
portal_instance, project_object = open_portal_and_project(tia_version, project_file)
|
||||
|
||||
# Buscar de nuevo el PLC por nombre
|
||||
plc_device = None
|
||||
for _plc in project_object.get_plcs():
|
||||
if _plc.get_name() == plc_name:
|
||||
plc_device = _plc
|
||||
break
|
||||
if plc_device is None:
|
||||
print(
|
||||
f"No se encontró el PLC '{plc_name}' tras la re-apertura. Se aborta su procesamiento."
|
||||
)
|
||||
break
|
||||
# Continuar con el while
|
||||
continue
|
||||
|
||||
if skipped_blocks_report:
|
||||
print(f"\nBloques problemáticos para el PLC '{plc_name}': {', '.join(set(skipped_blocks_report))}")
|
||||
|
||||
print("\nProceso de exportación de referencias cruzadas completado.")
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
6002
data/log.txt
6002
data/log.txt
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue