Compare commits
5 Commits
be3b333491
...
734e6637bc
Author | SHA1 | Date |
---|---|---|
|
734e6637bc | |
|
6150c719ca | |
|
0488624d64 | |
|
e70852ecf1 | |
|
04084e7289 |
|
@ -25,6 +25,9 @@ share/python-wheels/
|
|||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
*.txt
|
||||
*.json
|
||||
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
|
|
69
app.py
69
app.py
|
@ -33,6 +33,37 @@ websocket_connections = set()
|
|||
# --- Globals for Tray Icon ---
|
||||
tray_icon = None
|
||||
|
||||
# --- Parámetros para envío por lotes de logs ---
|
||||
BATCH_FLUSH_INTERVAL = 0.5 # segundos
|
||||
broadcast_buffer = [] # Almacena líneas formateadas pendientes de envío
|
||||
buffer_lock = threading.Lock() # Sincroniza acceso al buffer
|
||||
|
||||
def _broadcast_flush_loop():
|
||||
"""Hilo que vacía el buffer de logs cada BATCH_FLUSH_INTERVAL segundos."""
|
||||
while True:
|
||||
time.sleep(BATCH_FLUSH_INTERVAL)
|
||||
with buffer_lock:
|
||||
if not broadcast_buffer:
|
||||
continue
|
||||
batch = "\n".join(broadcast_buffer)
|
||||
broadcast_buffer.clear()
|
||||
_send_batch_to_clients(batch)
|
||||
|
||||
def _send_batch_to_clients(batch_message: str):
|
||||
"""Envía un bloque de texto a todas las conexiones WebSocket activas."""
|
||||
dead_connections = set()
|
||||
for ws in list(websocket_connections):
|
||||
try:
|
||||
if ws.connected:
|
||||
ws.send(batch_message + "\n")
|
||||
except Exception:
|
||||
dead_connections.add(ws)
|
||||
websocket_connections.difference_update(dead_connections)
|
||||
|
||||
# Iniciar hilo de vaciado en segundo plano (ahora que las dependencias están definidas)
|
||||
flusher_thread = threading.Thread(target=_broadcast_flush_loop, daemon=True)
|
||||
flusher_thread.start()
|
||||
|
||||
|
||||
@sock.route("/ws")
|
||||
def handle_websocket(ws):
|
||||
|
@ -49,49 +80,34 @@ def handle_websocket(ws):
|
|||
|
||||
|
||||
def broadcast_message(message):
|
||||
"""Envía un mensaje a todas las conexiones WebSocket activas y guarda en log."""
|
||||
dead_connections = set()
|
||||
"""Acumula mensajes en un buffer y los envía por lotes cada 500 ms."""
|
||||
timestamp = datetime.now().strftime("[%H:%M:%S] ")
|
||||
|
||||
# Normalize input to a list of messages
|
||||
# Normalizar entrada a lista de mensajes
|
||||
if isinstance(message, list):
|
||||
messages = message
|
||||
else:
|
||||
# Si es un solo mensaje, dividirlo en líneas
|
||||
messages = [line.strip() for line in message.splitlines() if line.strip()]
|
||||
|
||||
# Procesar cada mensaje
|
||||
for raw_msg in messages:
|
||||
# Limpiar timestamps duplicados al inicio del mensaje
|
||||
while raw_msg.startswith("[") and "]" in raw_msg:
|
||||
try:
|
||||
closing_bracket = raw_msg.index("]") + 1
|
||||
if raw_msg[1 : closing_bracket - 1].replace(":", "").isdigit():
|
||||
raw_msg = raw_msg[closing_bracket:].strip() # Update raw_msg itself
|
||||
if raw_msg[1:closing_bracket - 1].replace(":", "").isdigit():
|
||||
raw_msg = raw_msg[closing_bracket:].strip()
|
||||
else:
|
||||
break
|
||||
except:
|
||||
except ValueError:
|
||||
break
|
||||
|
||||
# Log the raw message using the config_manager's logger
|
||||
# The logger will handle its own timestamping for the file.
|
||||
# Registrar en archivo (la clase Logger añade timestamp propio)
|
||||
config_manager.append_log(raw_msg)
|
||||
|
||||
# Format message with timestamp *for WebSocket broadcast*
|
||||
# Formatear para el WebSocket y añadir al buffer
|
||||
formatted_msg_for_ws = f"{timestamp}{raw_msg}"
|
||||
|
||||
# Enviar a todos los clientes WebSocket
|
||||
for ws in list(websocket_connections):
|
||||
try:
|
||||
if ws.connected: # Check if ws is still connected before sending
|
||||
ws.send(
|
||||
f"{formatted_msg_for_ws}\n"
|
||||
) # Use the correct variable name here
|
||||
except Exception:
|
||||
dead_connections.add(ws) # Collect dead connections
|
||||
|
||||
# Limpiar conexiones muertas
|
||||
websocket_connections.difference_update(dead_connections)
|
||||
with buffer_lock:
|
||||
broadcast_buffer.append(formatted_msg_for_ws)
|
||||
|
||||
|
||||
@app.route("/api/execute_script", methods=["POST"])
|
||||
|
@ -1053,3 +1069,8 @@ if __name__ == "__main__":
|
|||
print(f"Error al iniciar el icono de notificación: {e}", file=sys.stderr)
|
||||
|
||||
print("Aplicación finalizada.")
|
||||
|
||||
# --- Iniciar hilo de vaciado en segundo plano (única vez) ---
|
||||
# flusher_thread = threading.Thread(target=_broadcast_flush_loop, daemon=True)
|
||||
# flusher_thread.start()
|
||||
# ------------------------------------------------------------
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,251 +1,199 @@
|
|||
--- Log de Ejecución: x4.py ---
|
||||
Grupo: ObtainIOFromProjectTia
|
||||
Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\SourceDoc\SourceXML
|
||||
Inicio: 2025-05-20 12:12:51
|
||||
Fin: 2025-05-20 12:20:01
|
||||
Duración: 0:07:09.648304
|
||||
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
|
||||
Estado: SUCCESS (Código de Salida: 0)
|
||||
|
||||
--- SALIDA ESTÁNDAR (STDOUT) ---
|
||||
--- TIA Portal Cross-Reference Exporter ---
|
||||
--- Exportador de Referencias Cruzadas de TIA Portal ---
|
||||
Versión de TIA Portal detectada: 19.0 (de la extensión .ap19)
|
||||
|
||||
Selected Project: C:/Trabajo/SIDEL/09 - SAE452 - Diet as Regular - San Giovanni in Bosco/Reporte/SourceDoc/Migration/SAE452/SAE452.ap18
|
||||
Using Base Export Directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\SourceDoc\SourceXML
|
||||
Proyecto seleccionado: D:/Trabajo/VM/22 - 93841 - Sidel - Tilting/InLavoro/PLC/93841_PLC_28/93841_PLC_28.ap19
|
||||
Usando directorio base de exportación: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports
|
||||
|
||||
Connecting to TIA Portal V18.0...
|
||||
2025-05-20 12:12:56,780 [1] INFO Siemens.TiaPortal.OpennessApi18.Implementations.Global OpenPortal - Start TIA Portal, please acknowledge the security dialog.
|
||||
2025-05-20 12:12:56,804 [1] INFO Siemens.TiaPortal.OpennessApi18.Implementations.Global OpenPortal - With user interface
|
||||
Connected to TIA Portal.
|
||||
2025-05-20 12:13:30,582 [1] INFO Siemens.TiaPortal.OpennessApi18.Implementations.Portal GetProcessId - Process id: 21952
|
||||
Portal Process ID: 21952
|
||||
Opening project: SAE452.ap18...
|
||||
2025-05-20 12:13:31,077 [1] INFO Siemens.TiaPortal.OpennessApi18.Implementations.Portal OpenProject - Open project... C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\SourceDoc\Migration\SAE452\SAE452.ap18
|
||||
Project opened successfully.
|
||||
2025-05-20 12:14:15,234 [1] INFO Siemens.TiaPortal.OpennessApi18.Implementations.Project GetPlcs - Found plc CPU 315F-2 PN/DP with parent name _SSAE0452
|
||||
Found 1 PLC(s). Starting cross-reference export process...
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
Se encontraron 2 PLC(s). Iniciando proceso de exportación de referencias cruzadas...
|
||||
|
||||
--- Processing PLC: CPU 315F-2 PN/DP ---
|
||||
--- Procesando PLC: VM 1512 ---
|
||||
|
||||
[PLC: CPU 315F-2 PN/DP] Exporting Program Block Cross-References...
|
||||
Target: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\SourceDoc\SourceXML\CPU 315F-2 PN\DP\ProgramBlocks_CR
|
||||
Found 410 program blocks.
|
||||
Processing block: ISOonTCP_or_TCP_Protocol...
|
||||
Exporting cross-references for ISOonTCP_or_TCP_Protocol...
|
||||
Processing block: PIDControl...
|
||||
Exporting cross-references for PIDControl...
|
||||
Processing block: DETAIL_DP_DIAG...
|
||||
Exporting cross-references for DETAIL_DP_DIAG...
|
||||
Processing block: Net Dosing Sys Prof...
|
||||
Exporting cross-references for Net Dosing Sys Prof...
|
||||
Processing block: ICS Profibus Comm...
|
||||
Exporting cross-references for ICS Profibus Comm...
|
||||
Processing block: GNS DriveDiag...
|
||||
Exporting cross-references for GNS DriveDiag...
|
||||
Processing block: HMI_Blender_Parameters...
|
||||
Exporting cross-references for HMI_Blender_Parameters...
|
||||
Processing block: HMI Drive...
|
||||
Exporting cross-references for HMI Drive...
|
||||
Processing block: GNS DriveDiagMain...
|
||||
Exporting cross-references for GNS DriveDiagMain...
|
||||
Processing block: Integral...
|
||||
Exporting cross-references for Integral...
|
||||
Processing block: LowPassFilter...
|
||||
Exporting cross-references for LowPassFilter...
|
||||
Processing block: SlewLimit...
|
||||
Exporting cross-references for SlewLimit...
|
||||
Processing block: MSE Slope...
|
||||
Exporting cross-references for MSE Slope...
|
||||
Processing block: Statistical_Analisys...
|
||||
Exporting cross-references for Statistical_Analisys...
|
||||
Processing block: Blender_Variables...
|
||||
Exporting cross-references for Blender_Variables...
|
||||
Processing block: BrixTracking_ProdSamples...
|
||||
Exporting cross-references for BrixTracking_ProdSamples...
|
||||
Processing block: Procedure_Variables...
|
||||
Exporting cross-references for Procedure_Variables...
|
||||
Processing block: Blender_Constants...
|
||||
Exporting cross-references for Blender_Constants...
|
||||
Processing block: BrixTracking_SampleTime...
|
||||
Exporting cross-references for BrixTracking_SampleTime...
|
||||
Processing block: Delay...
|
||||
Exporting cross-references for Delay...
|
||||
Processing block: CO2Tracking_ProdSamples...
|
||||
Exporting cross-references for CO2Tracking_ProdSamples...
|
||||
Processing block: CO2Tracking_SampleTime...
|
||||
Exporting cross-references for CO2Tracking_SampleTime...
|
||||
Processing block: Interlocking_Variables...
|
||||
Exporting cross-references for Interlocking_Variables...
|
||||
Processing block: System_RunOut_Variables...
|
||||
Exporting cross-references for System_RunOut_Variables...
|
||||
Processing block: CIP_Program_Variables...
|
||||
Exporting cross-references for CIP_Program_Variables...
|
||||
Processing block: Filler_Head_Variables...
|
||||
Exporting cross-references for Filler_Head_Variables...
|
||||
Processing block: Filling_Time_Tranfer_DB...
|
||||
Exporting cross-references for Filling_Time_Tranfer_DB...
|
||||
Processing block: Blender_Variables_Pers...
|
||||
Exporting cross-references for Blender_Variables_Pers...
|
||||
Processing block: HMI_Alarms...
|
||||
Exporting cross-references for HMI_Alarms...
|
||||
Processing block: HMI_Local_CIP_Variables...
|
||||
Exporting cross-references for HMI_Local_CIP_Variables...
|
||||
Processing block: HMI_Service...
|
||||
Exporting cross-references for HMI_Service...
|
||||
Processing block: HMI_Variables_Cmd...
|
||||
Exporting cross-references for HMI_Variables_Cmd...
|
||||
Processing block: HMI_Variables_Status...
|
||||
Exporting cross-references for HMI_Variables_Status...
|
||||
Processing block: HMI_Device...
|
||||
Exporting cross-references for HMI_Device...
|
||||
Processing block: HMI_Instrument...
|
||||
Exporting cross-references for HMI_Instrument...
|
||||
Processing block: HMI_Digital...
|
||||
Exporting cross-references for HMI_Digital...
|
||||
Processing block: HMI_PID...
|
||||
Exporting cross-references for HMI_PID...
|
||||
Processing block: HMI_ICS...
|
||||
Exporting cross-references for HMI_ICS...
|
||||
Processing block: HMI_Device_AVS...
|
||||
Exporting cross-references for HMI_Device_AVS...
|
||||
Processing block: Profibus_Variables...
|
||||
Exporting cross-references for Profibus_Variables...
|
||||
Processing block: Input_CheckFlowMetersSta...
|
||||
Exporting cross-references for Input_CheckFlowMetersSta...
|
||||
Processing block: Input_DigitalScanner...
|
||||
Exporting cross-references for Input_DigitalScanner...
|
||||
Processing block: ProductLiterInTank...
|
||||
Exporting cross-references for ProductLiterInTank...
|
||||
Processing block: ProductAvailable...
|
||||
Exporting cross-references for ProductAvailable...
|
||||
Processing block: T_Timer...
|
||||
Exporting cross-references for T_Timer...
|
||||
Processing block: SEL_I...
|
||||
Exporting cross-references for SEL_I...
|
||||
Processing block: _StepMove...
|
||||
Exporting cross-references for _StepMove...
|
||||
Processing block: ProductPipeDrain_Seq...
|
||||
Exporting cross-references for ProductPipeDrain_Seq...
|
||||
Processing block: ProductPipeDrain...
|
||||
Exporting cross-references for ProductPipeDrain...
|
||||
Processing block: ProductPipeRunOut_Seq...
|
||||
Exporting cross-references for ProductPipeRunOut_Seq...
|
||||
Processing block: SEL_R...
|
||||
Exporting cross-references for SEL_R...
|
||||
Processing block: ProductPipeRunOut...
|
||||
Exporting cross-references for ProductPipeRunOut...
|
||||
Processing block: LIMIT_I...
|
||||
Exporting cross-references for LIMIT_I...
|
||||
Processing block: System_Run_Out...
|
||||
Exporting cross-references for System_Run_Out...
|
||||
Processing block: System_Run_Out_Data...
|
||||
Exporting cross-references for System_Run_Out_Data...
|
||||
ERROR accessing Program Blocks for cross-reference export: RemotingException: El objeto '/bd68de4c_3307_463d_b3ce_57a1378b3bde/lnycb9uriadrpgmom_mjdspm_249.rem' se desconectó o no existe en el servidor.
|
||||
[PLC: VM 1512] Exportando referencias cruzadas de bloques de programa...
|
||||
Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\ProgramBlocks_CR
|
||||
Se encontraron 201 bloques de programa.
|
||||
Procesando bloque: FC General COM...
|
||||
Exportando referencias cruzadas para FC General COM...
|
||||
Procesando bloque: From_SIDEL...
|
||||
Exportando referencias cruzadas para From_SIDEL...
|
||||
Procesando bloque: To_SIDEL...
|
||||
Exportando referencias cruzadas para To_SIDEL...
|
||||
Procesando bloque: DB Early Restart Blower...
|
||||
Exportando referencias cruzadas para DB Early Restart Blower...
|
||||
Procesando bloque: DB Early Restart Filler...
|
||||
Exportando referencias cruzadas para DB Early Restart Filler...
|
||||
Procesando bloque: DB Early Restart SynchroBlock...
|
||||
Exportando referencias cruzadas para DB Early Restart SynchroBlock...
|
||||
Procesando bloque: FB Early Restart...
|
||||
Exportando referencias cruzadas para FB Early Restart...
|
||||
Procesando bloque: DB Signal Transport...
|
||||
Exportando referencias cruzadas para DB Signal Transport...
|
||||
Procesando bloque: FC Signal Transport...
|
||||
Exportando referencias cruzadas para FC Signal Transport...
|
||||
Procesando bloque: DB Lube - Dry Ecolab...
|
||||
Exportando referencias cruzadas para DB Lube - Dry Ecolab...
|
||||
Procesando bloque: FB Lube - Water/Dry...
|
||||
Exportando referencias cruzadas para FB Lube - Water/Dry...
|
||||
Procesando bloque: FB Lube - Dry Ecolab...
|
||||
Exportando referencias cruzadas para FB Lube - Dry Ecolab...
|
||||
Procesando bloque: FB Lube - EcoLab VM...
|
||||
Exportando referencias cruzadas para FB Lube - EcoLab VM...
|
||||
Procesando bloque: FB Lube - Ecolab...
|
||||
Exportando referencias cruzadas para FB Lube - Ecolab...
|
||||
Procesando bloque: DB LUBE - Ecolab...
|
||||
Exportando referencias cruzadas para DB LUBE - Ecolab...
|
||||
Procesando bloque: FC Ttop Configuration...
|
||||
Exportando referencias cruzadas para FC Ttop Configuration...
|
||||
Procesando bloque: FC Ttop Run...
|
||||
Exportando referencias cruzadas para FC Ttop Run...
|
||||
Procesando bloque: FC Ttop Alarms...
|
||||
Exportando referencias cruzadas para FC Ttop Alarms...
|
||||
Procesando bloque: DB Ttop Run...
|
||||
Exportando referencias cruzadas para DB Ttop Run...
|
||||
Procesando bloque: DB Ttop Motor CFG...
|
||||
Exportando referencias cruzadas para DB Ttop Motor CFG...
|
||||
Procesando bloque: DB Ttop Alarm...
|
||||
Exportando referencias cruzadas para DB Ttop Alarm...
|
||||
Procesando bloque: FC Ttop Motor 31...
|
||||
Exportando referencias cruzadas para FC Ttop Motor 31...
|
||||
Procesando bloque: FC Ttop Motor 32...
|
||||
Exportando referencias cruzadas para FC Ttop Motor 32...
|
||||
Procesando bloque: FC Ttop Motor 34...
|
||||
Exportando referencias cruzadas para FC Ttop Motor 34...
|
||||
Procesando bloque: FC Ttop Motor 35...
|
||||
Exportando referencias cruzadas para FC Ttop Motor 35...
|
||||
Procesando bloque: FC Ttop Motor 36...
|
||||
Exportando referencias cruzadas para FC Ttop Motor 36...
|
||||
Procesando bloque: DB Ttop Motor 31...
|
||||
Exportando referencias cruzadas para DB Ttop Motor 31...
|
||||
Procesando bloque: DB Ttop Motor 32...
|
||||
Exportando referencias cruzadas para DB Ttop Motor 32...
|
||||
Procesando bloque: DB Ttop Motor 34...
|
||||
Exportando referencias cruzadas para DB Ttop Motor 34...
|
||||
Procesando bloque: DB Ttop Motor 35...
|
||||
Exportando referencias cruzadas para DB Ttop Motor 35...
|
||||
Procesando bloque: DB Ttop Minimotor Cfg 32...
|
||||
Exportando referencias cruzadas para DB Ttop Minimotor Cfg 32...
|
||||
Procesando bloque: DB Ttop Minimotor Data 32...
|
||||
Exportando referencias cruzadas para DB Ttop Minimotor Data 32...
|
||||
Procesando bloque: DB Ttop Motor 36...
|
||||
Exportando referencias cruzadas para DB Ttop Motor 36...
|
||||
Procesando bloque: FB Ttop Dryer...
|
||||
Exportando referencias cruzadas para FB Ttop Dryer...
|
||||
Procesando bloque: FB Ttop Energy Saving...
|
||||
Exportando referencias cruzadas para FB Ttop Energy Saving...
|
||||
Procesando bloque: FB SKID...
|
||||
Exportando referencias cruzadas para FB SKID...
|
||||
Procesando bloque: FC Analog Sensor Process...
|
||||
Exportando referencias cruzadas para FC Analog Sensor Process...
|
||||
Procesando bloque: FC Valve...
|
||||
Exportando referencias cruzadas para FC Valve...
|
||||
Procesando bloque: FB SpeedRegulation...
|
||||
Exportando referencias cruzadas para FB SpeedRegulation...
|
||||
Procesando bloque: FC Simple PID...
|
||||
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.
|
||||
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.
|
||||
|
||||
[PLC: CPU 315F-2 PN/DP] Exporting PLC Tag Table Cross-References...
|
||||
Target: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\SourceDoc\SourceXML\CPU 315F-2 PN\DP\PlcTags_CR
|
||||
Found 2 Tag Tables.
|
||||
Processing Tag Table: Default tag table...
|
||||
Exporting cross-references for Default tag table...
|
||||
Processing Tag Table: STEP7 classic symbols...
|
||||
Exporting cross-references for STEP7 classic symbols...
|
||||
Tag Table CR Export Summary: Exported=2, Skipped/Errors=0
|
||||
TIA Portal has either been disposed or stopped running.
|
||||
|
||||
[PLC: CPU 315F-2 PN/DP] Exporting PLC Data Type (UDT) Cross-References...
|
||||
Target: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\SourceDoc\SourceXML\CPU 315F-2 PN\DP\PlcDataTypes_CR
|
||||
Found 21 UDTs.
|
||||
Processing UDT: AnyPoint...
|
||||
Exporting cross-references for AnyPoint...
|
||||
Processing UDT: FunctionButton...
|
||||
Exporting cross-references for FunctionButton...
|
||||
Processing UDT: TADDR_PAR...
|
||||
Exporting cross-references for TADDR_PAR...
|
||||
Processing UDT: Device...
|
||||
Exporting cross-references for Device...
|
||||
Processing UDT: AnalogInstrument...
|
||||
Exporting cross-references for AnalogInstrument...
|
||||
Processing UDT: DigitalInstrument...
|
||||
Exporting cross-references for DigitalInstrument...
|
||||
Processing UDT: PID...
|
||||
Exporting cross-references for PID...
|
||||
Processing UDT: EHS16...
|
||||
Exporting cross-references for EHS16...
|
||||
Processing UDT: Danfoss Diag...
|
||||
Exporting cross-references for Danfoss Diag...
|
||||
Processing UDT: QCO Timer...
|
||||
Exporting cross-references for QCO Timer...
|
||||
Processing UDT: QCO Phase...
|
||||
Exporting cross-references for QCO Phase...
|
||||
Processing UDT: ReportCIPSimpleData...
|
||||
Exporting cross-references for ReportCIPSimpleData...
|
||||
Processing UDT: CIP_WaitEvent_Type...
|
||||
Exporting cross-references for CIP_WaitEvent_Type...
|
||||
Processing UDT: CIP_Step_Type_New...
|
||||
Exporting cross-references for CIP_Step_Type_New...
|
||||
Processing UDT: CIP_Simple_Type...
|
||||
Exporting cross-references for CIP_Simple_Type...
|
||||
Processing UDT: CIP_Link_Type...
|
||||
Exporting cross-references for CIP_Link_Type...
|
||||
Processing UDT: CIP_Step_Type...
|
||||
Exporting cross-references for CIP_Step_Type...
|
||||
Processing UDT: Recipe_Prod...
|
||||
Exporting cross-references for Recipe_Prod...
|
||||
Processing UDT: ICS Hndsk receive signal...
|
||||
Exporting cross-references for ICS Hndsk receive signal...
|
||||
Processing UDT: ICS Hndsk send signal...
|
||||
Exporting cross-references for ICS Hndsk send signal...
|
||||
Processing UDT: TCON_PAR...
|
||||
Exporting cross-references for TCON_PAR...
|
||||
UDT CR Export Summary: Exported=21, Skipped/Errors=0
|
||||
[PLC: VM 1512] Exportando referencias cruzadas de tablas de variables...
|
||||
Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\PlcTags_CR
|
||||
ERROR al acceder a las tablas de variables para exportar referencias cruzadas: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
|
||||
[PLC: CPU 315F-2 PN/DP] Attempting to Export System Block Cross-References...
|
||||
Target: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\SourceDoc\SourceXML\CPU 315F-2 PN\DP\SystemBlocks_CR
|
||||
Found 12 system blocks (using get_system_blocks).
|
||||
Processing System Block: TIM_S5TI...
|
||||
Exporting cross-references for TIM_S5TI...
|
||||
Processing System Block: REPLACE...
|
||||
Exporting cross-references for REPLACE...
|
||||
Processing System Block: LIMIT...
|
||||
Exporting cross-references for LIMIT...
|
||||
Processing System Block: NE_STRNG...
|
||||
Exporting cross-references for NE_STRNG...
|
||||
Processing System Block: TURCV...
|
||||
Exporting cross-references for TURCV...
|
||||
Processing System Block: TUSEND...
|
||||
Exporting cross-references for TUSEND...
|
||||
Processing System Block: PID_Continuos...
|
||||
Exporting cross-references for PID_Continuos...
|
||||
Processing System Block: TDISCON...
|
||||
Exporting cross-references for TDISCON...
|
||||
Processing System Block: TCON...
|
||||
Exporting cross-references for TCON...
|
||||
Processing System Block: TRCV...
|
||||
Exporting cross-references for TRCV...
|
||||
Processing System Block: TSEND...
|
||||
Exporting cross-references for TSEND...
|
||||
Processing System Block: DT_DATE...
|
||||
Exporting cross-references for DT_DATE...
|
||||
System Block CR Export Summary: Exported=12, Skipped/Errors=0
|
||||
[PLC: VM 1512] Exportando referencias cruzadas de tipos de datos PLC (UDTs)...
|
||||
Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\PlcDataTypes_CR
|
||||
ERROR al acceder a los UDTs para exportar referencias cruzadas: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
|
||||
[PLC: CPU 315F-2 PN/DP] Attempting to Export Software Unit Cross-References...
|
||||
Target: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\SourceDoc\SourceXML\CPU 315F-2 PN\DP\SoftwareUnits_CR
|
||||
Found 0 Software Units.
|
||||
Software Unit CR Export Summary: Exported=0, Skipped/Errors=0
|
||||
[PLC: VM 1512] Intentando exportar referencias cruzadas de bloques de sistema...
|
||||
Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\SystemBlocks_CR
|
||||
ERROR al acceder/procesar bloques de sistema para exportar referencias cruzadas: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
|
||||
--- Finished processing PLC: CPU 315F-2 PN/DP ---
|
||||
[PLC: VM 1512] Intentando exportar referencias cruzadas de unidades de software...
|
||||
Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\SoftwareUnits_CR
|
||||
ERROR al acceder/procesar unidades de software para exportar referencias cruzadas: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
|
||||
Cross-reference export process completed.
|
||||
--- Finalizado el procesamiento del PLC: VM 1512 ---
|
||||
|
||||
Closing TIA Portal...
|
||||
2025-05-20 12:19:54,187 [1] INFO Siemens.TiaPortal.OpennessApi18.Implementations.Portal ClosePortal - Close TIA Portal
|
||||
TIA Portal closed.
|
||||
Ocurrió un error inesperado: OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.HW.DeviceItemImpl' is not possible.
|
||||
|
||||
Script finished.
|
||||
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
|
||||
TIA Portal cerrado.
|
||||
|
||||
Script finalizado.
|
||||
|
||||
--- ERRORES (STDERR) ---
|
||||
2025-06-13 11:16:43,458 [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 99, in export_plc_cross_references
|
||||
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 -
|
||||
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.
|
||||
Traceback (most recent call last):
|
||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 124, in export_plc_cross_references
|
||||
block_name = block.get_name()
|
||||
^^^^^^^^^^^^^^^^
|
||||
ValueError: RemotingException: El objeto '/bd68de4c_3307_463d_b3ce_57a1378b3bde/lnycb9uriadrpgmom_mjdspm_249.rem' se desconectó o no existe en el servidor.
|
||||
ValueError: 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.
|
||||
Traceback (most recent call last):
|
||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 164, in export_plc_cross_references
|
||||
tag_tables = plc.get_plc_tag_tables()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
ValueError: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
Traceback (most recent call last):
|
||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 207, in export_plc_cross_references
|
||||
udts = plc.get_user_data_types()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
ValueError: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
Traceback (most recent call last):
|
||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 251, in export_plc_cross_references
|
||||
system_blocks = plc.get_system_blocks()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
ValueError: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
Traceback (most recent call last):
|
||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 305, in export_plc_cross_references
|
||||
software_units = plc.get_software_units()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
ValueError: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
Traceback (most recent call last):
|
||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 415, in <module>
|
||||
export_plc_cross_references(
|
||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 105, in export_plc_cross_references
|
||||
plc_name = plc.get_name()
|
||||
^^^^^^^^^^^^^^
|
||||
ValueError: OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.HW.DeviceItemImpl' is not possible.
|
||||
|
||||
TIA Portal has either been disposed or stopped running.
|
||||
|
||||
--- FIN DEL LOG ---
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
},
|
||||
"level2": {},
|
||||
"level3": {},
|
||||
"working_directory": "D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source"
|
||||
"working_directory": "D:\\Trabajo\\VM\\22 - 93841 - Sidel - Tilting\\Reporte\\TiaExports"
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"x1.py": {
|
||||
"display_name": "1: Exportar Lógica desde TIA Portal v18 en XML",
|
||||
"display_name": "1: Exportar Lógica desde TIA Portal v18,v19,v20 en XML",
|
||||
"short_description": "Exporta la lógica del PLC desde TIA Portal en archivos XML y SCL.",
|
||||
"long_description": "Este script utiliza TIA Portal Openness para exportar la lógica de un PLC en formato XML y SCL. Permite seleccionar un proyecto de TIA Portal y genera los archivos de exportación en el directorio configurado.\n***\n**Lógica Principal:**\n\n1. **Configuración:** Carga parámetros desde `ParamManagerScripts` (directorio de trabajo, versión de TIA Portal).\n2. **Selección de Proyecto:** Abre un cuadro de diálogo para seleccionar el archivo del proyecto de TIA Portal.\n3. **Conexión a TIA Portal:** Utiliza la API de TIA Openness para conectarse al portal y abrir el proyecto seleccionado.\n4. **Exportación:** Exporta la lógica del PLC en archivos XML y SCL al directorio configurado.\n5. **Cierre:** Cierra la conexión con TIA Portal al finalizar.",
|
||||
"hidden": false
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"path": "D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source",
|
||||
"path": "D:\\Trabajo\\VM\\22 - 93841 - Sidel - Tilting\\Reporte\\TiaExports",
|
||||
"history": [
|
||||
"D:\\Trabajo\\VM\\22 - 93841 - Sidel - Tilting\\Reporte\\TiaExports",
|
||||
"D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source",
|
||||
"C:\\Trabajo\\SIDEL\\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\\Reporte\\SourceDoc\\SourcdSD",
|
||||
"C:\\Trabajo\\SIDEL\\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\\Reporte\\SourceDoc\\SourceXML"
|
||||
|
|
|
@ -7,6 +7,7 @@ from tkinter import filedialog
|
|||
import os
|
||||
import sys
|
||||
import traceback
|
||||
from pathlib import Path # Import Path
|
||||
|
||||
script_root = os.path.dirname(
|
||||
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
@ -15,11 +16,15 @@ sys.path.append(script_root)
|
|||
from backend.script_utils import load_configuration
|
||||
|
||||
# --- Configuration ---
|
||||
TIA_PORTAL_VERSION = "18.0" # Target TIA Portal version (e.g., "18.0")
|
||||
# Supported TIA Portal versions mapping (extension -> version)
|
||||
SUPPORTED_TIA_VERSIONS = {
|
||||
".ap18": "18.0",
|
||||
".ap19": "19.0",
|
||||
".ap20": "20.0"
|
||||
}
|
||||
|
||||
EXPORT_OPTIONS = None # Use default export options
|
||||
KEEP_FOLDER_STRUCTURE = (
|
||||
True # Replicate TIA project folder structure in export directory
|
||||
)
|
||||
KEEP_FOLDER_STRUCTURE = True # Replicate TIA project folder structure in export directory
|
||||
|
||||
# --- TIA Scripting Import Handling ---
|
||||
# Check if the TIA_SCRIPTING environment variable is set
|
||||
|
@ -59,6 +64,33 @@ except Exception as e:
|
|||
|
||||
# --- Functions ---
|
||||
|
||||
def get_supported_filetypes():
|
||||
"""Returns the supported file types for TIA Portal projects."""
|
||||
filetypes = []
|
||||
for ext, version in SUPPORTED_TIA_VERSIONS.items():
|
||||
version_major = version.split('.')[0]
|
||||
filetypes.append((f"TIA Portal V{version_major} Projects", f"*{ext}"))
|
||||
|
||||
# Add option to show all supported files
|
||||
all_extensions = " ".join([f"*{ext}" for ext in SUPPORTED_TIA_VERSIONS.keys()])
|
||||
filetypes.insert(0, ("All TIA Portal Projects", all_extensions))
|
||||
|
||||
return filetypes
|
||||
|
||||
def detect_tia_version(project_file_path):
|
||||
"""Detects TIA Portal version based on file extension."""
|
||||
file_path = Path(project_file_path)
|
||||
file_extension = file_path.suffix.lower()
|
||||
|
||||
if file_extension in SUPPORTED_TIA_VERSIONS:
|
||||
detected_version = SUPPORTED_TIA_VERSIONS[file_extension]
|
||||
print(f"Versión de TIA Portal detectada: {detected_version} (de la extensión {file_extension})")
|
||||
return detected_version
|
||||
else:
|
||||
print(f"ADVERTENCIA: Extensión de archivo no reconocida '{file_extension}'. Extensiones soportadas: {list(SUPPORTED_TIA_VERSIONS.keys())}")
|
||||
# Default to version 18.0 for backward compatibility
|
||||
print("Usando por defecto TIA Portal V18.0")
|
||||
return "18.0"
|
||||
|
||||
def select_project_file():
|
||||
"""Opens a dialog to select a TIA Portal project file."""
|
||||
|
@ -66,16 +98,11 @@ def select_project_file():
|
|||
root.withdraw() # Hide the main tkinter window
|
||||
file_path = filedialog.askopenfilename(
|
||||
title="Select TIA Portal Project File",
|
||||
filetypes=[
|
||||
(
|
||||
f"TIA Portal V{TIA_PORTAL_VERSION} Projects",
|
||||
f"*.ap{TIA_PORTAL_VERSION.split('.')[0]}",
|
||||
)
|
||||
], # e.g. *.ap18
|
||||
filetypes=get_supported_filetypes()
|
||||
)
|
||||
root.destroy()
|
||||
if not file_path:
|
||||
print("No project file selected. Exiting.")
|
||||
print("No se seleccionó ningún archivo de proyecto. Saliendo.")
|
||||
sys.exit(0)
|
||||
return file_path
|
||||
|
||||
|
@ -95,7 +122,7 @@ def select_export_directory():
|
|||
def export_plc_data(plc, export_base_dir):
|
||||
"""Exports Blocks, UDTs, and Tag Tables from a given PLC."""
|
||||
plc_name = plc.get_name()
|
||||
print(f"\n--- Processing PLC: {plc_name} ---")
|
||||
print(f"\n--- Procesando PLC: {plc_name} ---")
|
||||
|
||||
# Define base export path for this PLC
|
||||
plc_export_dir = os.path.join(export_base_dir, plc_name)
|
||||
|
@ -104,143 +131,140 @@ def export_plc_data(plc, export_base_dir):
|
|||
# --- Export Program Blocks ---
|
||||
blocks_exported = 0
|
||||
blocks_skipped = 0
|
||||
print(f"\n[PLC: {plc_name}] Exporting Program Blocks...")
|
||||
print(f"\n[PLC: {plc_name}] Exportando bloques de programa...")
|
||||
xml_blocks_path = os.path.join(plc_export_dir, "ProgramBlocks_XML")
|
||||
scl_blocks_path = os.path.join(plc_export_dir, "ProgramBlocks_SCL")
|
||||
os.makedirs(xml_blocks_path, exist_ok=True)
|
||||
os.makedirs(scl_blocks_path, exist_ok=True)
|
||||
print(f" XML Target: {xml_blocks_path}")
|
||||
print(f" SCL Target: {scl_blocks_path}")
|
||||
print(f" Destino XML: {xml_blocks_path}")
|
||||
print(f" Destino SCL: {scl_blocks_path}")
|
||||
|
||||
try:
|
||||
program_blocks = plc.get_program_blocks() #
|
||||
print(f" Found {len(program_blocks)} program blocks.")
|
||||
program_blocks = plc.get_program_blocks()
|
||||
print(f" Se encontraron {len(program_blocks)} bloques de programa.")
|
||||
for block in program_blocks:
|
||||
block_name = block.get_name() # Assuming get_name() exists
|
||||
print(f" Processing block: {block_name}...")
|
||||
block_name = block.get_name()
|
||||
print(f" Procesando bloque: {block_name}...")
|
||||
try:
|
||||
if not block.is_consistent(): #
|
||||
print(f" Compiling block {block_name}...")
|
||||
block.compile() #
|
||||
if not block.is_consistent():
|
||||
print(f" Compilando bloque {block_name}...")
|
||||
block.compile()
|
||||
if not block.is_consistent():
|
||||
print(
|
||||
f" WARNING: Block {block_name} inconsistent after compile. Skipping."
|
||||
f" ADVERTENCIA: Bloque {block_name} inconsistente después de compilar. Omitiendo."
|
||||
)
|
||||
blocks_skipped += 1
|
||||
continue
|
||||
|
||||
print(f" Exporting {block_name} as XML...")
|
||||
print(f" Exportando {block_name} como XML...")
|
||||
block.export(
|
||||
target_directory_path=xml_blocks_path, #
|
||||
export_options=EXPORT_OPTIONS, #
|
||||
export_format=ts.Enums.ExportFormats.SimaticML, #
|
||||
target_directory_path=xml_blocks_path,
|
||||
export_options=EXPORT_OPTIONS,
|
||||
export_format=ts.Enums.ExportFormats.SimaticML,
|
||||
keep_folder_structure=KEEP_FOLDER_STRUCTURE,
|
||||
) #
|
||||
)
|
||||
|
||||
try:
|
||||
prog_language = block.get_property(name="ProgrammingLanguage")
|
||||
if prog_language == "SCL":
|
||||
print(f" Exporting {block_name} as SCL...")
|
||||
print(f" Exportando {block_name} como SCL...")
|
||||
block.export(
|
||||
target_directory_path=scl_blocks_path,
|
||||
export_options=EXPORT_OPTIONS,
|
||||
export_format=ts.Enums.ExportFormats.ExternalSource, #
|
||||
export_format=ts.Enums.ExportFormats.ExternalSource,
|
||||
keep_folder_structure=KEEP_FOLDER_STRUCTURE,
|
||||
)
|
||||
except Exception as prop_ex:
|
||||
print(
|
||||
f" Could not get ProgrammingLanguage for {block_name}. Skipping SCL. Error: {prop_ex}"
|
||||
f" No se pudo obtener el lenguaje de programación para {block_name}. Omitiendo SCL. Error: {prop_ex}"
|
||||
)
|
||||
|
||||
blocks_exported += 1
|
||||
except Exception as block_ex:
|
||||
print(f" ERROR exporting block {block_name}: {block_ex}")
|
||||
print(f" ERROR exportando bloque {block_name}: {block_ex}")
|
||||
blocks_skipped += 1
|
||||
print(
|
||||
f" Program Blocks Export Summary: Exported={blocks_exported}, Skipped/Errors={blocks_skipped}"
|
||||
f" Resumen de exportación de bloques: Exportados={blocks_exported}, Omitidos/Errores={blocks_skipped}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f" ERROR processing Program Blocks: {e}")
|
||||
print(f" ERROR procesando bloques de programa: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
# --- Export PLC Data Types (UDTs) ---
|
||||
udts_exported = 0
|
||||
udts_skipped = 0
|
||||
print(f"\n[PLC: {plc_name}] Exporting PLC Data Types (UDTs)...")
|
||||
print(f"\n[PLC: {plc_name}] Exportando tipos de datos PLC (UDTs)...")
|
||||
udt_export_path = os.path.join(plc_export_dir, "PlcDataTypes")
|
||||
os.makedirs(udt_export_path, exist_ok=True)
|
||||
print(f" Target: {udt_export_path}")
|
||||
print(f" Destino: {udt_export_path}")
|
||||
|
||||
try:
|
||||
udts = plc.get_user_data_types() #
|
||||
print(f" Found {len(udts)} UDTs.")
|
||||
udts = plc.get_user_data_types()
|
||||
print(f" Se encontraron {len(udts)} UDTs.")
|
||||
for udt in udts:
|
||||
udt_name = udt.get_name() #
|
||||
print(f" Processing UDT: {udt_name}...")
|
||||
udt_name = udt.get_name()
|
||||
print(f" Procesando UDT: {udt_name}...")
|
||||
try:
|
||||
if not udt.is_consistent(): #
|
||||
print(f" Compiling UDT {udt_name}...")
|
||||
udt.compile() #
|
||||
if not udt.is_consistent():
|
||||
print(f" Compilando UDT {udt_name}...")
|
||||
udt.compile()
|
||||
if not udt.is_consistent():
|
||||
print(
|
||||
f" WARNING: UDT {udt_name} inconsistent after compile. Skipping."
|
||||
f" ADVERTENCIA: UDT {udt_name} inconsistente después de compilar. Omitiendo."
|
||||
)
|
||||
udts_skipped += 1
|
||||
continue
|
||||
|
||||
print(f" Exporting {udt_name}...")
|
||||
print(f" Exportando {udt_name}...")
|
||||
udt.export(
|
||||
target_directory_path=udt_export_path, #
|
||||
export_options=EXPORT_OPTIONS, #
|
||||
# export_format defaults to SimaticML for UDTs
|
||||
target_directory_path=udt_export_path,
|
||||
export_options=EXPORT_OPTIONS,
|
||||
keep_folder_structure=KEEP_FOLDER_STRUCTURE,
|
||||
) #
|
||||
)
|
||||
udts_exported += 1
|
||||
except Exception as udt_ex:
|
||||
print(f" ERROR exporting UDT {udt_name}: {udt_ex}")
|
||||
print(f" ERROR exportando UDT {udt_name}: {udt_ex}")
|
||||
udts_skipped += 1
|
||||
print(
|
||||
f" UDT Export Summary: Exported={udts_exported}, Skipped/Errors={udts_skipped}"
|
||||
f" Resumen de exportación de UDTs: Exportados={udts_exported}, Omitidos/Errores={udts_skipped}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f" ERROR processing UDTs: {e}")
|
||||
print(f" ERROR procesando UDTs: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
# --- Export PLC Tag Tables ---
|
||||
tags_exported = 0
|
||||
tags_skipped = 0
|
||||
print(f"\n[PLC: {plc_name}] Exporting PLC Tag Tables...")
|
||||
print(f"\n[PLC: {plc_name}] Exportando tablas de variables PLC...")
|
||||
tags_export_path = os.path.join(plc_export_dir, "PlcTags")
|
||||
os.makedirs(tags_export_path, exist_ok=True)
|
||||
print(f" Target: {tags_export_path}")
|
||||
print(f" Destino: {tags_export_path}")
|
||||
|
||||
try:
|
||||
tag_tables = plc.get_plc_tag_tables() #
|
||||
print(f" Found {len(tag_tables)} Tag Tables.")
|
||||
tag_tables = plc.get_plc_tag_tables()
|
||||
print(f" Se encontraron {len(tag_tables)} tablas de variables.")
|
||||
for table in tag_tables:
|
||||
table_name = table.get_name() #
|
||||
print(f" Processing Tag Table: {table_name}...")
|
||||
table_name = table.get_name()
|
||||
print(f" Procesando tabla de variables: {table_name}...")
|
||||
try:
|
||||
# Note: Consistency check might not be available/needed for tag tables like blocks/UDTs
|
||||
print(f" Exporting {table_name}...")
|
||||
print(f" Exportando {table_name}...")
|
||||
table.export(
|
||||
target_directory_path=tags_export_path, #
|
||||
export_options=EXPORT_OPTIONS, #
|
||||
# export_format defaults to SimaticML for Tag Tables
|
||||
target_directory_path=tags_export_path,
|
||||
export_options=EXPORT_OPTIONS,
|
||||
keep_folder_structure=KEEP_FOLDER_STRUCTURE,
|
||||
) #
|
||||
)
|
||||
tags_exported += 1
|
||||
except Exception as table_ex:
|
||||
print(f" ERROR exporting Tag Table {table_name}: {table_ex}")
|
||||
print(f" ERROR exportando tabla de variables {table_name}: {table_ex}")
|
||||
tags_skipped += 1
|
||||
print(
|
||||
f" Tag Table Export Summary: Exported={tags_exported}, Skipped/Errors={tags_skipped}"
|
||||
f" Resumen de exportación de tablas de variables: Exportados={tags_exported}, Omitidos/Errores={tags_skipped}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f" ERROR processing Tag Tables: {e}")
|
||||
print(f" ERROR procesando tablas de variables: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
print(f"\n--- Finished processing PLC: {plc_name} ---")
|
||||
print(f"\n--- Finalizado el procesamiento del PLC: {plc_name} ---")
|
||||
|
||||
|
||||
# --- Main Script ---
|
||||
|
@ -250,75 +274,76 @@ if __name__ == "__main__":
|
|||
configs = load_configuration()
|
||||
working_directory = configs.get("working_directory")
|
||||
|
||||
print("--- TIA Portal Data Exporter (Blocks, UDTs, Tags) ---")
|
||||
print("--- Exportador de datos TIA Portal (Bloques, UDTs, Variables) ---")
|
||||
|
||||
# Validate working directory
|
||||
if not working_directory or not os.path.isdir(working_directory):
|
||||
print("ERROR: Working directory not set or invalid in configuration.")
|
||||
print("Please configure the working directory using the main application.")
|
||||
print("ERROR: Directorio de trabajo no configurado o inválido.")
|
||||
print("Por favor configure el directorio de trabajo usando la aplicación principal.")
|
||||
sys.exit(1)
|
||||
|
||||
# 1. Select Project File, Export Directory comes from config
|
||||
project_file = select_project_file()
|
||||
export_dir = working_directory # Use working directory from config
|
||||
|
||||
print(f"\nSelected Project: {project_file}")
|
||||
print(f"Using Export Directory (Working Directory): {export_dir}")
|
||||
# 2. Detect TIA Portal version from project file
|
||||
tia_version = detect_tia_version(project_file)
|
||||
|
||||
print(f"\nProyecto seleccionado: {project_file}")
|
||||
print(f"Usando directorio de exportación (Directorio de trabajo): {export_dir}")
|
||||
|
||||
portal_instance = None
|
||||
project_object = None
|
||||
|
||||
try:
|
||||
# 2. Connect to TIA Portal
|
||||
print(f"\nConnecting to TIA Portal V{TIA_PORTAL_VERSION}...")
|
||||
# 3. Connect to TIA Portal with detected version
|
||||
print(f"\nConectando a TIA Portal V{tia_version}...")
|
||||
portal_instance = ts.open_portal(
|
||||
version=TIA_PORTAL_VERSION,
|
||||
version=tia_version,
|
||||
portal_mode=ts.Enums.PortalMode.WithGraphicalUserInterface,
|
||||
)
|
||||
print("Connected to TIA Portal.")
|
||||
print(f"Portal Process ID: {portal_instance.get_process_id()}") #
|
||||
print("Conectado a TIA Portal.")
|
||||
print(f"ID del proceso del Portal: {portal_instance.get_process_id()}")
|
||||
|
||||
# 3. Open Project
|
||||
print(f"Opening project: {os.path.basename(project_file)}...")
|
||||
project_object = portal_instance.open_project(project_file_path=project_file) #
|
||||
# 4. Open Project
|
||||
print(f"Abriendo proyecto: {os.path.basename(project_file)}...")
|
||||
project_object = portal_instance.open_project(project_file_path=project_file)
|
||||
if project_object is None:
|
||||
print("Project might already be open, attempting to get handle...")
|
||||
project_object = portal_instance.get_project() #
|
||||
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("Failed to open or get the specified project.")
|
||||
print("Project opened successfully.")
|
||||
raise Exception("No se pudo abrir u obtener el proyecto especificado.")
|
||||
print("Proyecto abierto exitosamente.")
|
||||
|
||||
# 4. Get PLCs
|
||||
plcs = project_object.get_plcs() #
|
||||
# 5. Get PLCs
|
||||
plcs = project_object.get_plcs()
|
||||
if not plcs:
|
||||
print("No PLC devices found in the project.")
|
||||
print("No se encontraron dispositivos PLC en el proyecto.")
|
||||
else:
|
||||
print(f"Found {len(plcs)} PLC(s). Starting export process...")
|
||||
print(f"Se encontraron {len(plcs)} PLC(s). Iniciando proceso de exportación...")
|
||||
|
||||
# 5. Iterate and Export Data for each PLC
|
||||
# 6. Iterate and Export Data for each PLC
|
||||
for plc_device in plcs:
|
||||
export_plc_data(
|
||||
plc=plc_device, export_base_dir=export_dir
|
||||
) # Pass export_dir
|
||||
export_plc_data(plc=plc_device, export_base_dir=export_dir)
|
||||
|
||||
print("\nExport process completed.")
|
||||
print("\nProceso de exportación completado.")
|
||||
|
||||
except ts.TiaException as tia_ex:
|
||||
print(f"\nTIA Portal Openness Error: {tia_ex}")
|
||||
print(f"\nError de TIA Portal Openness: {tia_ex}")
|
||||
traceback.print_exc()
|
||||
except FileNotFoundError:
|
||||
print(f"\nERROR: Project file not found at {project_file}")
|
||||
print(f"\nERROR: Archivo de proyecto no encontrado en {project_file}")
|
||||
except Exception as e:
|
||||
print(f"\nAn unexpected error occurred: {e}")
|
||||
print(f"\nOcurrió un error inesperado: {e}")
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
# 6. Cleanup
|
||||
# 7. Cleanup
|
||||
if portal_instance:
|
||||
try:
|
||||
print("\nClosing TIA Portal...")
|
||||
portal_instance.close_portal() #
|
||||
print("TIA Portal closed.")
|
||||
print("\nCerrando TIA Portal...")
|
||||
portal_instance.close_portal()
|
||||
print("TIA Portal cerrado.")
|
||||
except Exception as close_ex:
|
||||
print(f"Error during TIA Portal cleanup: {close_ex}")
|
||||
print(f"Error durante la limpieza de TIA Portal: {close_ex}")
|
||||
|
||||
print("\nScript finished.")
|
||||
print("\nScript finalizado.")
|
||||
|
|
|
@ -8,7 +8,7 @@ from tkinter import filedialog
|
|||
import os
|
||||
import sys
|
||||
import traceback
|
||||
from pathlib import Path # Import Path for easier path manipulation
|
||||
from pathlib import Path
|
||||
|
||||
script_root = os.path.dirname(
|
||||
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
@ -17,14 +17,19 @@ sys.path.append(script_root)
|
|||
from backend.script_utils import load_configuration
|
||||
|
||||
# --- Configuration ---
|
||||
TIA_PORTAL_VERSION = "18.0" # Target TIA Portal version (e.g., "18.0")
|
||||
# Supported TIA Portal versions mapping (extension -> version)
|
||||
SUPPORTED_TIA_VERSIONS = {
|
||||
".ap18": "18.0",
|
||||
".ap19": "19.0",
|
||||
".ap20": "20.0"
|
||||
}
|
||||
|
||||
# Filter for cross-references. Based on documentation:
|
||||
# 1: 'AllObjects', 2: 'ObjectsWithReferences', 3: 'ObjectsWithoutReferences', 4: 'UnusedObjects'
|
||||
# Using 1 to export all. 0 might also work as a default in some API versions.
|
||||
CROSS_REF_FILTER = 1
|
||||
|
||||
# --- TIA Scripting Import Handling ---
|
||||
# (Same import handling as x1.py)
|
||||
if os.getenv("TIA_SCRIPTING"):
|
||||
sys.path.append(os.getenv("TIA_SCRIPTING"))
|
||||
else:
|
||||
|
@ -33,209 +38,225 @@ else:
|
|||
try:
|
||||
import siemens_tia_scripting as ts
|
||||
except ImportError:
|
||||
print("ERROR: Failed to import 'siemens_tia_scripting'.")
|
||||
print("Ensure:")
|
||||
print(f"1. TIA Portal Openness for V{TIA_PORTAL_VERSION} is installed.")
|
||||
print("ERROR: Error al importar 'siemens_tia_scripting'.")
|
||||
print("Asegúrese de que:")
|
||||
print("1. TIA Portal Openness está instalado.")
|
||||
print(
|
||||
"2. The 'siemens_tia_scripting' Python module is installed (pip install ...) or"
|
||||
"2. El módulo 'siemens_tia_scripting' de Python está instalado (pip install ...) o"
|
||||
)
|
||||
print(
|
||||
" the path to its binaries is set in the 'TIA_SCRIPTING' environment variable."
|
||||
" la ruta a sus binarios está configurada en la variable de entorno 'TIA_SCRIPTING'."
|
||||
)
|
||||
print(
|
||||
"3. You are using a compatible Python version (e.g., 3.12.X as per documentation)."
|
||||
"3. Está usando una versión compatible de Python (ej. 3.12.X según la documentación)."
|
||||
)
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"An unexpected error occurred during import: {e}")
|
||||
print(f"Ocurrió un error inesperado durante la importación: {e}")
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
# --- Functions ---
|
||||
|
||||
def get_supported_filetypes():
|
||||
"""Returns the supported file types for TIA Portal projects."""
|
||||
filetypes = []
|
||||
for ext, version in SUPPORTED_TIA_VERSIONS.items():
|
||||
version_major = version.split('.')[0]
|
||||
filetypes.append((f"TIA Portal V{version_major} Projects", f"*{ext}"))
|
||||
|
||||
# Add option to show all supported files
|
||||
all_extensions = " ".join([f"*{ext}" for ext in SUPPORTED_TIA_VERSIONS.keys()])
|
||||
filetypes.insert(0, ("All TIA Portal Projects", all_extensions))
|
||||
|
||||
return filetypes
|
||||
|
||||
def detect_tia_version(project_file_path):
|
||||
"""Detects TIA Portal version based on file extension."""
|
||||
file_path = Path(project_file_path)
|
||||
file_extension = file_path.suffix.lower()
|
||||
|
||||
if file_extension in SUPPORTED_TIA_VERSIONS:
|
||||
detected_version = SUPPORTED_TIA_VERSIONS[file_extension]
|
||||
print(f"Versión de TIA Portal detectada: {detected_version} (de la extensión {file_extension})")
|
||||
return detected_version
|
||||
else:
|
||||
print(f"ADVERTENCIA: Extensión de archivo no reconocida '{file_extension}'. Extensiones soportadas: {list(SUPPORTED_TIA_VERSIONS.keys())}")
|
||||
# Default to version 18.0 for backward compatibility
|
||||
print("Usando por defecto TIA Portal V18.0")
|
||||
return "18.0"
|
||||
|
||||
def select_project_file():
|
||||
"""Opens a dialog to select a TIA Portal project file."""
|
||||
root = tk.Tk()
|
||||
root.withdraw() # Hide the main tkinter window
|
||||
root.withdraw()
|
||||
file_path = filedialog.askopenfilename(
|
||||
title="Select TIA Portal Project File",
|
||||
filetypes=[
|
||||
(
|
||||
f"TIA Portal V{TIA_PORTAL_VERSION} Projects",
|
||||
f"*.ap{TIA_PORTAL_VERSION.split('.')[0]}",
|
||||
)
|
||||
], # e.g. *.ap18
|
||||
title="Seleccionar archivo de proyecto TIA Portal",
|
||||
filetypes=get_supported_filetypes()
|
||||
)
|
||||
root.destroy()
|
||||
if not file_path:
|
||||
print("No project file selected. Exiting.")
|
||||
print("No se seleccionó ningún archivo de proyecto. Saliendo.")
|
||||
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."""
|
||||
plc_name = plc.get_name()
|
||||
print(f"\n--- Processing PLC: {plc_name} ---")
|
||||
print(f"\n--- Procesando PLC: {plc_name} ---")
|
||||
|
||||
# Define base export path for this PLC's cross-references
|
||||
plc_export_dir = export_base_dir / plc_name
|
||||
plc_export_dir.mkdir(parents=True, exist_ok=True) # Use pathlib's mkdir
|
||||
plc_export_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# --- Export Program Block Cross-References ---
|
||||
blocks_cr_exported = 0
|
||||
blocks_cr_skipped = 0
|
||||
print(f"\n[PLC: {plc_name}] Exporting Program Block Cross-References...")
|
||||
print(f"\n[PLC: {plc_name}] Exportando referencias cruzadas de bloques de programa...")
|
||||
blocks_cr_path = plc_export_dir / "ProgramBlocks_CR"
|
||||
blocks_cr_path.mkdir(exist_ok=True)
|
||||
print(f" Target: {blocks_cr_path}")
|
||||
print(f" Destino: {blocks_cr_path}")
|
||||
|
||||
try:
|
||||
# Assuming get_program_blocks() doesn't need folder_path to get all blocks
|
||||
program_blocks = plc.get_program_blocks()
|
||||
print(f" Found {len(program_blocks)} program blocks.")
|
||||
print(f" Se encontraron {len(program_blocks)} bloques de programa.")
|
||||
for block in program_blocks:
|
||||
block_name = block.get_name()
|
||||
print(f" Processing block: {block_name}...")
|
||||
print(f" Procesando bloque: {block_name}...")
|
||||
try:
|
||||
# Note: Consistency check might not be needed/available before cross-ref export
|
||||
print(f" Exporting cross-references for {block_name}...")
|
||||
print(f" Exportando referencias cruzadas para {block_name}...")
|
||||
block.export_cross_references(
|
||||
target_directorypath=str(
|
||||
blocks_cr_path
|
||||
), # API likely needs string path
|
||||
target_directorypath=str(blocks_cr_path),
|
||||
filter=CROSS_REF_FILTER,
|
||||
)
|
||||
blocks_cr_exported += 1
|
||||
except RuntimeError as block_ex:
|
||||
print(
|
||||
f" TIA ERROR exporting cross-references for block {block_name}: {block_ex}"
|
||||
f" ERROR TIA al exportar referencias cruzadas para el bloque {block_name}: {block_ex}"
|
||||
)
|
||||
blocks_cr_skipped += 1
|
||||
except Exception as block_ex:
|
||||
print(
|
||||
f" GENERAL ERROR exporting cross-references for block {block_name}: {block_ex}"
|
||||
f" ERROR GENERAL al exportar referencias cruzadas para el bloque {block_name}: {block_ex}"
|
||||
)
|
||||
traceback.print_exc() # Print stack trace for general errors
|
||||
traceback.print_exc()
|
||||
blocks_cr_skipped += 1
|
||||
print(
|
||||
f" Program Block CR Export Summary: Exported={blocks_cr_exported}, Skipped/Errors={blocks_cr_skipped}"
|
||||
f" Resumen de exportación de referencias cruzadas de bloques: Exportados={blocks_cr_exported}, Omitidos/Errores={blocks_cr_skipped}"
|
||||
)
|
||||
except AttributeError:
|
||||
print(
|
||||
" AttributeError: Could not find 'get_program_blocks' on PLC object. Skipping Program Blocks."
|
||||
" Error de atributo: No se pudo encontrar 'get_program_blocks' en el objeto PLC. Omitiendo bloques de programa."
|
||||
)
|
||||
except Exception as e:
|
||||
print(f" ERROR accessing Program Blocks for cross-reference export: {e}")
|
||||
print(f" ERROR al acceder a los bloques de programa para exportar referencias cruzadas: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
# --- Export PLC Tag Table Cross-References ---
|
||||
tags_cr_exported = 0
|
||||
tags_cr_skipped = 0
|
||||
print(f"\n[PLC: {plc_name}] Exporting PLC Tag Table Cross-References...")
|
||||
print(f"\n[PLC: {plc_name}] Exportando referencias cruzadas de tablas de variables...")
|
||||
tags_cr_path = plc_export_dir / "PlcTags_CR"
|
||||
tags_cr_path.mkdir(exist_ok=True)
|
||||
print(f" Target: {tags_cr_path}")
|
||||
print(f" Destino: {tags_cr_path}")
|
||||
|
||||
try:
|
||||
# Assuming get_plc_tag_tables() doesn't need folder_path to get all tables
|
||||
tag_tables = plc.get_plc_tag_tables()
|
||||
print(f" Found {len(tag_tables)} Tag Tables.")
|
||||
print(f" Se encontraron {len(tag_tables)} tablas de variables.")
|
||||
for table in tag_tables:
|
||||
table_name = table.get_name()
|
||||
print(f" Processing Tag Table: {table_name}...")
|
||||
print(f" Procesando tabla de variables: {table_name}...")
|
||||
try:
|
||||
print(f" Exporting cross-references for {table_name}...")
|
||||
print(f" Exportando referencias cruzadas para {table_name}...")
|
||||
table.export_cross_references(
|
||||
target_directorypath=str(tags_cr_path), filter=CROSS_REF_FILTER
|
||||
target_directorypath=str(tags_cr_path),
|
||||
filter=CROSS_REF_FILTER
|
||||
)
|
||||
tags_cr_exported += 1
|
||||
except RuntimeError as table_ex:
|
||||
print(
|
||||
f" TIA ERROR exporting cross-references for Tag Table {table_name}: {table_ex}"
|
||||
f" ERROR TIA al exportar referencias cruzadas para la tabla {table_name}: {table_ex}"
|
||||
)
|
||||
tags_cr_skipped += 1
|
||||
except Exception as table_ex:
|
||||
print(
|
||||
f" GENERAL ERROR exporting cross-references for Tag Table {table_name}: {table_ex}"
|
||||
f" ERROR GENERAL al exportar referencias cruzadas para la tabla {table_name}: {table_ex}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
tags_cr_skipped += 1
|
||||
print(
|
||||
f" Tag Table CR Export Summary: Exported={tags_cr_exported}, Skipped/Errors={tags_cr_skipped}"
|
||||
f" Resumen de exportación de referencias cruzadas de tablas: Exportados={tags_cr_exported}, Omitidos/Errores={tags_cr_skipped}"
|
||||
)
|
||||
except AttributeError:
|
||||
print(
|
||||
" AttributeError: Could not find 'get_plc_tag_tables' on PLC object. Skipping Tag Tables."
|
||||
" Error de atributo: No se pudo encontrar 'get_plc_tag_tables' en el objeto PLC. Omitiendo tablas de variables."
|
||||
)
|
||||
except Exception as e:
|
||||
print(f" ERROR accessing Tag Tables for cross-reference export: {e}")
|
||||
print(f" ERROR al acceder a las tablas de variables para exportar referencias cruzadas: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
# --- Export PLC Data Type (UDT) Cross-References ---
|
||||
udts_cr_exported = 0
|
||||
udts_cr_skipped = 0
|
||||
print(f"\n[PLC: {plc_name}] Exporting PLC Data Type (UDT) Cross-References...")
|
||||
print(f"\n[PLC: {plc_name}] Exportando referencias cruzadas de tipos de datos PLC (UDTs)...")
|
||||
udts_cr_path = plc_export_dir / "PlcDataTypes_CR"
|
||||
udts_cr_path.mkdir(exist_ok=True)
|
||||
print(f" Target: {udts_cr_path}")
|
||||
print(f" Destino: {udts_cr_path}")
|
||||
|
||||
try:
|
||||
# Assuming get_user_data_types() doesn't need folder_path to get all UDTs
|
||||
udts = plc.get_user_data_types()
|
||||
print(f" Found {len(udts)} UDTs.")
|
||||
print(f" Se encontraron {len(udts)} UDTs.")
|
||||
for udt in udts:
|
||||
udt_name = udt.get_name()
|
||||
print(f" Processing UDT: {udt_name}...")
|
||||
print(f" Procesando UDT: {udt_name}...")
|
||||
try:
|
||||
print(f" Exporting cross-references for {udt_name}...")
|
||||
print(f" Exportando referencias cruzadas para {udt_name}...")
|
||||
udt.export_cross_references(
|
||||
target_directorypath=str(udts_cr_path), filter=CROSS_REF_FILTER
|
||||
target_directorypath=str(udts_cr_path),
|
||||
filter=CROSS_REF_FILTER
|
||||
)
|
||||
udts_cr_exported += 1
|
||||
except RuntimeError as udt_ex:
|
||||
print(
|
||||
f" TIA ERROR exporting cross-references for UDT {udt_name}: {udt_ex}"
|
||||
f" ERROR TIA al exportar referencias cruzadas para el UDT {udt_name}: {udt_ex}"
|
||||
)
|
||||
udts_cr_skipped += 1
|
||||
except Exception as udt_ex:
|
||||
print(
|
||||
f" GENERAL ERROR exporting cross-references for UDT {udt_name}: {udt_ex}"
|
||||
f" ERROR GENERAL al exportar referencias cruzadas para el UDT {udt_name}: {udt_ex}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
udts_cr_skipped += 1
|
||||
print(
|
||||
f" UDT CR Export Summary: Exported={udts_cr_exported}, Skipped/Errors={udts_cr_skipped}"
|
||||
f" Resumen de exportación de referencias cruzadas de UDTs: Exportados={udts_cr_exported}, Omitidos/Errores={udts_cr_skipped}"
|
||||
)
|
||||
except AttributeError:
|
||||
print(
|
||||
" AttributeError: Could not find 'get_user_data_types' on PLC object. Skipping UDTs."
|
||||
" Error de atributo: No se pudo encontrar 'get_user_data_types' en el objeto PLC. Omitiendo UDTs."
|
||||
)
|
||||
except Exception as e:
|
||||
print(f" ERROR accessing UDTs for cross-reference export: {e}")
|
||||
print(f" ERROR al acceder a los UDTs para exportar referencias cruzadas: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
# --- Export System Block Cross-References ---
|
||||
sys_blocks_cr_exported = 0
|
||||
sys_blocks_cr_skipped = 0
|
||||
print(f"\n[PLC: {plc_name}] Attempting to Export System Block Cross-References...")
|
||||
print(f"\n[PLC: {plc_name}] Intentando exportar referencias cruzadas de bloques de sistema...")
|
||||
sys_blocks_cr_path = plc_export_dir / "SystemBlocks_CR"
|
||||
sys_blocks_cr_path.mkdir(exist_ok=True)
|
||||
print(f" Target: {sys_blocks_cr_path}")
|
||||
print(f" Destino: {sys_blocks_cr_path}")
|
||||
|
||||
try:
|
||||
# Check if method exists before calling
|
||||
if hasattr(plc, "get_system_blocks"):
|
||||
system_blocks = plc.get_system_blocks()
|
||||
print(
|
||||
f" Found {len(system_blocks)} system blocks (using get_system_blocks)."
|
||||
f" Se encontraron {len(system_blocks)} bloques de sistema."
|
||||
)
|
||||
for sys_block in system_blocks:
|
||||
sys_block_name = sys_block.get_name()
|
||||
print(f" Processing System Block: {sys_block_name}...")
|
||||
print(f" Procesando bloque de sistema: {sys_block_name}...")
|
||||
try:
|
||||
print(f" Exporting cross-references for {sys_block_name}...")
|
||||
print(f" Exportando referencias cruzadas para {sys_block_name}...")
|
||||
sys_block.export_cross_references(
|
||||
target_directorypath=str(sys_blocks_cr_path),
|
||||
filter=CROSS_REF_FILTER,
|
||||
|
@ -243,53 +264,51 @@ def export_plc_cross_references(plc, export_base_dir):
|
|||
sys_blocks_cr_exported += 1
|
||||
except RuntimeError as sys_ex:
|
||||
print(
|
||||
f" TIA ERROR exporting cross-references for System Block {sys_block_name}: {sys_ex}"
|
||||
f" ERROR TIA al exportar referencias cruzadas para el bloque de sistema {sys_block_name}: {sys_ex}"
|
||||
)
|
||||
sys_blocks_cr_skipped += 1
|
||||
except Exception as sys_ex:
|
||||
print(
|
||||
f" GENERAL ERROR exporting cross-references for System Block {sys_block_name}: {sys_ex}"
|
||||
f" ERROR GENERAL al exportar referencias cruzadas para el bloque de sistema {sys_block_name}: {sys_ex}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
sys_blocks_cr_skipped += 1
|
||||
else:
|
||||
print(
|
||||
" Method 'get_system_blocks' not found on PLC object. Skipping System Blocks."
|
||||
" Método 'get_system_blocks' no encontrado en el objeto PLC. Omitiendo bloques de sistema."
|
||||
)
|
||||
# Alternative: Try navigating DeviceItems if needed, but that's more complex.
|
||||
|
||||
print(
|
||||
f" System Block CR Export Summary: Exported={sys_blocks_cr_exported}, Skipped/Errors={sys_blocks_cr_skipped}"
|
||||
f" Resumen de exportación de referencias cruzadas de bloques de sistema: Exportados={sys_blocks_cr_exported}, Omitidos/Errores={sys_blocks_cr_skipped}"
|
||||
)
|
||||
except AttributeError: # Catch if get_name() or other methods fail on sys_block
|
||||
except AttributeError:
|
||||
print(
|
||||
" AttributeError during System Block processing. Skipping remaining System Blocks."
|
||||
" Error de atributo durante el procesamiento de bloques de sistema. Omitiendo bloques de sistema restantes."
|
||||
)
|
||||
traceback.print_exc()
|
||||
except Exception as e:
|
||||
print(
|
||||
f" ERROR accessing/processing System Blocks for cross-reference export: {e}"
|
||||
f" ERROR al acceder/procesar bloques de sistema para exportar referencias cruzadas: {e}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
|
||||
# --- Export Software Unit Cross-References ---
|
||||
sw_units_cr_exported = 0
|
||||
sw_units_cr_skipped = 0
|
||||
print(f"\n[PLC: {plc_name}] Attempting to Export Software Unit Cross-References...")
|
||||
print(f"\n[PLC: {plc_name}] Intentando exportar referencias cruzadas de unidades de software...")
|
||||
sw_units_cr_path = plc_export_dir / "SoftwareUnits_CR"
|
||||
sw_units_cr_path.mkdir(exist_ok=True)
|
||||
print(f" Target: {sw_units_cr_path}")
|
||||
print(f" Destino: {sw_units_cr_path}")
|
||||
|
||||
try:
|
||||
# Check if method exists before calling
|
||||
if hasattr(plc, "get_software_units"):
|
||||
software_units = plc.get_software_units()
|
||||
print(f" Found {len(software_units)} Software Units.")
|
||||
print(f" Se encontraron {len(software_units)} unidades de software.")
|
||||
for unit in software_units:
|
||||
unit_name = unit.get_name()
|
||||
print(f" Processing Software Unit: {unit_name}...")
|
||||
print(f" Procesando unidad de software: {unit_name}...")
|
||||
try:
|
||||
print(f" Exporting cross-references for {unit_name}...")
|
||||
print(f" Exportando referencias cruzadas para {unit_name}...")
|
||||
unit.export_cross_references(
|
||||
target_directorypath=str(sw_units_cr_path),
|
||||
filter=CROSS_REF_FILTER,
|
||||
|
@ -297,35 +316,34 @@ def export_plc_cross_references(plc, export_base_dir):
|
|||
sw_units_cr_exported += 1
|
||||
except RuntimeError as unit_ex:
|
||||
print(
|
||||
f" TIA ERROR exporting cross-references for Software Unit {unit_name}: {unit_ex}"
|
||||
f" ERROR TIA al exportar referencias cruzadas para la unidad de software {unit_name}: {unit_ex}"
|
||||
)
|
||||
sw_units_cr_skipped += 1
|
||||
except Exception as unit_ex:
|
||||
print(
|
||||
f" GENERAL ERROR exporting cross-references for Software Unit {unit_name}: {unit_ex}"
|
||||
f" ERROR GENERAL al exportar referencias cruzadas para la unidad de software {unit_name}: {unit_ex}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
sw_units_cr_skipped += 1
|
||||
print(
|
||||
f" Software Unit CR Export Summary: Exported={sw_units_cr_exported}, Skipped/Errors={sw_units_cr_skipped}"
|
||||
f" Resumen de exportación de referencias cruzadas de unidades de software: Exportados={sw_units_cr_exported}, Omitidos/Errores={sw_units_cr_skipped}"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
" Method 'get_software_units' not found on PLC object. Skipping Software Units."
|
||||
" Método 'get_software_units' no encontrado en el objeto PLC. Omitiendo unidades de software."
|
||||
)
|
||||
except AttributeError: # Catch if get_name() or other methods fail on unit
|
||||
except AttributeError:
|
||||
print(
|
||||
" AttributeError during Software Unit processing. Skipping remaining Software Units."
|
||||
" Error de atributo durante el procesamiento de unidades de software. Omitiendo unidades restantes."
|
||||
)
|
||||
traceback.print_exc()
|
||||
except Exception as e:
|
||||
print(
|
||||
f" ERROR accessing/processing Software Units for cross-reference export: {e}"
|
||||
f" ERROR al acceder/procesar unidades de software para exportar referencias cruzadas: {e}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
|
||||
print(f"\n--- Finished processing PLC: {plc_name} ---")
|
||||
|
||||
print(f"\n--- Finalizado el procesamiento del PLC: {plc_name} ---")
|
||||
|
||||
# --- Main Script ---
|
||||
|
||||
|
@ -333,90 +351,90 @@ if __name__ == "__main__":
|
|||
configs = load_configuration()
|
||||
working_directory = configs.get("working_directory")
|
||||
|
||||
print("--- TIA Portal Cross-Reference Exporter ---")
|
||||
print("--- Exportador de Referencias Cruzadas de TIA Portal ---")
|
||||
|
||||
# Validate working directory
|
||||
if not working_directory or not os.path.isdir(working_directory):
|
||||
print("ERROR: Working directory not set or invalid in configuration.")
|
||||
print("Please configure the working directory using the main application.")
|
||||
print("ERROR: Directorio de trabajo no configurado o inválido.")
|
||||
print("Por favor configure el directorio de trabajo usando la aplicación principal.")
|
||||
sys.exit(1)
|
||||
|
||||
# 1. Select Project File
|
||||
project_file = select_project_file()
|
||||
|
||||
# 2. Define Export Directory using working_directory and subfolder
|
||||
# The export base directory is the working directory. PLC-specific folders will be created inside.
|
||||
# 2. Detect TIA Portal version from project file
|
||||
tia_version = detect_tia_version(project_file)
|
||||
|
||||
# 3. Define Export Directory using working_directory and subfolder
|
||||
export_base_dir = Path(working_directory)
|
||||
try:
|
||||
# Ensure the base working directory exists (it should, but check doesn't hurt)
|
||||
export_base_dir.mkdir(parents=True, exist_ok=True)
|
||||
print(f"\nSelected Project: {project_file}")
|
||||
print(f"Using Base Export Directory: {export_base_dir.resolve()}")
|
||||
print(f"\nProyecto seleccionado: {project_file}")
|
||||
print(f"Usando directorio base de exportación: {export_base_dir.resolve()}")
|
||||
except Exception as e:
|
||||
print(f"ERROR: Could not create export directory '{export_dir}'. Error: {e}")
|
||||
print(f"ERROR: No se pudo crear el directorio de exportación '{export_base_dir}'. Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
portal_instance = None
|
||||
project_object = None
|
||||
|
||||
try:
|
||||
# 3. Connect to TIA Portal
|
||||
print(f"\nConnecting to TIA Portal V{TIA_PORTAL_VERSION}...")
|
||||
# Connect using WithGraphicalUserInterface mode for visibility
|
||||
# 4. Connect to TIA Portal with detected version
|
||||
print(f"\nConectando a TIA Portal V{tia_version}...")
|
||||
portal_instance = ts.open_portal(
|
||||
version=TIA_PORTAL_VERSION,
|
||||
version=tia_version,
|
||||
portal_mode=ts.Enums.PortalMode.WithGraphicalUserInterface,
|
||||
)
|
||||
print("Connected to TIA Portal.")
|
||||
print(f"Portal Process ID: {portal_instance.get_process_id()}")
|
||||
print("Conectado a TIA Portal.")
|
||||
print(f"ID del proceso del Portal: {portal_instance.get_process_id()}")
|
||||
|
||||
# 4. Open Project
|
||||
print(f"Opening project: {os.path.basename(project_file)}...")
|
||||
project_path_obj = Path(project_file) # Use Path object
|
||||
# 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("Project might already be open, attempting to get handle...")
|
||||
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("Failed to open or get the specified project.")
|
||||
print("Project opened successfully.")
|
||||
raise Exception("No se pudo abrir u obtener el proyecto especificado.")
|
||||
print("Proyecto abierto exitosamente.")
|
||||
|
||||
# 5. Get PLCs
|
||||
# 6. Get PLCs
|
||||
plcs = project_object.get_plcs()
|
||||
if not plcs:
|
||||
print("No PLC devices found in the project.")
|
||||
print("No se encontraron dispositivos PLC en el proyecto.")
|
||||
else:
|
||||
print(
|
||||
f"Found {len(plcs)} PLC(s). Starting cross-reference export process..."
|
||||
f"Se encontraron {len(plcs)} PLC(s). Iniciando proceso de exportación de referencias cruzadas..."
|
||||
)
|
||||
|
||||
# 6. Iterate and Export Cross-References for each PLC
|
||||
# 7. Iterate and Export Cross-References for each PLC
|
||||
for plc_device in plcs:
|
||||
export_plc_cross_references(
|
||||
plc=plc_device,
|
||||
export_base_dir=export_base_dir, # Pass the base directory
|
||||
export_base_dir=export_base_dir,
|
||||
)
|
||||
|
||||
print("\nCross-reference export process completed.")
|
||||
print("\nProceso de exportación de referencias cruzadas completado.")
|
||||
|
||||
except RuntimeError as tia_ex:
|
||||
print(f"\nTIA Portal Openness Error: {tia_ex}")
|
||||
print(f"\nError de TIA Portal Openness: {tia_ex}")
|
||||
traceback.print_exc()
|
||||
except FileNotFoundError:
|
||||
print(f"\nERROR: Project file not found at {project_file}")
|
||||
print(f"\nERROR: Archivo de proyecto no encontrado en {project_file}")
|
||||
except Exception as e:
|
||||
print(f"\nAn unexpected error occurred: {e}")
|
||||
print(f"\nOcurrió un error inesperado: {e}")
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
# 7. Cleanup
|
||||
# 8. Cleanup
|
||||
if portal_instance:
|
||||
try:
|
||||
print("\nClosing TIA Portal...")
|
||||
print("\nCerrando TIA Portal...")
|
||||
portal_instance.close_portal()
|
||||
print("TIA Portal closed.")
|
||||
print("TIA Portal cerrado.")
|
||||
except Exception as close_ex:
|
||||
print(f"Error during TIA Portal cleanup: {close_ex}")
|
||||
print(f"Error durante la limpieza de TIA Portal: {close_ex}")
|
||||
|
||||
print("\nScript finished.")
|
||||
print("\nScript finalizado.")
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"block_name": "FC General Lamp",
|
||||
"block_number": 172,
|
||||
"language": "LAD",
|
||||
"block_type": "FC",
|
||||
"block_comment": "",
|
||||
"interface": {
|
||||
"Return": [
|
||||
{
|
||||
"name": "Ret_Val",
|
||||
"datatype": "Void",
|
||||
"remanence": "NonRetain",
|
||||
"accessibility": "Public",
|
||||
"start_value": null,
|
||||
"comment": null,
|
||||
"children": [],
|
||||
"array_elements": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": [
|
||||
{
|
||||
"id": "4",
|
||||
"title": "Lamp Alarm - Q.E. - Light Green",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "B",
|
||||
"title": "Lamp Alarm - Q.E. - Light Red",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "12",
|
||||
"title": "Lamp Alarm - Q.E. - Buzzer",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "19",
|
||||
"title": "Lamp Alarm - Q.E. - Light Blue",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "20",
|
||||
"title": "Lamp - Alarm Presence",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "27",
|
||||
"title": "Light Signal Phased Stop Machine",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "2E",
|
||||
"title": "",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
}
|
||||
],
|
||||
"source_xml_mod_time": 1749751920.2702959,
|
||||
"source_xml_size": 39346
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"block_name": "FC General Lamp",
|
||||
"block_number": 172,
|
||||
"language": "LAD",
|
||||
"block_type": "FC",
|
||||
"block_comment": "",
|
||||
"interface": {
|
||||
"Return": [
|
||||
{
|
||||
"name": "Ret_Val",
|
||||
"datatype": "Void",
|
||||
"remanence": "NonRetain",
|
||||
"accessibility": "Public",
|
||||
"start_value": null,
|
||||
"comment": null,
|
||||
"children": [],
|
||||
"array_elements": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": [
|
||||
{
|
||||
"id": "4",
|
||||
"title": "Lamp Alarm - Q.E. - Light Green",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "B",
|
||||
"title": "Lamp Alarm - Q.E. - Light Red",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "12",
|
||||
"title": "Lamp Alarm - Q.E. - Buzzer",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "19",
|
||||
"title": "Lamp Alarm - Q.E. - Light Blue",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "20",
|
||||
"title": "Lamp - Alarm Presence",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "27",
|
||||
"title": "Light Signal Phased Stop Machine",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
},
|
||||
{
|
||||
"id": "2E",
|
||||
"title": "",
|
||||
"comment": "",
|
||||
"language": "LAD",
|
||||
"logic": [],
|
||||
"error": "FlgNet not found inside NetworkSource or CompileUnit"
|
||||
}
|
||||
],
|
||||
"source_xml_mod_time": 1749751920.2702959,
|
||||
"source_xml_size": 39346
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,455 @@
|
|||
// Block Type: FC
|
||||
// Block Name (Original): FC Ttop Motor M31010
|
||||
// Block Number: 327
|
||||
// Original Network Languages: LAD, SCL
|
||||
|
||||
FUNCTION "FC_Ttop_Motor_M31010" : Void
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
VERSION : 0.1
|
||||
|
||||
VAR_INOUT
|
||||
Motor : STRUCT
|
||||
RCP_Speed_Fix_01 : Int;
|
||||
RCP_Speed_Fix_02 : Int;
|
||||
RCP_Speed_Fix_03 : Int;
|
||||
RCP_Speed_Fix_04 : Int;
|
||||
RCP_Speed_Fix_05 : Int;
|
||||
RCP_Speed_Sync_01 : Int;
|
||||
RCP_Speed_Sync_02 : Int;
|
||||
RCP_Speed_Sync_03 : Int;
|
||||
RCP_Speed_Sync_04 : Int;
|
||||
RCP_Speed_Sync_05 : Int;
|
||||
RCP_Timer_01 : Int;
|
||||
RCP_Timer_02 : Int;
|
||||
RCP_Timer_03 : Int;
|
||||
RCP_Timer_04 : Int;
|
||||
RCP_Timer_05 : Int;
|
||||
RCP_Speed_Fix_01_mBar : Int;
|
||||
RCP_Speed_Fix_02_mBar : Int;
|
||||
RCP_Speed_Fix_03_mBar : Int;
|
||||
RCP_Speed_Fix_04_mBar : Int;
|
||||
RCP_Speed_Fix_05_mBar : Int;
|
||||
RCP_ACC_Ramp : Int;
|
||||
RCP_DEC_Ramp : Int;
|
||||
RCP_W044 : Int;
|
||||
RCP_W046 : Int;
|
||||
RCP_W048 : Int;
|
||||
CFG_VFD : Bool;
|
||||
CFG_DP : Bool;
|
||||
CFG_Analog_Speed : Bool;
|
||||
CFG_EN_BWD : Bool;
|
||||
CFG_Reverse : Bool;
|
||||
CFG_Motor_N_Sel : Bool;
|
||||
CFG_PN : Bool;
|
||||
CFG_X050_7 : Bool;
|
||||
CFG_TH_CTR_Single : Bool;
|
||||
CFG_SW_CTR_Single : Bool;
|
||||
CFG_TRIP_CTR_Single : Bool;
|
||||
CFG_Speed_User : Bool;
|
||||
CFG_mBar : Bool;
|
||||
CFG_SW_CTR_OnOff : Bool;
|
||||
CFG_Plug_CTR_Single : Bool;
|
||||
CFG_X051_7 : Bool;
|
||||
CFG_Min_Speed_Hz : Int;
|
||||
CFG_Max_Speed_Hz : Int;
|
||||
CFG_mBar_Type : Byte;
|
||||
CFG_B57 : Byte;
|
||||
CFG_Max_mBar : Int;
|
||||
CFG_EOLO_Zone : Bool;
|
||||
CFG_TableTop_Zone : Bool;
|
||||
CFG_Pack_Zone : Bool;
|
||||
CFG_VIS_Sp_User_Step200 : Bool;
|
||||
CFG_X060_4 : Bool;
|
||||
CFG_X060_5 : Bool;
|
||||
CFG_X060_6 : Bool;
|
||||
CFG_X060_7 : Bool;
|
||||
CFG_MPrew : Int;
|
||||
CFG_MNext : Int;
|
||||
CFG_DBExternal1 : Int;
|
||||
CFG_DBExternal2 : Int;
|
||||
CFG_Vis_Fix_00 : Bool;
|
||||
CFG_VIS_Fix_01 : Bool;
|
||||
CFG_VIS_Fix_02 : Bool;
|
||||
CFG_VIS_Fix_03 : Bool;
|
||||
CFG_VIS_Fix_04 : Bool;
|
||||
CFG_VIS_Fix_05 : Bool;
|
||||
CFG_VIS_Fix_06 : Bool;
|
||||
CFG_VIS_Fix_07 : Bool;
|
||||
CFG_VIS_Sync_00 : Bool;
|
||||
CFG_VIS_Sync_01 : Bool;
|
||||
CFG_VIS_Sync_02 : Bool;
|
||||
CFG_VIS_Sync_03 : Bool;
|
||||
CFG_VIS_Sync_04 : Bool;
|
||||
CFG_VIS_Sync_05 : Bool;
|
||||
CFG_VIS_Sync_06 : Bool;
|
||||
CFG_VIS_Sync_07 : Bool;
|
||||
CFG_VIS_Timer_00 : Bool;
|
||||
CFG_VIS_Timer_01 : Bool;
|
||||
CFG_VIS_Timer_02 : Bool;
|
||||
CFG_VIS_Timer_03 : Bool;
|
||||
CFG_VIS_Timer_04 : Bool;
|
||||
CFG_VIS_Timer_05 : Bool;
|
||||
CFG_VIS_Timer_06 : Bool;
|
||||
CFG_VIS_Timer_07 : Bool;
|
||||
CFG_VIS_SA : Bool;
|
||||
CFG_VIS_SB : Bool;
|
||||
CFG_VIS_SC : Bool;
|
||||
CFG_VIS_SD : Bool;
|
||||
CFG_VIS_BA : Bool;
|
||||
CFG_VIS_BB : Bool;
|
||||
CFG_VIS_EXTA : Bool;
|
||||
CFG_VIS_EXTB : Bool;
|
||||
CFG_VIS_SW : Bool;
|
||||
CFG_VIS_TH : Bool;
|
||||
CFG_VIS_TRIP : Bool;
|
||||
CFG_VIS_PAW : Bool;
|
||||
CFG_VIS_RUN_FWD : Bool;
|
||||
CFG_VIS_RUN_BWD : Bool;
|
||||
CFG_VIS_Kspeed : Bool;
|
||||
CFG_VIS_PLUG : Bool;
|
||||
CFG_VIS_PB_Auto : Bool;
|
||||
CFG_VIS_PB_Man : Bool;
|
||||
CFG_VIS_PB_Jog : Bool;
|
||||
CFG_VIS_PB_Stop : Bool;
|
||||
CFG_VIS_PB_Reverse : Bool;
|
||||
CFG_VIS_PB_sp_05 : Bool;
|
||||
CFG_VIS_PB_sp_06 : Bool;
|
||||
CFG_VIS_ManSpeed : Bool;
|
||||
CFG_VIS_ACT_Torque : Bool;
|
||||
CFG_VIS_ACC_Ramp : Bool;
|
||||
CFG_VIS_DEC_Ramp : Bool;
|
||||
CFG_VIS_X76_3 : Bool;
|
||||
CFG_VIS_X76_4 : Bool;
|
||||
CFG_VIS_X76_5 : Bool;
|
||||
CFG_VIS_X76_6 : Bool;
|
||||
CFG_VIS_X76 : Bool;
|
||||
CFG_B77 : Byte;
|
||||
CFG_W078 : Int;
|
||||
CFG_Add_Signal_SA : UInt;
|
||||
CFG_Add_Signal_SB : UInt;
|
||||
CFG_Add_Signal_SC : UInt;
|
||||
CFG_Add_Signal_SD : UInt;
|
||||
CFG_Add_Signal_BA : UInt;
|
||||
CFG_Add_Signal_BB : UInt;
|
||||
CFG_Add_Signal_EXTA : UInt;
|
||||
CFG_Add_Signal_EXTB : UInt;
|
||||
CFG_Add_Signal_SW : UInt;
|
||||
CFG_Add_Signal_TH : UInt;
|
||||
CFG_Add_Signal_TRIP : UInt;
|
||||
CFG_Add_Signal_PAW : Int;
|
||||
CFG_Add_Signal_RUN_FWD : UInt;
|
||||
CFG_Add_Signal_RUN_BWD : UInt;
|
||||
CFG_Add_Signal_mBar : Int;
|
||||
CFG_Add_Signal_PLUG : Int;
|
||||
CFG_Add_Signal_SP02 : Int;
|
||||
CFG_DB_Machine : Int;
|
||||
CFG_DB_NextMotor : Int;
|
||||
CFG_W118 : Int;
|
||||
CFG_Stop_Empty : Bool;
|
||||
CFG_Stop_Full : Bool;
|
||||
CFG_Stop_STBY : Bool;
|
||||
CFG_Pressurization : Bool;
|
||||
CFG_EOLO_Press_Speed : Int;
|
||||
Spare_124 : Array[124..145] of Byte;
|
||||
CFG_Motor_N : DInt;
|
||||
CFG_Phylosopy_N : Int;
|
||||
CFG_Motor_HW_IO : "HW_IO";
|
||||
CFG_Node_N : Int;
|
||||
CFG_Inverter_Type : Int;
|
||||
CFG_W158 : Int;
|
||||
CFG_Kspeed_User50Hz : Int;
|
||||
CFG_Min_Speed_User : Int;
|
||||
CFG_Max_Speed_User : Int;
|
||||
CFG_W166 : Int;
|
||||
CFG_W168 : Int;
|
||||
CFG_EN_mBar_FCT : Bool;
|
||||
CFG_EN_mBar_FilterALM : Bool;
|
||||
CFG_Isteresi_mBar : Int;
|
||||
CFG_Gain_Mbar : Int;
|
||||
CFG_Max_Speed_FilterALM : Int;
|
||||
CFG_W178 : Int;
|
||||
CFG_T_Gain : STRUCT
|
||||
S : Bool;
|
||||
Q : Bool;
|
||||
TW : Int;
|
||||
ST : Int;
|
||||
ACT : Int;
|
||||
W008 : Int;
|
||||
END_STRUCT;
|
||||
|
||||
CFG_T_FilterALM : STRUCT
|
||||
S : Bool;
|
||||
Q : Bool;
|
||||
TW : Int;
|
||||
ST : Int;
|
||||
ACT : Int;
|
||||
W008 : Int;
|
||||
END_STRUCT;
|
||||
|
||||
IN_PB_Start : Bool;
|
||||
IN_PB_Stop : Bool;
|
||||
IN_PB_Reset : Bool;
|
||||
IN_PB_Silence : Bool;
|
||||
IN_X200_4 : Bool;
|
||||
IN_X200_5 : Bool;
|
||||
IN_X200_6 : Bool;
|
||||
IN_X200_7 : Bool;
|
||||
IN_KG_PowerON : Bool;
|
||||
IN_SW_ManAuto : Bool;
|
||||
IN_Cycle_ON : Bool;
|
||||
IN_X201_3 : Bool;
|
||||
IN_X201_4 : Bool;
|
||||
IN_X201_5 : Bool;
|
||||
IN_X201_6 : Bool;
|
||||
IN_X201_7 : Bool;
|
||||
IN_SW_HMI_Auto : Bool;
|
||||
IN_SW_HMI_Man : Bool;
|
||||
IN_SW_HMI_Jog : Bool;
|
||||
IN_SW_HMI_Stop : Bool;
|
||||
IN_SW_HMI_Reverse : Bool;
|
||||
IN_SW_HMI_sp_05 : Bool;
|
||||
IN_SW_HMI_sp_06 : Bool;
|
||||
IN_SW_HMI_ManSpeed : Bool;
|
||||
IN_SW_HMI_sp_08 : Bool;
|
||||
IN_SW_HMI_VVFix1 : Bool;
|
||||
IN_SW_HMI_VVFix2 : Bool;
|
||||
IN_SW_HMI_VVFix3 : Bool;
|
||||
IN_SW_HMI_VVFix4 : Bool;
|
||||
IN_SW_HMI_VVFix5 : Bool;
|
||||
IN_SW_HMI_sp_14 : Bool;
|
||||
IN_SW_HMI_sp_15 : Bool;
|
||||
IN_HMI_ManSpeed : Int;
|
||||
IN_Signal_SA : Bool;
|
||||
IN_Signal_SB : Bool;
|
||||
IN_Signal_SC : Bool;
|
||||
IN_Signal_SD : Bool;
|
||||
IN_Signal_BA : Bool;
|
||||
IN_Signal_BB : Bool;
|
||||
IN_Signal_EXTA : Bool;
|
||||
IN_Signal_EXTB : Bool;
|
||||
IN_Signal_SW : Bool;
|
||||
IN_Signal_TH : Bool;
|
||||
IN_Signal_TRIP : Bool;
|
||||
IN_Signal_RUN_FWD : Bool;
|
||||
IN_Signal_RUN_BWD : Bool;
|
||||
IN_Signal_sp_05 : Bool;
|
||||
IN_Signal_sp_06 : Bool;
|
||||
IN_Signal_PLUG : Bool;
|
||||
IN_Signal_sp_08 : Int;
|
||||
IN_Signal_PEW_mBar : Int;
|
||||
IN_Signal_mBar : Int;
|
||||
IN_Motor_DI : "Struct";
|
||||
IN_W216 : Int;
|
||||
IN_W218 : Int;
|
||||
IN_Line_Empty : Bool;
|
||||
IN_Line_Full : Bool;
|
||||
IN_Line_StandBy : Bool;
|
||||
Spare_222 : Array[222..249] of Byte;
|
||||
OUT_VFD_Run_FWD : Bool;
|
||||
OUT_VFD_Run_BWD : Bool;
|
||||
OUT_VFD_Reverse : Bool;
|
||||
OUT_VFD_Qstop : Bool;
|
||||
OUT_VFD_Reset : Bool;
|
||||
OUT_X250_5 : Bool;
|
||||
OUT_X250_6 : Bool;
|
||||
OUT_EnergySavingON : Bool;
|
||||
OUT_VFD_REQ_Speed_Hz : Int;
|
||||
OUT_VFD_REQ_Speed_User : Int;
|
||||
OUT_VFD_ACT_Sync_Speed : Int;
|
||||
OUT_VFD_REQ_Speed_mBar : Int;
|
||||
OUT_Motor_DO : "Struct";
|
||||
OUT_W262 : Int;
|
||||
OUT_W264 : Int;
|
||||
OUT_W266 : Int;
|
||||
OUT_W268 : Int;
|
||||
STATUS_VFD_Run_FWD : Bool;
|
||||
STATUS_VFD_Run_BWD : Bool;
|
||||
STATUS_VFD_Trip : Bool;
|
||||
STATUS_VFD_Warning : Bool;
|
||||
STATUS_Ready : Bool;
|
||||
STATUS_VFD_Ready : Bool;
|
||||
STATUS_VFD_Coasting : Bool;
|
||||
STATUS_X270_7 : Bool;
|
||||
STATUS_VFD_ACT_Speed_Hz : Int;
|
||||
STATUS_VFD_ACT_Speed_Use : Int;
|
||||
STATUS_VFD_ACT_Torque : Int;
|
||||
STATUS_MainFault_MovigearADV : Byte;
|
||||
STATUS_Subfault_MovigearADV : Byte;
|
||||
STATUS_W280 : Int;
|
||||
STATUS_W282 : Int;
|
||||
STATUS_PWR_OFF : Bool;
|
||||
STATUS_CYCLE_OFF : Bool;
|
||||
STATUS_ALARM : Bool;
|
||||
STATUS_AUTO : Bool;
|
||||
STATUS_MAN : Bool;
|
||||
STATUS_JOG : Bool;
|
||||
STATUS_STOP : Bool;
|
||||
STATUS_X284_7 : Bool;
|
||||
STATUS_X285_0 : Bool;
|
||||
STATUS_X285_1 : Bool;
|
||||
STATUS_X285_2 : Bool;
|
||||
STATUS_X285_3 : Bool;
|
||||
STATUS_X285_4 : Bool;
|
||||
STATUS_X285_5 : Bool;
|
||||
STATUS_X285_6 : Bool;
|
||||
STATUS_X285_7 : Bool;
|
||||
STATUS_NOTRUN : Bool;
|
||||
STATUS_RUN : Bool;
|
||||
STATUS_X286_2 : Bool;
|
||||
STATUS_X286_3 : Bool;
|
||||
STATUS_X286_4 : Bool;
|
||||
STATUS_X286_5 : Bool;
|
||||
STATUS_X286_6 : Bool;
|
||||
STATUS_X286_7 : Bool;
|
||||
Spare_288 : Array[288..289] of Byte;
|
||||
Alarm_09 : Bool;
|
||||
Alarm_10 : Bool;
|
||||
Alarm_11 : Bool;
|
||||
Alarm_12 : Bool;
|
||||
Alarm_13 : Bool;
|
||||
Alarm_14 : Bool;
|
||||
Alarm_15 : Bool;
|
||||
Alarm_16 : Bool;
|
||||
Alarm_01 : Bool;
|
||||
Alarm_02 : Bool;
|
||||
Alarm_03 : Bool;
|
||||
Alarm_04 : Bool;
|
||||
Alarm_05 : Bool;
|
||||
Alarm_06 : Bool;
|
||||
Alarm_07 : Bool;
|
||||
Alarm_08 : Bool;
|
||||
Spare_292 : Array[292..299] of Byte;
|
||||
M_Power_ON : Bool;
|
||||
M_Cycle_ON_AUTO : Bool;
|
||||
M_Cycle_ON_MAN : Bool;
|
||||
M_W302 : Int;
|
||||
M_W304 : Int;
|
||||
M_W306 : Int;
|
||||
M_W308 : Int;
|
||||
M_Delay_Cycle_ON_Auto : STRUCT
|
||||
S : Bool;
|
||||
Q : Bool;
|
||||
TW : Int;
|
||||
ST : Int;
|
||||
ACT : Int;
|
||||
W008 : Int;
|
||||
END_STRUCT;
|
||||
|
||||
Spare_320 : Array[320..349] of Byte;
|
||||
REQ_EN_Run : Bool;
|
||||
REQ_Start_FWD : Bool;
|
||||
REQ_Start_BWD : Bool;
|
||||
REQ_QStop : Bool;
|
||||
REQ_X350_4 : Bool;
|
||||
REQ_X350_5 : Bool;
|
||||
REQ_X350_6 : Bool;
|
||||
REQ_X350_7 : Bool;
|
||||
REQ_X351_0 : Bool;
|
||||
REQ_X351_1 : Bool;
|
||||
REQ_X351_2 : Bool;
|
||||
REQ_X351_3 : Bool;
|
||||
REQ_X351_4 : Bool;
|
||||
REQ_X351_5 : Bool;
|
||||
REQ_X351_6 : Bool;
|
||||
REQ_X351_7 : Bool;
|
||||
REQ_W352 : Int;
|
||||
REQ_Master_Speed_Sync : Int;
|
||||
REQ_W356 : Int;
|
||||
REQ_Speed_Fix_00_NU : Bool;
|
||||
REQ_Speed_Fix_01 : Bool;
|
||||
REQ_Speed_Fix_02 : Bool;
|
||||
REQ_Speed_Fix_03 : Bool;
|
||||
REQ_Speed_Fix_04 : Bool;
|
||||
REQ_Speed_Fix_05 : Bool;
|
||||
REQ_Speed_Fix_06_NU : Bool;
|
||||
REQ_Speed_Fix_07_NU : Bool;
|
||||
REQ_Speed_Sync_00_NU : Bool;
|
||||
REQ_Speed_Sync_01 : Bool;
|
||||
REQ_Speed_Sync_02 : Bool;
|
||||
REQ_Speed_Sync_03 : Bool;
|
||||
REQ_Speed_Sync_04 : Bool;
|
||||
REQ_Speed_Sync_05 : Bool;
|
||||
REQ_Speed_Sync_06_NU : Bool;
|
||||
REQ_Speed_Sync_07_NU : Bool;
|
||||
REQ_T01 : STRUCT
|
||||
S : Bool;
|
||||
Q : Bool;
|
||||
TW : Int;
|
||||
ST : Int;
|
||||
ACT : Int;
|
||||
W008 : Int;
|
||||
END_STRUCT;
|
||||
|
||||
REQ_T02 : STRUCT
|
||||
S : Bool;
|
||||
Q : Bool;
|
||||
TW : Int;
|
||||
ST : Int;
|
||||
ACT : Int;
|
||||
W008 : Int;
|
||||
END_STRUCT;
|
||||
|
||||
REQ_T03 : STRUCT
|
||||
S : Bool;
|
||||
Q : Bool;
|
||||
TW : Int;
|
||||
ST : Int;
|
||||
ACT : Int;
|
||||
W008 : Int;
|
||||
END_STRUCT;
|
||||
|
||||
REQ_T04 : STRUCT
|
||||
S : Bool;
|
||||
Q : Bool;
|
||||
TW : Int;
|
||||
ST : Int;
|
||||
ACT : Int;
|
||||
W008 : Int;
|
||||
END_STRUCT;
|
||||
|
||||
REQ_T05 : STRUCT
|
||||
S : Bool;
|
||||
Q : Bool;
|
||||
TW : Int;
|
||||
ST : Int;
|
||||
ACT : Int;
|
||||
W008 : Int;
|
||||
END_STRUCT;
|
||||
|
||||
END_STRUCT;
|
||||
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
RetVal : Int;
|
||||
MotorNumber : Int;
|
||||
DBNumber : Int;
|
||||
END_VAR
|
||||
|
||||
BEGIN
|
||||
|
||||
// Network 1: INIT Configuration (Original Language: SCL)
|
||||
|
||||
// SCL extraction failed: StructuredText node not found.
|
||||
|
||||
// Network 2: (Original Language: LAD)
|
||||
|
||||
// Network 2 has no logic elements.
|
||||
|
||||
// Network 3: EN run (Original Language: LAD)
|
||||
|
||||
"Motor"."REQ_EN_Run" := "M0.1";
|
||||
|
||||
// Network 4: REQ Auto RUN (Original Language: LAD)
|
||||
|
||||
"Motor"."REQ_Start_FWD" := TRUE;
|
||||
|
||||
// Network 5: Request Speed Fix 01 (Original Language: LAD)
|
||||
|
||||
"Motor"."REQ_Speed_Fix_01" := "M0.1";
|
||||
|
||||
// Network 6: INIT Configuration (Original Language: SCL)
|
||||
|
||||
// SCL extraction failed: StructuredText node not found.
|
||||
|
||||
END_FUNCTION
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,93 @@
|
|||
--- Log de Ejecución: x7_clear.py ---
|
||||
Grupo: XML Parser to SCL
|
||||
Directorio de Trabajo: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\Source
|
||||
Inicio: 2025-06-13 01:01:10
|
||||
Fin: 2025-06-13 01:01:11
|
||||
Duración: 0:00:00.701052
|
||||
Estado: SUCCESS (Código de Salida: 0)
|
||||
|
||||
--- SALIDA ESTÁNDAR (STDOUT) ---
|
||||
INFO: format_variable_name importado desde generators.generator_utils
|
||||
|
||||
=== Limpiando PLC: 98050_PLC ===
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\CONVEYORS\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\CONVEYORS\MiniMotor\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\CONVEYORS\MiniMotor\DBS55_PN_Extend-A\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\CONVEYORS\SICK AG\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\CONVEYORS\TRANSFER\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\ConveyorsBase\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\Library\Motion\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\Library\Motion\Siemens\LCamHdl_Types\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\Library\Motion\Technology\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\Library\SeamlessDivider\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\Library\SeamlessDivider\Technology\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\Machine\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcDataTypes\Machine\Cycle\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcTags\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\PlcTags\Library\Motion\Siemens\LCamHdl_Tags\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\DB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FC\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FC\1-AIR Philosophy\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FC\2-TTOP Philosophy\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FC\3-Motors Manage\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FC\3-Motors Manage\MiniMotor_PN\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FC\3-Motors Manage\MiniMotor_PN\MiniMotor_PN\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FC\HMI\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\FC\MACHINE SIGNALS\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!! SYS !!!\OB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\!!!TRANSFER\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\0 - MAIN\DB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\0 - MAIN\FC\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\0 - MAIN\OB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\Device\DB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\Device\FB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\Device\FC\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\General\DB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\General\FC\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\Motor\DB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\Motor\DB\Minimotor\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\Motor\FC\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\2 - TTOP\Motor\FC\Minimotor\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\4 - LUBE\DB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\4 - LUBE\FB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\1 - CONVEYORS\4 - LUBE\FB\OLD\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\2 - MACHINE\DB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\2 - MACHINE\FB\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\! ConveyorsSTD\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\! ConveyorsSTD\Hmi\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\! ConveyorsSTD\System\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\! ConveyorsSTD\TimeZone\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\AAA_Debug\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\AAA_VirtualMaster\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\ExchangeSignals\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\ExchangeSignals\Loop\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\HMI\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Instances\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Libraries\Generic\Alarms\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Libraries\Motion\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Libraries\Motion\Siemens\LCamHdl_Blocks\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Libraries\Motion\Technology\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Libraries\Motion\Utilities\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Libraries\SeamlessDivider\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Libraries\SeamlessDivider\Technology\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Machine\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Machine\Instances\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\Setup\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\TimingBelt (downstream divider)\parsing
|
||||
- Eliminado directorio de parsing: 98050_PLC\ProgramBlocks_XML\Divider\TimingBelt (downstream divider)\Instances\parsing
|
||||
- Eliminado directorio 'scl_output': 98050_PLC\scl_output
|
||||
- Eliminado directorio 'xref_output': 98050_PLC\xref_output
|
||||
- Eliminado archivo agregado: 98050_PLC\full_project_representation.md
|
||||
- Eliminado log: log_98050_PLC.txt
|
||||
|
||||
--- Resumen de limpieza ---
|
||||
Directorios eliminados: 70
|
||||
Archivos eliminados: 2
|
||||
Limpieza completada.
|
||||
|
||||
--- ERRORES (STDERR) ---
|
||||
Ninguno
|
||||
--- FIN DEL LOG ---
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -61,15 +61,19 @@ def parse_lad_fbd_network(network_element):
|
|||
network_lang = lang_node_net[0].strip()
|
||||
|
||||
# --- Buscar FlgNet ---
|
||||
# Buscar NetworkSource y luego FlgNet (ambos usan namespace flg)
|
||||
network_source_node = network_element.xpath(".//flg:NetworkSource", namespaces=ns)
|
||||
# Paso 1: localizar el nodo <NetworkSource> (sin importar namespace)
|
||||
network_source_node = network_element.xpath(".//*[local-name()='NetworkSource']")
|
||||
|
||||
flgnet = None
|
||||
if network_source_node:
|
||||
flgnet_list = network_source_node[0].xpath("./flg:FlgNet", namespaces=ns)
|
||||
# Buscar FlgNet dentro del NetworkSource
|
||||
flgnet_list = network_source_node[0].xpath(".//*[local-name()='FlgNet']")
|
||||
if flgnet_list:
|
||||
flgnet = flgnet_list[0]
|
||||
else: # Intentar buscar FlgNet directamente si no hay NetworkSource
|
||||
flgnet_list = network_element.xpath(".//flg:FlgNet", namespaces=ns)
|
||||
|
||||
# Paso 2: si no se encontró, intentar buscar FlgNet directamente en el CompileUnit
|
||||
if flgnet is None:
|
||||
flgnet_list = network_element.xpath(".//*[local-name()='FlgNet']")
|
||||
if flgnet_list:
|
||||
flgnet = flgnet_list[0]
|
||||
|
||||
|
|
|
@ -217,30 +217,41 @@ def parse_scl_network(network_element):
|
|||
network_id = network_element.get("ID", "UnknownSCL_ID")
|
||||
network_lang = "SCL" # Sabemos que es SCL
|
||||
|
||||
# Buscar NetworkSource y luego StructuredText
|
||||
network_source_node = network_element.xpath(".//flg:NetworkSource", namespaces=ns)
|
||||
# --- Obtener título y comentario para coherencia con otros parsers ---
|
||||
title_elem = network_element.xpath(
|
||||
"./ObjectList/MultilingualText[@CompositionName='Title']", namespaces=ns
|
||||
)
|
||||
network_title = get_multilingual_text(title_elem[0]) if title_elem else f"Network {network_id}"
|
||||
|
||||
comment_elem = network_element.xpath(
|
||||
"./ObjectList/MultilingualText[@CompositionName='Comment']", namespaces=ns
|
||||
)
|
||||
network_comment = get_multilingual_text(comment_elem[0]) if comment_elem else ""
|
||||
|
||||
# --- Buscar NetworkSource y StructuredText sin depender del namespace ---
|
||||
network_source_node = network_element.xpath(".//*[local-name()='NetworkSource']")
|
||||
structured_text_node = None
|
||||
if network_source_node:
|
||||
structured_text_node_list = network_source_node[0].xpath("./st:StructuredText", namespaces=ns)
|
||||
if structured_text_node_list:
|
||||
structured_text_node = structured_text_node_list[0]
|
||||
st_nodes = network_source_node[0].xpath(".//*[local-name()='StructuredText']")
|
||||
if st_nodes:
|
||||
structured_text_node = st_nodes[0]
|
||||
|
||||
reconstructed_scl = "// SCL extraction failed: StructuredText node not found.\n"
|
||||
if structured_text_node is not None:
|
||||
reconstructed_scl = reconstruct_scl_from_tokens(structured_text_node)
|
||||
|
||||
# Crear la estructura de datos para la red
|
||||
parsed_network_data = {
|
||||
"id": network_id,
|
||||
"title": network_title,
|
||||
"comment": network_comment,
|
||||
"language": network_lang,
|
||||
"logic": [ # SCL se guarda como un único bloque lógico
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": f"SCL_{network_id}", # UID sintético
|
||||
"type": "RAW_SCL_CHUNK", # Tipo especial para SCL crudo
|
||||
"scl": reconstructed_scl, # El código SCL reconstruido
|
||||
"instruction_uid": f"SCL_{network_id}",
|
||||
"type": "RAW_SCL_CHUNK",
|
||||
"scl": reconstructed_scl,
|
||||
}
|
||||
],
|
||||
# No añadimos error aquí, reconstruct_scl_from_tokens ya incluye comentarios de error
|
||||
}
|
||||
return parsed_network_data
|
||||
|
||||
|
|
|
@ -478,3 +478,74 @@ def parse_interface_members(member_elements):
|
|||
} # Guardar como dict simple si no hay comment
|
||||
members_data.append(member_info)
|
||||
return members_data
|
||||
|
||||
# --- NUEVA FUNCIÓN: Adaptación dinámica de namespaces ---
|
||||
|
||||
def adapt_namespaces(root):
|
||||
"""Actualiza dinámicamente los valores en el diccionario global `ns` para que
|
||||
coincidan con los namespaces reales presentes en el XML exportado por TIA.
|
||||
|
||||
Debe llamarse después de obtener la raíz (`root = tree.getroot()`). Si en el
|
||||
XML aparecen nuevas versiones (p.ej. v6) de los URIs, esta función las
|
||||
detectará y sobreescribirá las entradas correspondientes en `ns`.
|
||||
"""
|
||||
if root is None:
|
||||
return # nada que hacer
|
||||
|
||||
detected = {}
|
||||
|
||||
# 1) Examinar los namespaces declarados en la raíz (cuando existan)
|
||||
if hasattr(root, "nsmap") and root.nsmap:
|
||||
for uri in root.nsmap.values():
|
||||
if not uri or "siemens.com/automation" not in str(uri):
|
||||
continue
|
||||
_assign_uri_to_prefix(str(uri), detected)
|
||||
|
||||
# 2) Escaneo rápido por elementos clave si aún no hemos encontrado URIs
|
||||
# Utilizamos búsquedas sin namespace (local-name) para localizar el primer
|
||||
# elemento relevante y extraer su URI real.
|
||||
|
||||
# helper interno
|
||||
|
||||
def find_uri_by_localname(tag_local):
|
||||
elem = root.xpath(f'//*[local-name()="{tag_local}"]')
|
||||
if elem:
|
||||
return etree.QName(elem[0]).namespace
|
||||
return None
|
||||
|
||||
if "flg" not in detected or not detected.get("flg"):
|
||||
flg_uri = find_uri_by_localname("FlgNet")
|
||||
if flg_uri:
|
||||
detected["flg"] = flg_uri
|
||||
|
||||
if "st" not in detected or not detected.get("st"):
|
||||
st_uri = find_uri_by_localname("StructuredText")
|
||||
if st_uri:
|
||||
detected["st"] = st_uri
|
||||
|
||||
if "stl" not in detected or not detected.get("stl"):
|
||||
stl_uri = find_uri_by_localname("StatementList")
|
||||
if stl_uri:
|
||||
detected["stl"] = stl_uri
|
||||
|
||||
if "iface" not in detected or not detected.get("iface"):
|
||||
iface_uri = find_uri_by_localname("Sections")
|
||||
if iface_uri and "/Interface/" in iface_uri:
|
||||
detected["iface"] = iface_uri
|
||||
|
||||
if detected:
|
||||
ns.update(detected)
|
||||
|
||||
|
||||
# --- función auxiliar privada para adapt_namespaces ---
|
||||
|
||||
def _assign_uri_to_prefix(uri_str: str, out_dict: dict):
|
||||
"""Asigna un URI concreto al prefijo adecuado en `out_dict`."""
|
||||
if "/Interface/" in uri_str:
|
||||
out_dict["iface"] = uri_str
|
||||
elif "/NetworkSource/FlgNet/" in uri_str:
|
||||
out_dict["flg"] = uri_str
|
||||
elif "/NetworkSource/StructuredText/" in uri_str:
|
||||
out_dict["st"] = uri_str
|
||||
elif "/NetworkSource/StatementList/" in uri_str:
|
||||
out_dict["stl"] = uri_str
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
"xref_source_subdir": "source"
|
||||
},
|
||||
"level3": {},
|
||||
"working_directory": "D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source"
|
||||
"working_directory": "D:\\Trabajo\\VM\\22 - 93841 - Sidel - Tilting\\Reporte\\TiaExports"
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"x0_main.py": {
|
||||
"display_name": "1: Procesar Exportación XML",
|
||||
"display_name": "1: Procesar Exportación XML de un proyecto a SCL",
|
||||
"short_description": "LadderToSCL - Conversor de Siemens LAD/FUP XML a SCL",
|
||||
"long_description": "Este script es el punto de entrada y orquestador principal para el proceso de conversión de archivos XML de Siemens TIA Portal (LAD/FUP) a código SCL y la generación de documentación relacionada.\n\n**Lógica Principal:**\n\n1. **Configuración:** Carga parámetros desde `ParamManagerScripts` (directorio de trabajo, nombres de carpetas de salida, etc.).\n2. **Logging:** Inicia un archivo `log.txt` para registrar detalladamente el progreso y los errores.\n3. **Descubrimiento:** Busca recursivamente todos los archivos `.xml` dentro del subdirectorio `PLC` del directorio de trabajo configurado.\n4. **Procesamiento Individual (Pasos x1-x3):**\n * Itera sobre cada archivo XML encontrado.\n * Implementa lógica para **saltar** pasos si el XML no ha cambiado y las salidas ya existen y están actualizadas.\n * Llama a funciones de `x1_to_json.py`, `x2_process.py`, y `x3_generate_scl.py` para convertir XML -> JSON intermedio -> JSON procesado -> archivo SCL/Markdown final.\n5. **Referencias Cruzadas (Paso x4):** Llama a una función de `x4_cross_reference.py` para generar análisis de llamadas, uso de DBs, etc., basándose en los archivos procesados.\n6. **Agregación (Paso x5):** Llama a una función de `x5_aggregate.py` para combinar las salidas SCL/Markdown y las referencias cruzadas en un único archivo Markdown resumen.\n7. **Resumen y Salida:** Registra un resumen final del proceso (éxitos, saltos, fallos) y finaliza con un código de estado (0 para éxito, 1 si hubo errores).\n",
|
||||
"hidden": false
|
||||
|
@ -34,5 +34,11 @@
|
|||
"short_description": "LadderToSCL - Conversor de Siemens LAD/FUP XML a SCL",
|
||||
"long_description": "",
|
||||
"hidden": true
|
||||
},
|
||||
"x7_clear.py": {
|
||||
"display_name": "3: Limpiar archivos json y md",
|
||||
"short_description": "3: Limpiar archivos json y md generados por (1)",
|
||||
"long_description": "",
|
||||
"hidden": false
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"path": "D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source",
|
||||
"path": "D:\\Trabajo\\VM\\22 - 93841 - Sidel - Tilting\\Reporte\\TiaExports",
|
||||
"history": [
|
||||
"D:\\Trabajo\\VM\\22 - 93841 - Sidel - Tilting\\Reporte\\TiaExports",
|
||||
"D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source",
|
||||
"C:\\Trabajo\\SIDEL\\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\\Reporte\\SourceDoc\\SourceXML",
|
||||
"C:\\Trabajo\\SIDEL\\06 - E5.007363 - Modifica O&U - SAE196 (cip integrato)\\Reporte\\IOExport"
|
||||
|
|
|
@ -158,16 +158,178 @@ def check_skip_status(
|
|||
return status
|
||||
|
||||
|
||||
# --- FUNCIÓN DE LIMPIEZA (x7) ---------------------------------------------------------------------------
|
||||
|
||||
def clear_generated_outputs(plc_dir: str = None) -> bool:
|
||||
"""Elimina todos los artefactos (JSON, SCL, MD, logs) generados por este script.
|
||||
|
||||
Si *plc_dir* es None, se comporta de forma análoga al modo orquestador,
|
||||
localizando todos los PLCs bajo el *working_directory* configurado y
|
||||
limpiándolos uno a uno. Devuelve *True* si la operación terminó sin
|
||||
errores críticos, *False* en caso contrario.
|
||||
"""
|
||||
errors_found = False
|
||||
|
||||
try:
|
||||
configs = load_configuration()
|
||||
working_directory = configs.get("working_directory")
|
||||
if not working_directory or not os.path.isdir(working_directory):
|
||||
print("Error: 'working_directory' inválido en la configuración.", file=sys.stderr)
|
||||
return False
|
||||
|
||||
xml_parser_config = configs.get("level2", {})
|
||||
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_aggregated_filename = xml_parser_config.get("aggregated_filename", "full_project_representation.md")
|
||||
|
||||
# Determinar la lista de PLCs a limpiar
|
||||
if plc_dir is not None:
|
||||
plc_dirs = [os.path.abspath(plc_dir)]
|
||||
if not os.path.isdir(plc_dirs[0]):
|
||||
print(f"Advertencia: El directorio PLC especificado no existe: {plc_dirs[0]}")
|
||||
return False
|
||||
else:
|
||||
plc_dirs = []
|
||||
for entry in os.listdir(working_directory):
|
||||
cand_path = os.path.join(working_directory, entry)
|
||||
if os.path.isdir(cand_path) and glob.glob(os.path.join(cand_path, "**", "*.xml"), recursive=True):
|
||||
plc_dirs.append(cand_path)
|
||||
if not plc_dirs:
|
||||
plc_dirs = [working_directory]
|
||||
|
||||
total_dirs_removed = 0
|
||||
total_files_removed = 0
|
||||
|
||||
for plc_path in plc_dirs:
|
||||
plc_path = os.path.abspath(plc_path)
|
||||
plc_name_safe = os.path.basename(plc_path.strip(os.sep))
|
||||
print(f"\n=== Limpiando PLC: {plc_name_safe} ===")
|
||||
|
||||
# 1) Eliminar carpetas 'parsing' (y su contenido JSON)
|
||||
for parsing_dir in glob.glob(os.path.join(plc_path, "**", "parsing"), recursive=True):
|
||||
if os.path.isdir(parsing_dir):
|
||||
try:
|
||||
shutil.rmtree(parsing_dir)
|
||||
print(f" - Eliminado directorio de parsing: {os.path.relpath(parsing_dir, working_directory)}")
|
||||
total_dirs_removed += 1
|
||||
except Exception as e:
|
||||
print(f" - ERROR al eliminar {parsing_dir}: {e}")
|
||||
errors_found = True
|
||||
|
||||
# 2) Eliminar directorios de salida SCL y XRef
|
||||
for dirname in [cfg_scl_output_dirname, cfg_xref_output_dirname]:
|
||||
target_dir = os.path.join(plc_path, dirname)
|
||||
if os.path.isdir(target_dir):
|
||||
try:
|
||||
shutil.rmtree(target_dir)
|
||||
print(f" - Eliminado directorio '{dirname}': {os.path.relpath(target_dir, working_directory)}")
|
||||
total_dirs_removed += 1
|
||||
except Exception as e:
|
||||
print(f" - ERROR al eliminar {target_dir}: {e}")
|
||||
errors_found = True
|
||||
|
||||
# 3) Eliminar archivo agregado principal
|
||||
agg_file = os.path.join(plc_path, cfg_aggregated_filename)
|
||||
if os.path.isfile(agg_file):
|
||||
try:
|
||||
os.remove(agg_file)
|
||||
print(f" - Eliminado archivo agregado: {os.path.relpath(agg_file, working_directory)}")
|
||||
total_files_removed += 1
|
||||
except Exception as e:
|
||||
print(f" - ERROR al eliminar {agg_file}: {e}")
|
||||
errors_found = True
|
||||
|
||||
# 4) Eliminar logs específicos del PLC
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
log_path = os.path.join(script_dir, f"log_{plc_name_safe}.txt")
|
||||
if os.path.isfile(log_path):
|
||||
try:
|
||||
os.remove(log_path)
|
||||
print(f" - Eliminado log: {os.path.basename(log_path)}")
|
||||
total_files_removed += 1
|
||||
except Exception as e:
|
||||
print(f" - ERROR al eliminar {log_path}: {e}")
|
||||
errors_found = True
|
||||
|
||||
print("\n--- Resumen de limpieza ---")
|
||||
print(f" Directorios eliminados: {total_dirs_removed}")
|
||||
print(f" Archivos eliminados: {total_files_removed}")
|
||||
print(" Limpieza completada." if not errors_found else " Limpieza completada con errores.")
|
||||
|
||||
return not errors_found
|
||||
except Exception as e:
|
||||
print(f"ERROR inesperado durante la limpieza: {e}", file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
# --- FIN FUNCIÓN DE LIMPIEZA -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# --- Bloque Principal ---
|
||||
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()
|
||||
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", {})
|
||||
|
||||
# <-- 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_xref_output_dirname = xml_parser_config.get("xref_output_dir", "xref_output")
|
||||
cfg_xref_source_subdir = xml_parser_config.get("xref_source_subdir", "source")
|
||||
|
@ -175,59 +337,46 @@ if __name__ == "__main__":
|
|||
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")
|
||||
|
||||
# Ensure max_call_depth is an integer
|
||||
# Conversión de enteros con control de errores
|
||||
try:
|
||||
cfg_max_call_depth = int(xml_parser_config.get("max_call_depth", 5))
|
||||
except (ValueError, TypeError):
|
||||
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
|
||||
|
||||
# Ensure max_users_list is an integer
|
||||
try:
|
||||
cfg_max_users_list = int(xml_parser_config.get("max_users_list", 20))
|
||||
except (ValueError, TypeError):
|
||||
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_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)
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# <-- MODIFICADO: Abrir archivo log -->
|
||||
log_filepath = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), LOG_FILENAME
|
||||
)
|
||||
with open(
|
||||
log_filepath, "w", encoding="utf-8"
|
||||
) as log_f: # Usar 'a' para añadir al log
|
||||
log_message("=" * 40 + " LOG START " + "=" * 40, log_f)
|
||||
|
||||
# --- PARTE 1: BUSCAR ARCHIVOS ---
|
||||
# <-- MODIFICADO: Apuntar al subdirectorio 'PLC' dentro del working_directory -->
|
||||
plc_subdir_name = "PLC" # Nombre estándar del subdirectorio de TIA Portal
|
||||
xml_project_dir = os.path.join(working_directory, plc_subdir_name)
|
||||
|
||||
# Se trabaja exclusivamente dentro del PLC indicado.
|
||||
log_message(
|
||||
f"Directorio de trabajo base configurado: '{working_directory}'", log_f
|
||||
)
|
||||
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
|
||||
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)
|
||||
# Patrón de búsqueda global para todos los PLC
|
||||
search_pattern = os.path.join(xml_project_dir, "**", "*.xml")
|
||||
xml_files_found = glob.glob(search_pattern, recursive=True)
|
||||
if not xml_files_found:
|
||||
|
@ -423,7 +572,7 @@ if __name__ == "__main__":
|
|||
log_message(f"Se encontraron {len(filtered_scl_files)} archivos .scl existentes para copiar:", log_f)
|
||||
for src_scl_path in filtered_scl_files:
|
||||
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
|
||||
if os.path.exists(dest_scl_path):
|
||||
|
@ -513,7 +662,8 @@ if __name__ == "__main__":
|
|||
run_x5 = False
|
||||
|
||||
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(
|
||||
f"Ejecutando x5 (aggregate_outputs) sobre: {xml_project_dir}, salida agregada en: {output_agg_file}",
|
||||
log_f
|
||||
|
@ -590,7 +740,7 @@ if __name__ == "__main__":
|
|||
|
||||
log_message(final_console_message, log_f) # Loguear mensaje final
|
||||
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
|
||||
log_message("="*41 + " LOG END " + "="*42, log_f)
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ from backend.script_utils import load_configuration
|
|||
|
||||
# Importar funciones comunes y namespaces desde el nuevo módulo de utils
|
||||
try:
|
||||
from parsers.parser_utils import ns, get_multilingual_text, parse_interface_members
|
||||
from parsers.parser_utils import ns, get_multilingual_text, parse_interface_members, adapt_namespaces
|
||||
except ImportError as e:
|
||||
print(
|
||||
f"Error crítico: No se pudieron importar funciones desde parsers.parser_utils: {e}"
|
||||
|
@ -253,6 +253,11 @@ def convert_xml_to_json(xml_filepath, json_filepath):
|
|||
parser = etree.XMLParser(remove_blank_text=True, recover=True)
|
||||
tree = etree.parse(xml_filepath, parser)
|
||||
root = tree.getroot()
|
||||
# Ajustar namespaces dinámicamente para soportar distintas versiones de TIA
|
||||
try:
|
||||
adapt_namespaces(root)
|
||||
except Exception as e_ns:
|
||||
print(f"Advertencia: No se pudo adaptar namespaces dinámicamente: {e_ns}")
|
||||
print("Paso 1: Parseo XML completado.")
|
||||
|
||||
result = None
|
||||
|
|
|
@ -366,6 +366,18 @@ def generate_call_tree_output(call_graph, block_data, base_xref_dir, max_call_de
|
|||
"""
|
||||
output_lines = ["# Árbol de Referencias Cruzadas de Llamadas\n"]
|
||||
output_lines.append(f"(Profundidad máxima: {max_call_depth})\n") # <-- Usar el parámetro
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Aviso cuando NO se han detectado llamadas entre bloques
|
||||
# ------------------------------------------------------------
|
||||
has_any_call = any(len(callees) > 0 for callees in call_graph.values())
|
||||
if not has_any_call:
|
||||
output_lines.append(
|
||||
"\n> ⚠️ Nota: No se detectaron referencias cruzadas de llamadas. "
|
||||
"Es posible que no existan los archivos '*_XRef.xml' o que aún no "
|
||||
"se haya ejecutado el análisis de fallback sobre los bloques SCL.\n"
|
||||
)
|
||||
|
||||
root_nodes = sorted( # Encontrar OBs
|
||||
[
|
||||
name
|
||||
|
@ -646,7 +658,8 @@ def generate_cross_references(
|
|||
# 2. Construir Grafo de Llamadas desde XML XRef
|
||||
print("Construyendo grafo de llamadas desde archivos XML XRef...")
|
||||
call_graph = defaultdict(list) # Usamos lista, no necesitamos contar llamadas múltiples aquí
|
||||
xref_xml_files = glob.glob(os.path.join(xref_xml_dir, "*_XRef.xml"))
|
||||
# Buscar recursivamente en todas las subcarpetas (algunos proyectos guardan los XML en estructuras anidadas)
|
||||
xref_xml_files = glob.glob(os.path.join(xref_xml_dir, "**", "*_XRef.xml"), recursive=True)
|
||||
if not xref_xml_files:
|
||||
print(f"ADVERTENCIA: No se encontraron archivos '*_XRef.xml' en {xref_xml_dir}. El árbol de llamadas estará vacío.", file=sys.stderr)
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
"""x7_clear.py
|
||||
Script de limpieza para eliminar todos los artefactos generados por x0_main.py.
|
||||
|
||||
Este script actúa como envoltorio del método `clear_generated_outputs` definido
|
||||
en `x0_main.py`. De esta forma, la lógica de eliminación se mantiene en un solo
|
||||
lugar y se adapta automáticamente a futuros cambios en la estructura de
|
||||
salidas de x0.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
# Importar la función de limpieza desde x0_main.py
|
||||
from x0_main import clear_generated_outputs # noqa: E402 – import absoluto intencional
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Elimina los archivos generados por x0_main.py (JSON, SCL, MD, logs)."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--plc-dir",
|
||||
dest="plc_dir",
|
||||
default=None,
|
||||
help=(
|
||||
"Ruta de un PLC específico a limpiar. Si se omite, se limpiarán "
|
||||
"todos los PLCs detectados bajo el working_directory definido en la configuración."
|
||||
),
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
success = clear_generated_outputs(args.plc_dir)
|
||||
# Salir con 0 si todo fue bien, 1 en caso de errores
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -1,5 +1,18 @@
|
|||
{
|
||||
"history": [
|
||||
{
|
||||
"id": "15176a5f",
|
||||
"group_id": "1",
|
||||
"script_name": "calc.py",
|
||||
"executed_date": "2025-06-13T10:53:37.648203Z",
|
||||
"arguments": [],
|
||||
"working_directory": "D:/Proyectos/Scripts/Calcv2",
|
||||
"python_env": "tia_scripting",
|
||||
"executable_type": "pythonw.exe",
|
||||
"status": "running",
|
||||
"pid": 21072,
|
||||
"execution_time": null
|
||||
},
|
||||
{
|
||||
"id": "a599effd",
|
||||
"group_id": "4",
|
||||
|
|
134
data/log.txt
134
data/log.txt
|
@ -1,5 +1,129 @@
|
|||
[20:03:36] Iniciando ejecución de x1.py en D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\Source...
|
||||
[20:03:37] --- TIA Portal Data Exporter (Blocks, UDTs, Tags) ---
|
||||
[20:03:47] No project file selected. Exiting.
|
||||
[20:03:47] Ejecución de x1.py finalizada (success). Duración: 0:00:10.497365.
|
||||
[20:03:47] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\log_x1.txt
|
||||
[11:14:30] Iniciando ejecución de x4.py en D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports...
|
||||
[11:14:30] --- Exportador de Referencias Cruzadas de TIA Portal ---
|
||||
[11:14:34] Versión de TIA Portal detectada: 19.0 (de la extensión .ap19)
|
||||
[11:14:34] Proyecto seleccionado: D:/Trabajo/VM/22 - 93841 - Sidel - Tilting/InLavoro/PLC/93841_PLC_28/93841_PLC_28.ap19
|
||||
[11:14:34] Usando directorio base de exportación: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports
|
||||
[11:14:34] Conectando a TIA Portal V19.0...
|
||||
[11:14:34] 2025-06-13 11:14:34,713 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - Start TIA Portal, please acknowledge the security dialog.
|
||||
[11:14:34] 2025-06-13 11:14:34,731 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - With user interface
|
||||
[11:14:58] Conectado a TIA Portal.
|
||||
[11:14:58] 2025-06-13 11:14:58,165 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal GetProcessId - Process id: 30140
|
||||
[11:14:58] ID del proceso del Portal: 30140
|
||||
[11:14:58] Abriendo proyecto: 93841_PLC_28.ap19...
|
||||
[11:14:58] 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
|
||||
[11:15:25] Proyecto abierto exitosamente.
|
||||
[11:15:29] 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
|
||||
[11:15:30] 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
|
||||
[11:15:34] Se encontraron 2 PLC(s). Iniciando proceso de exportación de referencias cruzadas...
|
||||
[11:15:34] --- Procesando PLC: VM 1512 ---
|
||||
[11:15:34] [PLC: VM 1512] Exportando referencias cruzadas de bloques de programa...
|
||||
[11:15:34] Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\ProgramBlocks_CR
|
||||
[11:15:34] Se encontraron 201 bloques de programa.
|
||||
[11:15:34] Procesando bloque: FC General COM...
|
||||
[11:15:34] Exportando referencias cruzadas para FC General COM...
|
||||
[11:15:38] Procesando bloque: From_SIDEL...
|
||||
[11:15:38] Exportando referencias cruzadas para From_SIDEL...
|
||||
[11:15:38] Procesando bloque: To_SIDEL...
|
||||
[11:15:38] Exportando referencias cruzadas para To_SIDEL...
|
||||
[11:15:38] Procesando bloque: DB Early Restart Blower...
|
||||
[11:15:38] Exportando referencias cruzadas para DB Early Restart Blower...
|
||||
[11:15:39] Procesando bloque: DB Early Restart Filler...
|
||||
[11:15:39] Exportando referencias cruzadas para DB Early Restart Filler...
|
||||
[11:15:39] Procesando bloque: DB Early Restart SynchroBlock...
|
||||
[11:15:39] Exportando referencias cruzadas para DB Early Restart SynchroBlock...
|
||||
[11:15:40] Procesando bloque: FB Early Restart...
|
||||
[11:15:40] Exportando referencias cruzadas para FB Early Restart...
|
||||
[11:15:40] Procesando bloque: DB Signal Transport...
|
||||
[11:15:40] Exportando referencias cruzadas para DB Signal Transport...
|
||||
[11:15:42] Procesando bloque: FC Signal Transport...
|
||||
[11:15:42] Exportando referencias cruzadas para FC Signal Transport...
|
||||
[11:15:43] Procesando bloque: DB Lube - Dry Ecolab...
|
||||
[11:15:43] Exportando referencias cruzadas para DB Lube - Dry Ecolab...
|
||||
[11:15:46] Procesando bloque: FB Lube - Water/Dry...
|
||||
[11:15:46] Exportando referencias cruzadas para FB Lube - Water/Dry...
|
||||
[11:15:46] Procesando bloque: FB Lube - Dry Ecolab...
|
||||
[11:15:46] Exportando referencias cruzadas para FB Lube - Dry Ecolab...
|
||||
[11:15:47] Procesando bloque: FB Lube - EcoLab VM...
|
||||
[11:15:47] Exportando referencias cruzadas para FB Lube - EcoLab VM...
|
||||
[11:15:48] Procesando bloque: FB Lube - Ecolab...
|
||||
[11:15:48] Exportando referencias cruzadas para FB Lube - Ecolab...
|
||||
[11:15:49] Procesando bloque: DB LUBE - Ecolab...
|
||||
[11:15:49] Exportando referencias cruzadas para DB LUBE - Ecolab...
|
||||
[11:15:57] Procesando bloque: FC Ttop Configuration...
|
||||
[11:15:57] Exportando referencias cruzadas para FC Ttop Configuration...
|
||||
[11:15:57] Procesando bloque: FC Ttop Run...
|
||||
[11:15:57] Exportando referencias cruzadas para FC Ttop Run...
|
||||
[11:15:58] Procesando bloque: FC Ttop Alarms...
|
||||
[11:15:58] Exportando referencias cruzadas para FC Ttop Alarms...
|
||||
[11:15:58] Procesando bloque: DB Ttop Run...
|
||||
[11:15:58] Exportando referencias cruzadas para DB Ttop Run...
|
||||
[11:15:59] Procesando bloque: DB Ttop Motor CFG...
|
||||
[11:15:59] Exportando referencias cruzadas para DB Ttop Motor CFG...
|
||||
[11:16:02] Procesando bloque: DB Ttop Alarm...
|
||||
[11:16:02] Exportando referencias cruzadas para DB Ttop Alarm...
|
||||
[11:16:07] Procesando bloque: FC Ttop Motor 31...
|
||||
[11:16:07] Exportando referencias cruzadas para FC Ttop Motor 31...
|
||||
[11:16:07] Procesando bloque: FC Ttop Motor 32...
|
||||
[11:16:07] Exportando referencias cruzadas para FC Ttop Motor 32...
|
||||
[11:16:07] Procesando bloque: FC Ttop Motor 34...
|
||||
[11:16:07] Exportando referencias cruzadas para FC Ttop Motor 34...
|
||||
[11:16:08] Procesando bloque: FC Ttop Motor 35...
|
||||
[11:16:08] Exportando referencias cruzadas para FC Ttop Motor 35...
|
||||
[11:16:08] Procesando bloque: FC Ttop Motor 36...
|
||||
[11:16:08] Exportando referencias cruzadas para FC Ttop Motor 36...
|
||||
[11:16:08] Procesando bloque: DB Ttop Motor 31...
|
||||
[11:16:08] Exportando referencias cruzadas para DB Ttop Motor 31...
|
||||
[11:16:13] Procesando bloque: DB Ttop Motor 32...
|
||||
[11:16:13] Exportando referencias cruzadas para DB Ttop Motor 32...
|
||||
[11:16:18] Procesando bloque: DB Ttop Motor 34...
|
||||
[11:16:18] Exportando referencias cruzadas para DB Ttop Motor 34...
|
||||
[11:16:23] Procesando bloque: DB Ttop Motor 35...
|
||||
[11:16:23] Exportando referencias cruzadas para DB Ttop Motor 35...
|
||||
[11:16:27] Procesando bloque: DB Ttop Minimotor Cfg 32...
|
||||
[11:16:27] Exportando referencias cruzadas para DB Ttop Minimotor Cfg 32...
|
||||
[11:16:29] Procesando bloque: DB Ttop Minimotor Data 32...
|
||||
[11:16:29] Exportando referencias cruzadas para DB Ttop Minimotor Data 32...
|
||||
[11:16:31] Procesando bloque: DB Ttop Motor 36...
|
||||
[11:16:31] Exportando referencias cruzadas para DB Ttop Motor 36...
|
||||
[11:16:35] Procesando bloque: FB Ttop Dryer...
|
||||
[11:16:35] Exportando referencias cruzadas para FB Ttop Dryer...
|
||||
[11:16:36] Procesando bloque: FB Ttop Energy Saving...
|
||||
[11:16:36] Exportando referencias cruzadas para FB Ttop Energy Saving...
|
||||
[11:16:36] Procesando bloque: FB SKID...
|
||||
[11:16:36] Exportando referencias cruzadas para FB SKID...
|
||||
[11:16:36] Procesando bloque: FC Analog Sensor Process...
|
||||
[11:16:36] Exportando referencias cruzadas para FC Analog Sensor Process...
|
||||
[11:16:37] Procesando bloque: FC Valve...
|
||||
[11:16:37] Exportando referencias cruzadas para FC Valve...
|
||||
[11:16:37] Procesando bloque: FB SpeedRegulation...
|
||||
[11:16:37] Exportando referencias cruzadas para FB SpeedRegulation...
|
||||
[11:16:37] Procesando bloque: FC Simple PID...
|
||||
[11:16:37] Exportando referencias cruzadas para FC Simple PID...
|
||||
[11:16:38] Procesando bloque: FC Scale Real...
|
||||
[11:16:38] Exportando referencias cruzadas para FC Scale Real...
|
||||
[11:16:38] Procesando bloque: FB Correct Speed F/Pulses...
|
||||
[11:16:38] Exportando referencias cruzadas para FB Correct Speed F/Pulses...
|
||||
[11:16:43] ERROR GENERAL al exportar referencias cruzadas para el bloque FB Correct Speed F/Pulses: OpennessAccessException: Unexpected exception - no exception message available.
|
||||
[11:16:43] 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.
|
||||
[11:16:43] TIA Portal has either been disposed or stopped running.
|
||||
[11:16:43] [PLC: VM 1512] Exportando referencias cruzadas de tablas de variables...
|
||||
[11:16:43] Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\PlcTags_CR
|
||||
[11:16:43] ERROR al acceder a las tablas de variables para exportar referencias cruzadas: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
[11:16:43] [PLC: VM 1512] Exportando referencias cruzadas de tipos de datos PLC (UDTs)...
|
||||
[11:16:43] Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\PlcDataTypes_CR
|
||||
[11:16:43] ERROR al acceder a los UDTs para exportar referencias cruzadas: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
[11:16:43] [PLC: VM 1512] Intentando exportar referencias cruzadas de bloques de sistema...
|
||||
[11:16:43] Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\SystemBlocks_CR
|
||||
[11:16:43] ERROR al acceder/procesar bloques de sistema para exportar referencias cruzadas: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
[11:16:43] [PLC: VM 1512] Intentando exportar referencias cruzadas de unidades de software...
|
||||
[11:16:43] Destino: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports\VM 1512\SoftwareUnits_CR
|
||||
[11:16:43] ERROR al acceder/procesar unidades de software para exportar referencias cruzadas: SerializationException: No se puede encontrar el ensamblado 'Siemens.Engineering, Version=19.0.0.0, Culture=neutral, PublicKeyToken=d29ec89bac048f84'.
|
||||
[11:16:43] --- Finalizado el procesamiento del PLC: VM 1512 ---
|
||||
[11:16:43] Ocurrió un error inesperado: OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.HW.DeviceItemImpl' is not possible.
|
||||
[11:16:43] TIA Portal has either been disposed or stopped running.
|
||||
[11:16:43] Cerrando TIA Portal...
|
||||
[11:16:43] 2025-06-13 11:16:43,486 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal ClosePortal - Close TIA Portal
|
||||
[11:16:43] TIA Portal cerrado.
|
||||
[11:16:43] Script finalizado.
|
||||
[11:16:43] Ejecución de x4.py finalizada (success). Duración: 0:02:13.165274. Se detectaron errores (ver log).
|
||||
[11:16:43] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\log_x4.txt
|
||||
|
|
|
@ -181,18 +181,18 @@
|
|||
<div class="flex-1 flex gap-2">
|
||||
<input type="text" id="working-directory" class="flex-1 p-2 border rounded bg-green-50">
|
||||
<button class="bg-gray-500 text-white px-4 py-2 rounded" onclick="browseDirectory()">
|
||||
Explorar
|
||||
Buscar
|
||||
</button>
|
||||
<button id="open-in-explorer-btn"
|
||||
class="bg-indigo-500 hover:bg-indigo-600 text-white px-4 py-2 rounded"
|
||||
title="Abrir directorio actual en el explorador de archivos">
|
||||
Abrir Carpeta
|
||||
</button>
|
||||
</div>
|
||||
<button class="bg-blue-500 text-white px-4 py-2 rounded" onclick="setWorkingDirectory()">
|
||||
Confirmar
|
||||
Salvar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Add directory history dropdown -->
|
||||
<div class="mt-2">
|
||||
<select id="directory-history" class="w-full p-2 border rounded text-gray-600"
|
||||
|
|
Loading…
Reference in New Issue