77 lines
3.4 KiB
Python
77 lines
3.4 KiB
Python
# processors/process_sd.py
|
|
# -*- coding: utf-8 -*-
|
|
import sympy
|
|
import traceback
|
|
# Usar las nuevas utilidades
|
|
from .processor_utils import get_sympy_representation, sympy_expr_to_scl, format_variable_name, get_target_scl_name
|
|
from .symbol_manager import SymbolManager, extract_plc_variable_name
|
|
|
|
SCL_SUFFIX = "_sympy_processed"
|
|
|
|
def process_sd(instruction, network_id, sympy_map, symbol_manager: SymbolManager, data):
|
|
"""
|
|
Genera SCL para Temporizador On-Delay (Sd -> TON).
|
|
Requiere datos de instancia (DB o STAT/TEMP).
|
|
"""
|
|
instr_uid = instruction["instruction_uid"]
|
|
instr_type_original = "Sd" # Tipo original LAD
|
|
if instruction.get("type","").endswith(SCL_SUFFIX) or "_error" in instruction.get("type",""):
|
|
return False
|
|
|
|
# 1. Obtener Inputs: s (start), tv (time value), timer (instance)
|
|
s_info = instruction["inputs"].get("s")
|
|
tv_info = instruction["inputs"].get("tv")
|
|
timer_instance_info = instruction["inputs"].get("timer")
|
|
|
|
sympy_s_expr = get_sympy_representation(s_info, network_id, sympy_map, symbol_manager)
|
|
# tv suele ser constante, pero lo obtenemos igual
|
|
sympy_or_const_tv = get_sympy_representation(tv_info, network_id, sympy_map, symbol_manager)
|
|
# Obtener el nombre de la INSTANCIA (no su valor)
|
|
instance_plc_name = extract_plc_variable_name(timer_instance_info)
|
|
|
|
# Verificar dependencias
|
|
if sympy_s_expr is None or sympy_or_const_tv is None: return False
|
|
if instance_plc_name is None:
|
|
print(f"Error: Sd {instr_uid} sin variable de instancia 'timer'.")
|
|
instance_plc_name = f"#TON_INSTANCE_{instr_uid}" # Placeholder con error implícito
|
|
print(f"Advertencia: Usando placeholder '{instance_plc_name}'. ¡Declarar en SCL!")
|
|
# Podríamos marcar como error, pero intentamos generar algo
|
|
# instruction["type"] = instr_type_original + "_error"
|
|
# return True
|
|
|
|
# Formatear nombre de instancia
|
|
instance_name_scl = format_variable_name(instance_plc_name)
|
|
|
|
# Convertir entradas SymPy/Constante a SCL strings
|
|
s_scl = sympy_expr_to_scl(sympy_s_expr, symbol_manager)
|
|
tv_scl = sympy_expr_to_scl(sympy_or_const_tv, symbol_manager)
|
|
|
|
# Generar la llamada SCL (TON usa IN, PT)
|
|
# Ignoramos 'r' (reset) de Sd
|
|
scl_call = f"{instance_name_scl}(IN := {s_scl}, PT := {tv_scl}); // TODO: Declarar {instance_name_scl} : TON;"
|
|
|
|
# Actualizar instrucción
|
|
instruction["scl"] = scl_call # SCL final generado
|
|
instruction["type"] = instr_type_original + SCL_SUFFIX
|
|
|
|
# 7. Actualizar sympy_map para las salidas Q y RT
|
|
map_key_q = (network_id, instr_uid, "q")
|
|
q_output_scl_access = f"{instance_name_scl}.Q" # SCL string to access output
|
|
# *** GET/CREATE AND STORE SYMBOL for boolean output Q ***
|
|
sympy_q_symbol = symbol_manager.get_symbol(q_output_scl_access)
|
|
if sympy_q_symbol:
|
|
sympy_map[map_key_q] = sympy_q_symbol # STORE THE SYMBOL OBJECT
|
|
else:
|
|
print(f"Error: Could not create symbol for {q_output_scl_access} in Sd {instr_uid}")
|
|
sympy_map[map_key_q] = None # Indicate error/unresolved
|
|
|
|
map_key_rt = (network_id, instr_uid, "rt")
|
|
# ET is TIME, store SCL access string
|
|
sympy_map[map_key_rt] = f"{instance_name_scl}.ET"
|
|
|
|
return True
|
|
|
|
# --- Processor Information Function ---
|
|
def get_processor_info():
|
|
"""Devuelve la información para el temporizador On-Delay (Sd -> TON)."""
|
|
return {'type_name': 'sd', 'processor_func': process_sd, 'priority': 5} |