From 607e3105b5b6a3be2372e22a058adeef3eefca1f Mon Sep 17 00:00:00 2001 From: Miguel Date: Sat, 19 Apr 2025 02:02:30 +0200 Subject: [PATCH] BLKMOV Funcionando --- TestLAD_simplified_processed.json | 5 +- TestLAD_simplified_processed.scl | 3 + x2_process.py | 99 +++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 2 deletions(-) diff --git a/TestLAD_simplified_processed.json b/TestLAD_simplified_processed.json index cb55b91..b2aaa83 100644 --- a/TestLAD_simplified_processed.json +++ b/TestLAD_simplified_processed.json @@ -70,7 +70,7 @@ { "instruction_uid": "26", "uid": "26", - "type": "BLKMOV", + "type": "BLKMOV_scl", "template_values": { "blk_type": "Type" }, @@ -106,7 +106,8 @@ "name": "\"Filler_Head_Variables\".\"FillerHead\"" } ] - } + }, + "scl": "IF \"AUX FALSE\" THEN\n \"Block_Move_Err\" := BLKMOV(SRCBLK := \"HMI_PID\".\"PPM303\", DSTBLK => \"Filler_Head_Variables\".\"FillerHead\"); // ADVERTENCIA: BLKMOV usado directamente, probablemente no compile!\nEND_IF;" } ] } diff --git a/TestLAD_simplified_processed.scl b/TestLAD_simplified_processed.scl index a7e9b16..724eee4 100644 --- a/TestLAD_simplified_processed.scl +++ b/TestLAD_simplified_processed.scl @@ -30,5 +30,8 @@ BEGIN // Network 1: Filler Head // RLO: "AUX FALSE" + IF "AUX FALSE" THEN + "Block_Move_Err" := BLKMOV(SRCBLK := "HMI_PID"."PPM303", DSTBLK => "Filler_Head_Variables"."FillerHead"); // ADVERTENCIA: BLKMOV usado directamente, probablemente no compile! + END_IF; END_FUNCTION_BLOCK diff --git a/x2_process.py b/x2_process.py index fb8bd98..ba0c6c6 100644 --- a/x2_process.py +++ b/x2_process.py @@ -772,6 +772,102 @@ def process_move(instruction, network_id, scl_map, access_map): # print(f"DEBUG Edge: {instr_type_original} UID {instr_uid} procesado exitosamente.") # Debug return True # Indicar que se procesó +# EN x2_process.py + +def process_blkmov(instruction, network_id, scl_map, access_map): + """ + Genera SCL usando BLKMOV directamente como nombre de función, + sin COUNT y con formato específico, según solicitud del usuario. + ADVERTENCIA: Es MUY PROBABLE que esto NO compile en TIA Portal estándar, + ya que BLKMOV no es una función SCL y MOVE_BLK requiere COUNT. + """ + instr_uid = instruction["instruction_uid"] + instr_type = instruction["type"] + if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: + return False # Ya procesado o con error + + # --- Obtener Entradas --- + en_input = instruction["inputs"].get("en") + en_scl = ( + get_scl_representation(en_input, network_id, scl_map, access_map) + if en_input + else "TRUE" + ) + srcblk_info = instruction["inputs"].get("SRCBLK") + # ¡IMPORTANTE! Obtenemos el nombre RAW antes de formatearlo para usarlo como pide el usuario + raw_srcblk_name = srcblk_info.get("name") if srcblk_info else None + + # Verificar dependencias de entrada (solo necesitamos que EN esté resuelto) + if en_scl is None: + return False # Dependencia EN no lista + if raw_srcblk_name is None: + print(f"Error: BLKMOV {instr_uid} sin información válida para SRCBLK.") + instruction["scl"] = f"// ERROR: BLKMOV {instr_uid} sin SRCBLK válido." + instruction["type"] += "_error" + return True + + # --- Obtener Destinos (Salidas) --- + # RET_VAL (Usamos get_target_scl_name para manejar variables temporales si es necesario) + retval_target_scl = get_target_scl_name( + instruction, "RET_VAL", network_id, default_to_temp=True + ) + if retval_target_scl is None: + print(f"Error: BLKMOV {instr_uid} sin destino claro para RET_VAL.") + instruction["scl"] = f"// ERROR: BLKMOV {instr_uid} sin destino RET_VAL" + instruction["type"] += "_error" + return True + + # DSTBLK (Obtenemos el nombre RAW para usarlo como pide el usuario) + raw_dstblk_name = None + dstblk_output_list = instruction.get("outputs", {}).get("DSTBLK", []) + if dstblk_output_list and isinstance(dstblk_output_list, list) and len(dstblk_output_list) == 1: + dest_access = dstblk_output_list[0] + if dest_access.get("type") == "variable": + raw_dstblk_name = dest_access.get("name") # Nombre raw del JSON + else: + print(f"Advertencia: Destino DSTBLK de BLKMOV {instr_uid} no es una variable (Tipo: {dest_access.get('type')}).") + else: + print(f"Error: No se encontró un destino único y válido para DSTBLK en BLKMOV {instr_uid}.") + + if raw_dstblk_name is None: + instruction["scl"] = f"// ERROR: BLKMOV {instr_uid} sin destino DSTBLK válido." + instruction["type"] += "_error" + return True + + # --- Formateo especial para SRCBLK/DSTBLK como pidió el usuario --- + # Asume formato "DB".Variable o "Struct".Variable del JSON y lo mantiene + # (Esto anula la limpieza normal de format_variable_name para estos parámetros) + srcblk_final_str = raw_srcblk_name if raw_srcblk_name else "_ERROR_SRC_" + dstblk_final_str = raw_dstblk_name if raw_dstblk_name else "_ERROR_DST_" + + # --- Generar SCL Exacto Solicitado --- + scl_core = ( + f"{retval_target_scl} := BLKMOV(SRCBLK := {srcblk_final_str}, " + f"DSTBLK => {dstblk_final_str}); " + f"// ADVERTENCIA: BLKMOV usado directamente, probablemente no compile!" + ) + + # Añadir condición EN (usando la representación SCL obtenida para EN) + scl_final = ( + f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" if en_scl != "TRUE" else scl_core + ) + + # --- Actualizar Instrucción y Mapa SCL --- + instruction["scl"] = scl_final + instruction["type"] = instr_type + SCL_SUFFIX + + # Propagar ENO (igual que EN) + map_key_eno = (network_id, instr_uid, "eno") + scl_map[map_key_eno] = en_scl + + # Propagar el valor de retorno (el contenido de la variable asignada a RET_VAL) + map_key_ret_val = (network_id, instr_uid, "RET_VAL") + scl_map[map_key_ret_val] = retval_target_scl # El valor es lo que sea que se asigne + + return True + +# ... (Asegúrate de que esta función está registrada en processor_map como antes) ... + def process_o(instruction, network_id, scl_map, access_map): instr_uid = instruction["instruction_uid"] instr_type = instruction["type"] @@ -1177,6 +1273,7 @@ def process_json_to_scl(json_filepath): base_processors = [ process_convert, process_mod, + process_blkmov, process_eq, process_contact, process_o, @@ -1200,6 +1297,8 @@ def process_json_to_scl(json_filepath): elif type_name == "edge_detector": # Mapear PBox y NBox a la nueva función processor_map["pbox"] = func processor_map["nbox"] = func + elif type_name == "blkmov": + processor_map[type_name] = process_blkmov # Usar la nueva función BLKMOV else: processor_map[type_name] = func