Se modificó el script `x1_lad_converter.py` para cambiar el manejo de los objetivos de red, pasando de un solo objetivo a una lista de objetivos. Se implementaron mejoras en la lógica de análisis de redes, permitiendo la recopilación de múltiples salidas y optimizando la generación de código SCL. Además, se actualizaron los mensajes de depuración y se mejoró la estructura del código para una mayor claridad y mantenimiento.
This commit is contained in:
parent
ffc686e140
commit
164667bc2f
|
@ -366,7 +366,7 @@ class SimpleLadConverter:
|
|||
"id": self.current_network_id,
|
||||
"comment": "",
|
||||
"logic": None,
|
||||
"target": "",
|
||||
"targets": [],
|
||||
"calls": [], # NUEVO: para almacenar llamadas a FB/FUN
|
||||
"function_blocks": [],
|
||||
}
|
||||
|
@ -417,13 +417,31 @@ class SimpleLadConverter:
|
|||
# Continuar buscando
|
||||
i += 1
|
||||
|
||||
elif line.startswith("_OUTPUTS"):
|
||||
num_outputs = int(line.split(":")[1].strip())
|
||||
i += 1
|
||||
for _ in range(num_outputs):
|
||||
while i < len(lines) and not lines[i].strip().startswith("_OUTPUT"):
|
||||
i += 1
|
||||
if i >= len(lines):
|
||||
break
|
||||
i += 1 # past _OUTPUT
|
||||
|
||||
while i < len(lines) and lines[i].strip().startswith("_"): # flags
|
||||
i += 1
|
||||
if i < len(lines):
|
||||
var_name = lines[i].strip()
|
||||
if var_name:
|
||||
network["targets"].append(var_name)
|
||||
i += 1
|
||||
|
||||
elif line.startswith("_OUTPUT"):
|
||||
# Buscar variable de salida
|
||||
i += 1
|
||||
while i < len(lines) and lines[i].strip().startswith("_"):
|
||||
i += 1
|
||||
if i < len(lines) and lines[i].strip() and "ENABLELIST" not in lines[i]:
|
||||
network["target"] = lines[i].strip()
|
||||
network["targets"].append(lines[i].strip())
|
||||
i += 1
|
||||
else:
|
||||
i += 1
|
||||
|
@ -442,7 +460,7 @@ class SimpleLadConverter:
|
|||
print(f" 🎯 Función reconocida: {call['name']}")
|
||||
else:
|
||||
print(f" 📋 Llamada: {call['type']} - {call['name']}")
|
||||
print(f" Target: '{network['target']}'")
|
||||
print(f" Targets: '{network['targets']}'")
|
||||
return i
|
||||
|
||||
def _parse_lad_expression(self, lines, start_idx):
|
||||
|
@ -1030,7 +1048,7 @@ class SimpleLadConverter:
|
|||
"id": self.current_network_id,
|
||||
"comment": f'Llamada a función: {function_logic.get("name", "unknown")}',
|
||||
"logic": function_logic,
|
||||
"target": target_name,
|
||||
"targets": [target_name],
|
||||
"function_blocks": [],
|
||||
"calls": [function_logic], # ✅ Añadir la llamada al array calls
|
||||
}
|
||||
|
@ -1134,18 +1152,19 @@ class SimpleLadConverter:
|
|||
if condition_str:
|
||||
output.append(" END_IF;")
|
||||
|
||||
elif network["target"]:
|
||||
# Red sin llamadas pero con target
|
||||
elif network["targets"]:
|
||||
# Red sin llamadas pero con target(s)
|
||||
if condition_str:
|
||||
output.append(f" IF {condition_str} THEN")
|
||||
output.append(f" {network['target']} := TRUE;")
|
||||
for target in network["targets"]:
|
||||
output.append(f" {target} := TRUE;")
|
||||
output.append(" ELSE")
|
||||
output.append(f" {network['target']} := FALSE;")
|
||||
for target in network["targets"]:
|
||||
output.append(f" {target} := FALSE;")
|
||||
output.append(" END_IF;")
|
||||
else:
|
||||
output.append(
|
||||
f" {network['target']} := TRUE; // Sin condición"
|
||||
)
|
||||
for target in network["targets"]:
|
||||
output.append(f" {target} := TRUE; // Sin condición")
|
||||
|
||||
output.append("")
|
||||
|
||||
|
@ -1301,6 +1320,8 @@ class SimpleLadConverter:
|
|||
# Asegurar que el campo 'calls' existe
|
||||
if "calls" not in network:
|
||||
network["calls"] = []
|
||||
if "targets" not in network:
|
||||
network["targets"] = []
|
||||
|
||||
output.append(f" // Red {network['id']}")
|
||||
if network["comment"]:
|
||||
|
@ -1325,18 +1346,21 @@ class SimpleLadConverter:
|
|||
call_str = self._convert_call_to_string(call, indent)
|
||||
output.append(call_str)
|
||||
|
||||
elif network["target"]:
|
||||
output.append(f"{indent}{network['target']} := TRUE;")
|
||||
elif network["targets"]:
|
||||
for target in network["targets"]:
|
||||
output.append(f"{indent}{target} := TRUE;")
|
||||
|
||||
if condition_str:
|
||||
if not network_calls and network["target"]:
|
||||
if not network_calls and network["targets"]:
|
||||
output.append(" ELSE")
|
||||
output.append(f" {network['target']} := FALSE;")
|
||||
for target in network["targets"]:
|
||||
output.append(f" {target} := FALSE;")
|
||||
output.append(" END_IF;")
|
||||
|
||||
elif network["target"]:
|
||||
elif network["targets"]:
|
||||
for target in network["targets"]:
|
||||
output.append(
|
||||
f" {network['target']} := TRUE; // Sin condición, solo target"
|
||||
f" {target} := TRUE; // Sin condición, solo target"
|
||||
)
|
||||
|
||||
output.append("")
|
||||
|
@ -1461,7 +1485,7 @@ class SimpleLadConverter:
|
|||
print(f"\nRed {network['id']}:")
|
||||
if network["comment"]:
|
||||
print(f" Comentario: {network['comment']}")
|
||||
print(f" Target: {network['target']}")
|
||||
print(f" Targets: {network['targets']}")
|
||||
|
||||
if network["logic"]:
|
||||
print(f" Lógica: {self._debug_logic_string(network['logic'])}")
|
||||
|
@ -1652,7 +1676,7 @@ class SimpleLadConverter:
|
|||
for network in self.networks:
|
||||
if (
|
||||
network["logic"]
|
||||
and network["target"]
|
||||
and network["targets"]
|
||||
and network["id"] in self.sympy_expressions
|
||||
):
|
||||
groupable_networks.append(network)
|
||||
|
@ -1892,45 +1916,57 @@ class SimpleLadConverter:
|
|||
print(f"Total ACTIONs: {len(self.actions)}")
|
||||
|
||||
def _parse_action_lad(self, action_name, action_content):
|
||||
"""Parsear una ACTION que contiene código LAD"""
|
||||
# Crear un convertidor temporal para esta ACTION
|
||||
action_converter = SimpleLadConverter()
|
||||
action_converter.symbol_manager = self.symbol_manager # Compartir símbolos
|
||||
# We create a completely new, isolated instance of the converter to parse the action's LAD code.
|
||||
# This prevents any state (like network counts) from leaking between the main program and the action parsing.
|
||||
action_converter = SimpleLadConverter(self.function_registry)
|
||||
|
||||
# Encontrar sección LAD
|
||||
lad_start = action_content.find("_LD_BODY")
|
||||
if lad_start != -1:
|
||||
# Extraer contenido LAD hasta el final
|
||||
lad_content = action_content[lad_start:]
|
||||
lines = lad_content.split("\n")
|
||||
# Extract just the LAD body from the action content
|
||||
lad_body_match = re.search(r"_LD_BODY(.*)", action_content, re.DOTALL)
|
||||
if lad_body_match:
|
||||
lad_content = lad_body_match.group(1)
|
||||
lines = lad_content.strip().split("\n")
|
||||
|
||||
# The parse_networks method will process all networks it finds in the provided lines.
|
||||
action_converter._parse_networks(lines)
|
||||
|
||||
return {
|
||||
"type": "LAD",
|
||||
"networks": action_converter.networks,
|
||||
"raw_content": action_content,
|
||||
}
|
||||
# The parsed networks are stored in the temporary converter's `networks` list.
|
||||
# We return this list as the logic for the action.
|
||||
return {"type": "LAD", "networks": action_converter.networks}
|
||||
|
||||
# If no LAD body is found, return an empty structure.
|
||||
return {"type": "LAD", "networks": []}
|
||||
|
||||
def _extract_st_code(self, content):
|
||||
"""Extraer código ST del programa principal"""
|
||||
# Buscar desde después de END_VAR hasta ACTION o END_PROGRAM
|
||||
var_end = content.rfind("END_VAR")
|
||||
if var_end == -1:
|
||||
var_end_match = re.search(r"END_VAR", content)
|
||||
if not var_end_match:
|
||||
self.st_main_code = None
|
||||
return
|
||||
|
||||
# Buscar el final del código principal
|
||||
action_start = content.find("\nACTION", var_end)
|
||||
end_program = content.find("\nEND_PROGRAM", var_end)
|
||||
start_index = var_end_match.end()
|
||||
|
||||
code_end = action_start if action_start != -1 else end_program
|
||||
if code_end == -1:
|
||||
code_end = len(content)
|
||||
# Buscar el final del código principal
|
||||
action_start_match = re.search(r"\nACTION", content[start_index:])
|
||||
end_program_match = re.search(r"\nEND_PROGRAM", content[start_index:])
|
||||
|
||||
end_index = -1
|
||||
|
||||
if action_start_match:
|
||||
end_index = start_index + action_start_match.start()
|
||||
|
||||
if end_program_match:
|
||||
program_end = start_index + end_program_match.start()
|
||||
if end_index == -1 or program_end < end_index:
|
||||
end_index = program_end
|
||||
|
||||
if end_index == -1:
|
||||
end_index = len(content)
|
||||
|
||||
# Extraer código ST
|
||||
st_code = content[var_end + 7 : code_end].strip() # +7 para saltar "END_VAR"
|
||||
st_code = content[start_index:end_index].strip()
|
||||
|
||||
if st_code:
|
||||
# Almacenar código ST para usar en la generación
|
||||
self.st_main_code = st_code
|
||||
print(f"Código ST principal extraído: {len(st_code)} caracteres")
|
||||
else:
|
||||
|
@ -2121,144 +2157,132 @@ def collect_function_interfaces(input_directory, debug_mode=False):
|
|||
return function_registry, function_files
|
||||
|
||||
|
||||
def main():
|
||||
"""Función principal - Convierte todos los archivos .EXP a .SCL con dos pasadas"""
|
||||
try:
|
||||
import time
|
||||
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
print("=== SCRIPT VERIFICADO Y EJECUTÁNDOSE CORRECTAMENTE ===")
|
||||
print(f"🕒 Timestamp: {timestamp}")
|
||||
print("=== INICIANDO CONVERTIDOR SCRIPT (2 PASADAS) ===")
|
||||
|
||||
# Verificar si se pasó un archivo específico como parámetro para debug
|
||||
debug_file = None
|
||||
if len(sys.argv) > 1:
|
||||
debug_file = sys.argv[1]
|
||||
def run_debug_mode(debug_file_arg):
|
||||
"""Ejecuta el convertidor en modo debug para un solo archivo."""
|
||||
print(f"=== MODO DEBUG: Procesando archivo específico ===")
|
||||
print(f"Archivo: {debug_file}")
|
||||
print(f"Archivo: {debug_file_arg}")
|
||||
print("🔧 VERIFICACIÓN: Script modificado y ejecutándose en tiempo real")
|
||||
|
||||
# Determinar el path absoluto del archivo de debug.
|
||||
# Esto permite que el script se ejecute desde cualquier lugar.
|
||||
debug_file_path = os.path.abspath(debug_file_arg)
|
||||
|
||||
if not debug_file_path.endswith(".EXP"):
|
||||
debug_file_path += ".EXP"
|
||||
|
||||
if not os.path.exists(debug_file_path):
|
||||
print(f"Error: No se encontró el archivo de debug: {debug_file_path}")
|
||||
# Intenta buscarlo en el directorio relativo ExportTwinCat por si acaso
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
export_dir_path = os.path.join(
|
||||
script_dir, "..", "ExportTwinCat", os.path.basename(debug_file_path)
|
||||
)
|
||||
if os.path.exists(export_dir_path):
|
||||
debug_file_path = os.path.abspath(export_dir_path)
|
||||
print(f"Archivo encontrado en path alternativo: {debug_file_path}")
|
||||
else:
|
||||
return
|
||||
|
||||
# El directorio de entrada y salida es el del archivo de debug
|
||||
input_directory = os.path.dirname(debug_file_path)
|
||||
scl_output_dir = input_directory
|
||||
|
||||
print(f"Directorio de análisis para interfaces: {input_directory}")
|
||||
print(f"Directorio de salida para .SCL: {scl_output_dir}")
|
||||
|
||||
# PRIMERA PASADA: Recopilar interfaces de TODOS los archivos .EXP en el directorio
|
||||
function_registry, _ = collect_function_interfaces(input_directory, debug_mode=True)
|
||||
|
||||
if function_registry.functions or function_registry.function_blocks:
|
||||
print("\n🔧 REGISTRY DE FUNCIONES PARA EL DEBUG:")
|
||||
function_registry.print_summary()
|
||||
|
||||
# SEGUNDA PASADA: Procesar solo el archivo de debug
|
||||
print("\n=== SEGUNDA PASADA (DEBUG): CONVIRTIENDO ARCHIVO ÚNICO ===")
|
||||
filename = os.path.basename(debug_file_path)
|
||||
base_name = os.path.splitext(filename)[0]
|
||||
scl_filename = f"{base_name}.scl"
|
||||
scl_output_path = os.path.join(scl_output_dir, scl_filename)
|
||||
|
||||
print(f"{'='*60}")
|
||||
print(f"Procesando: {filename}")
|
||||
print(f"Salida: {scl_output_path}")
|
||||
|
||||
try:
|
||||
converter = SimpleLadConverter(function_registry)
|
||||
converter.parse_file(debug_file_path)
|
||||
|
||||
print(f" ✓ Redes encontradas: {len(converter.networks)}")
|
||||
print(f" ✓ Secciones de variables: {list(converter.var_sections.keys())}")
|
||||
print(f" ✓ ACTIONs encontradas: {list(converter.actions.keys())}")
|
||||
|
||||
converter.print_debug_info()
|
||||
converter.optimize_expressions()
|
||||
converter.group_common_conditions()
|
||||
|
||||
print(f" Generando código SCL...")
|
||||
structured_code = converter.save_to_file(scl_output_path)
|
||||
|
||||
# Mostrar código por stdout como fue solicitado
|
||||
print("\n\n=== CÓDIGO SCL GENERADO (STDOUT) ===")
|
||||
print(structured_code)
|
||||
print("====================================")
|
||||
|
||||
print(f"\n ✓ Guardado en: {scl_output_path}")
|
||||
|
||||
except Exception as e:
|
||||
print(f" ✗ Error procesando {filename}: {e}")
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
|
||||
print(f"\n✓ Proceso de debug finalizado.")
|
||||
|
||||
|
||||
def run_mass_conversion():
|
||||
"""Ejecuta el convertidor en modo masivo usando la configuración global."""
|
||||
print("=== Convertidor Masivo LAD a SCL con SymPy (2 Pasadas) ===")
|
||||
|
||||
# Cargar configuración
|
||||
configs = load_configuration()
|
||||
|
||||
# Verificar que se cargó correctamente
|
||||
if not configs:
|
||||
print(
|
||||
"Advertencia: No se pudo cargar la configuración, usando valores por defecto"
|
||||
)
|
||||
working_directory = "./"
|
||||
scl_output_dir = "scl"
|
||||
debug_mode = True
|
||||
show_optimizations = True
|
||||
show_generated_code = False
|
||||
max_display_lines = 50
|
||||
force_regenerate = False
|
||||
level1_config = {}
|
||||
level2_config = {}
|
||||
level3_config = {}
|
||||
else:
|
||||
print("Error: No se pudo cargar la configuración. Abortando.")
|
||||
return
|
||||
|
||||
# Obtener configuraciones
|
||||
working_directory = configs.get("working_directory", "./")
|
||||
level1_config = configs.get("level1", {})
|
||||
level2_config = configs.get("level2", {})
|
||||
level3_config = configs.get("level3", {})
|
||||
|
||||
# Parámetros de configuración
|
||||
debug_mode = level1_config.get("debug_mode", True)
|
||||
show_optimizations = level1_config.get("show_optimizations", True)
|
||||
scl_output_dir = level2_config.get("scl_output_dir", "scl")
|
||||
backup_existing = level2_config.get("backup_existing", True)
|
||||
show_generated_code = level2_config.get("show_generated_code", False)
|
||||
max_display_lines = level2_config.get("max_display_lines", 50)
|
||||
force_regenerate = level2_config.get("force_regenerate", False)
|
||||
input_directory = level3_config.get("twincat_exp_directory", working_directory)
|
||||
sympy_optimization = level3_config.get("sympy_optimization", True)
|
||||
group_analysis = level3_config.get("group_analysis", True)
|
||||
force_regenerate = level2_config.get(
|
||||
"force_regenerate", False
|
||||
) # Nueva opción
|
||||
|
||||
# Directorio de entrada para archivos .EXP
|
||||
# En modo debug, usar el directorio actual si no hay configuración específica
|
||||
if debug_file:
|
||||
# Modo debug: usar directorio actual donde están los archivos EXP
|
||||
input_directory = os.path.dirname(os.path.abspath(__file__))
|
||||
# Buscar directorio ExportTwinCat si existe
|
||||
export_dir = os.path.join(input_directory, "../ExportTwinCat")
|
||||
if os.path.exists(export_dir):
|
||||
input_directory = os.path.abspath(export_dir)
|
||||
print(f"Detectado directorio ExportTwinCat: {input_directory}")
|
||||
else:
|
||||
print(f"Usando directorio actual: {input_directory}")
|
||||
else:
|
||||
# Modo normal: usar configuración
|
||||
input_directory = level3_config.get(
|
||||
"twincat_exp_directory", working_directory
|
||||
)
|
||||
|
||||
# Verificar directorio de trabajo
|
||||
if not os.path.exists(working_directory):
|
||||
print(f"Error: El directorio de trabajo no existe: {working_directory}")
|
||||
return
|
||||
|
||||
# Verificar directorio de entrada
|
||||
if not os.path.exists(input_directory):
|
||||
print(f"Error: El directorio de entrada no existe: {input_directory}")
|
||||
return
|
||||
|
||||
# Crear directorio de salida SCL
|
||||
full_scl_path = os.path.join(working_directory, scl_output_dir)
|
||||
if not os.path.exists(full_scl_path):
|
||||
os.makedirs(full_scl_path)
|
||||
print(f"Directorio creado: {full_scl_path}")
|
||||
|
||||
# PRIMERA PASADA: Recopilar interfaces de funciones
|
||||
# IMPORTANTE: Siempre hacer primera pasada, incluso en modo debug
|
||||
print(f"Directorio para primera pasada: {input_directory}")
|
||||
function_registry, function_files = collect_function_interfaces(
|
||||
input_directory, debug_mode
|
||||
)
|
||||
function_registry, _ = collect_function_interfaces(input_directory, debug_mode)
|
||||
|
||||
# Determinar archivos a procesar
|
||||
if debug_file:
|
||||
# Modo debug - archivo específico
|
||||
if not debug_file.endswith(".EXP"):
|
||||
debug_file += ".EXP"
|
||||
|
||||
debug_file_path = os.path.join(input_directory, debug_file)
|
||||
if not os.path.exists(debug_file_path):
|
||||
print(f"Error: No se encontró el archivo {debug_file_path}")
|
||||
return
|
||||
|
||||
exp_files = [debug_file_path]
|
||||
print(f"🔍 MODO DEBUG ACTIVADO")
|
||||
print(f"Procesando archivo específico: {debug_file}")
|
||||
print(f"Directorio de entrada: {input_directory}")
|
||||
print(f"Directorio de salida SCL: {full_scl_path}")
|
||||
print(f"Funciones en registry: {len(function_registry.functions)}")
|
||||
print(
|
||||
f"Function Blocks en registry: {len(function_registry.function_blocks)}"
|
||||
)
|
||||
|
||||
# En modo debug, forzar regeneración y mostrar más información
|
||||
force_regenerate = True
|
||||
debug_mode = True
|
||||
show_generated_code = True
|
||||
max_display_lines = 100
|
||||
|
||||
# Mostrar información detallada del registry en modo debug
|
||||
if function_registry.functions:
|
||||
print("\n🔧 FUNCIONES DETECTADAS:")
|
||||
for name, func_info in function_registry.functions.items():
|
||||
print(f" ✓ {name}: {func_info.return_type}")
|
||||
if func_info.inputs:
|
||||
print(f" IN: {[f'{n}:{t}' for n, t in func_info.inputs]}")
|
||||
if func_info.outputs:
|
||||
print(f" OUT: {[f'{n}:{t}' for n, t in func_info.outputs]}")
|
||||
print()
|
||||
else:
|
||||
# Modo normal - todos los archivos
|
||||
# SEGUNDA PASADA: Procesar todos los archivos
|
||||
exp_pattern = os.path.join(input_directory, "*.EXP")
|
||||
exp_files = glob.glob(exp_pattern)
|
||||
|
||||
|
@ -2266,15 +2290,11 @@ def main():
|
|||
print(f"No se encontraron archivos .EXP en: {input_directory}")
|
||||
return
|
||||
|
||||
print(f"Encontrados {len(exp_files)} archivos .EXP en: {input_directory}")
|
||||
print(f"\nEncontrados {len(exp_files)} archivos .EXP en: {input_directory}")
|
||||
print(f"Directorio de salida SCL: {full_scl_path}")
|
||||
print("\n=== SEGUNDA PASADA: CONVERSIÓN CON INTERFACES CONOCIDAS ===")
|
||||
|
||||
print()
|
||||
print("=== SEGUNDA PASADA: CONVERSIÓN CON INTERFACES CONOCIDAS ===")
|
||||
|
||||
# Procesar cada archivo
|
||||
successful_conversions = 0
|
||||
failed_conversions = 0
|
||||
successful_conversions, failed_conversions = 0, 0
|
||||
|
||||
for exp_file in exp_files:
|
||||
filename = os.path.basename(exp_file)
|
||||
|
@ -2282,50 +2302,29 @@ def main():
|
|||
scl_filename = f"{base_name}.scl"
|
||||
scl_output_path = os.path.join(full_scl_path, scl_filename)
|
||||
|
||||
# Verificar si ya existe el archivo SCL (exportación progresiva)
|
||||
if os.path.exists(scl_output_path) and not force_regenerate:
|
||||
print(f"{'='*60}")
|
||||
print(f"SALTANDO: {filename} - Ya existe {scl_filename}")
|
||||
print(
|
||||
f" (usa force_regenerate: true en configuración para forzar regeneración)"
|
||||
f"SALTANDO: {filename} - Ya existe. (Usar 'force_regenerate: true' para sobreescribir)"
|
||||
)
|
||||
successful_conversions += 1 # Contar como exitoso
|
||||
successful_conversions += 1
|
||||
continue
|
||||
|
||||
print(f"{'='*60}")
|
||||
print(f"Procesando: {filename}")
|
||||
print(f"Salida: {scl_filename}")
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Procesando: {filename} -> {scl_filename}")
|
||||
|
||||
try:
|
||||
# Crear nuevo convertidor para cada archivo CON el registry de funciones
|
||||
converter = SimpleLadConverter(function_registry)
|
||||
|
||||
# Parsear archivo
|
||||
converter.parse_file(exp_file)
|
||||
|
||||
print(f" ✓ Redes encontradas: {len(converter.networks)}")
|
||||
print(
|
||||
f" ✓ Secciones de variables: {list(converter.var_sections.keys())}"
|
||||
)
|
||||
print(f" ✓ ACTIONs encontradas: {list(converter.actions.keys())}")
|
||||
|
||||
# Mostrar información de debug si está habilitado
|
||||
if debug_mode:
|
||||
converter.print_debug_info()
|
||||
|
||||
# Optimizar expresiones con SymPy si está habilitado
|
||||
if sympy_optimization and show_optimizations:
|
||||
converter.optimize_expressions()
|
||||
|
||||
# Analizar agrupación de condiciones si está habilitado
|
||||
if group_analysis and show_optimizations:
|
||||
converter.group_common_conditions()
|
||||
|
||||
# Convertir y guardar
|
||||
print(f" Generando código SCL...")
|
||||
structured_code = converter.save_to_file(scl_output_path)
|
||||
|
||||
# Mostrar parte del código generado si está habilitado
|
||||
if show_generated_code:
|
||||
lines = structured_code.split("\n")
|
||||
display_lines = min(max_display_lines, len(lines))
|
||||
|
@ -2348,24 +2347,31 @@ def main():
|
|||
traceback.print_exc()
|
||||
failed_conversions += 1
|
||||
|
||||
print()
|
||||
|
||||
# Resumen final
|
||||
print(f"{'='*60}")
|
||||
print(f"RESUMEN DE CONVERSIÓN:")
|
||||
print(f" 📋 Funciones registradas: {len(function_registry.functions)}")
|
||||
print(
|
||||
f" 📋 Function Blocks registrados: {len(function_registry.function_blocks)}"
|
||||
)
|
||||
print(f"\n{'='*60}")
|
||||
print(f"RESUMEN DE CONVERSIÓN MASIVA:")
|
||||
print(f" ✓ Exitosas: {successful_conversions}")
|
||||
print(f" ✗ Fallidas: {failed_conversions}")
|
||||
print(f" 📁 Directorio salida: {full_scl_path}")
|
||||
|
||||
if successful_conversions > 0:
|
||||
print(f"\n✓ Conversión masiva completada!")
|
||||
|
||||
def main():
|
||||
"""Función principal - Despachador para modo debug o masivo."""
|
||||
try:
|
||||
import time
|
||||
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
print("=== SCRIPT VERIFICADO Y EJECUTÁNDOSE CORRECTAMENTE ===")
|
||||
print(f"🕒 Timestamp: {timestamp}")
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
# Modo debug si hay argumentos en la línea de comandos
|
||||
run_debug_mode(sys.argv[1])
|
||||
else:
|
||||
# Modo masivo por defecto
|
||||
run_mass_conversion()
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error general: {e}")
|
||||
print(f"Error general en main: {e}")
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
|
|
5397
data/log.txt
5397
data/log.txt
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue