Simatic_XML_Parser_to_SCL/processors/process_blkmov.py

113 lines
4.9 KiB
Python

# -*- coding: utf-8 -*-
from .processor_utils import get_scl_representation, format_variable_name,get_target_scl_name
# TODO: Import necessary functions from processor_utils
# Example: from .processor_utils import get_scl_representation, format_variable_name
# Or: import processors.processor_utils as utils
# TODO: Define constants if needed (e.g., SCL_SUFFIX) or import them
SCL_SUFFIX = "_scl"
# --- Function code starts ---
def process_blkmov(instruction, network_id, scl_map, access_map, data):
"""
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) ...
# --- Function code ends ---
# --- Processor Information Function ---
def get_processor_info():
"""Devuelve la información para el procesador BLKMOV."""
# Asumiendo que 'BLKMOV' es el type en el JSON simplificado
return {'type_name': 'blkmov', 'processor_func': process_blkmov, 'priority': 6}