Agregado de Volt a Valores Actuales
This commit is contained in:
parent
1266fa705d
commit
0caea3ddc0
|
@ -8,9 +8,13 @@
|
|||
"max_brix_map": "80",
|
||||
"adam_address": "01",
|
||||
"function_type": "Manual",
|
||||
"cycle_time": "10.0",
|
||||
"cycle_time": "3",
|
||||
"samples_per_cycle": "100",
|
||||
"manual_brix": "10.0",
|
||||
"netcom_com_port": "COM9",
|
||||
"netcom_baud_rate": "9600"
|
||||
"manual_input_type": "Brix",
|
||||
"manual_value": "0.00",
|
||||
"netcom_com_port": "COM11",
|
||||
"netcom_baud_rate": "9600",
|
||||
"netcom_rtscts": false,
|
||||
"netcom_dsrdtr": false,
|
||||
"netcom_xonxoff": false
|
||||
}
|
|
@ -31,6 +31,29 @@ class SimulatorTab:
|
|||
self.ma_data = deque(maxlen=self.max_points)
|
||||
self.start_time = time.time()
|
||||
|
||||
# Cargar configuración inicial para obtener valores por defecto para StringVars
|
||||
# Esto es para asegurar que las StringVars tengan un valor inicial antes de que set_config sea llamado
|
||||
# por maselli_app.py.
|
||||
initial_config = self.shared_config['config_manager'].load_config()
|
||||
|
||||
self.adam_address_var = tk.StringVar(value=initial_config.get('adam_address', '01'))
|
||||
self.function_type_var = tk.StringVar(value=initial_config.get('function_type', 'Lineal'))
|
||||
self.cycle_time_var = tk.StringVar(value=initial_config.get('cycle_time', '10.0'))
|
||||
self.samples_per_cycle_var = tk.StringVar(value=initial_config.get('samples_per_cycle', '100'))
|
||||
|
||||
self.manual_input_type_var = tk.StringVar(value=initial_config.get('manual_input_type', 'Brix'))
|
||||
self.manual_value_var = tk.StringVar(value=initial_config.get('manual_value', '10.0'))
|
||||
|
||||
try:
|
||||
manual_value_float = float(initial_config.get('manual_value', '10.0'))
|
||||
except ValueError:
|
||||
manual_value_float = 10.0 # Fallback
|
||||
self.manual_slider_var = tk.DoubleVar(value=manual_value_float)
|
||||
|
||||
self.current_brix_var = tk.StringVar(value="---")
|
||||
self.current_ma_var = tk.StringVar(value="--.-- mA")
|
||||
self.current_voltage_var = tk.StringVar(value="-.-- V") # Nueva para voltaje
|
||||
|
||||
self.create_widgets()
|
||||
|
||||
def create_widgets(self):
|
||||
|
@ -41,13 +64,13 @@ class SimulatorTab:
|
|||
|
||||
# Dirección ADAM
|
||||
ttk.Label(config_frame, text="ADAM Address (2c):").grid(row=0, column=0, padx=5, pady=5, sticky="w")
|
||||
self.adam_address_var = tk.StringVar(value=self.shared_config.get('adam_address', '01'))
|
||||
# self.adam_address_var inicializada en __init__
|
||||
self.adam_address_entry = ttk.Entry(config_frame, textvariable=self.adam_address_var, width=5)
|
||||
self.adam_address_entry.grid(row=0, column=1, padx=5, pady=5, sticky="ew")
|
||||
|
||||
# Función
|
||||
ttk.Label(config_frame, text="Función:").grid(row=0, column=2, padx=5, pady=5, sticky="w")
|
||||
self.function_type_var = tk.StringVar(value=self.shared_config.get('function_type', 'Lineal'))
|
||||
# self.function_type_var inicializada en __init__
|
||||
self.function_type_combo = ttk.Combobox(config_frame, textvariable=self.function_type_var,
|
||||
values=["Lineal", "Sinusoidal", "Manual"],
|
||||
state="readonly", width=10)
|
||||
|
@ -56,37 +79,45 @@ class SimulatorTab:
|
|||
|
||||
# Tiempo de ciclo completo (nueva característica)
|
||||
ttk.Label(config_frame, text="Tiempo Ciclo (s):").grid(row=0, column=4, padx=5, pady=5, sticky="w")
|
||||
self.cycle_time_var = tk.StringVar(value=self.shared_config.get('cycle_time', '10.0'))
|
||||
# self.cycle_time_var inicializada en __init__
|
||||
self.cycle_time_entry = ttk.Entry(config_frame, textvariable=self.cycle_time_var, width=8)
|
||||
self.cycle_time_entry.grid(row=0, column=5, padx=5, pady=5, sticky="ew")
|
||||
|
||||
# Velocidad de muestreo (calculada automáticamente)
|
||||
ttk.Label(config_frame, text="Muestras/ciclo:").grid(row=0, column=6, padx=5, pady=5, sticky="w")
|
||||
self.samples_per_cycle_var = tk.StringVar(value="100")
|
||||
# self.samples_per_cycle_var inicializada en __init__
|
||||
self.samples_per_cycle_entry = ttk.Entry(config_frame, textvariable=self.samples_per_cycle_var, width=8)
|
||||
self.samples_per_cycle_entry.grid(row=0, column=7, padx=5, pady=5, sticky="ew")
|
||||
|
||||
# Frame para modo Manual
|
||||
# --- Frame para modo Manual (Modificado) ---
|
||||
manual_frame = ttk.LabelFrame(config_frame, text="Modo Manual")
|
||||
manual_frame.grid(row=1, column=0, columnspan=8, padx=5, pady=5, sticky="ew")
|
||||
|
||||
ttk.Label(manual_frame, text="Valor Brix:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
|
||||
self.manual_brix_var = tk.StringVar(value=self.shared_config.get('manual_brix', '10.0'))
|
||||
self.manual_brix_entry = ttk.Entry(manual_frame, textvariable=self.manual_brix_var, width=10, state=tk.DISABLED)
|
||||
self.manual_brix_entry.grid(row=0, column=1, padx=5, pady=5, sticky="ew")
|
||||
self.manual_brix_entry.bind('<Return>', lambda e: self.update_slider_from_entry())
|
||||
self.manual_brix_entry.bind('<FocusOut>', lambda e: self.update_slider_from_entry())
|
||||
ttk.Label(manual_frame, text="Entrada Por:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
|
||||
# self.manual_input_type_var inicializada en __init__
|
||||
self.manual_input_type_combo = ttk.Combobox(manual_frame, textvariable=self.manual_input_type_var,
|
||||
values=["Brix", "mA", "Voltaje"], state="readonly", width=8)
|
||||
self.manual_input_type_combo.grid(row=0, column=1, padx=5, pady=5, sticky="ew")
|
||||
self.manual_input_type_combo.bind("<<ComboboxSelected>>", self.on_manual_input_type_change)
|
||||
|
||||
self.manual_value_label = ttk.Label(manual_frame, text="Valor Brix:") # Se actualiza dinámicamente
|
||||
self.manual_value_label.grid(row=1, column=0, padx=5, pady=5, sticky="w")
|
||||
|
||||
# self.manual_value_var y self.manual_slider_var inicializadas en __init__
|
||||
self.manual_value_entry = ttk.Entry(manual_frame, textvariable=self.manual_value_var, width=10, state=tk.DISABLED)
|
||||
self.manual_value_entry.grid(row=1, column=1, padx=5, pady=5, sticky="ew")
|
||||
self.manual_value_entry.bind('<Return>', lambda e: self.update_slider_from_entry())
|
||||
self.manual_value_entry.bind('<FocusOut>', lambda e: self.update_slider_from_entry())
|
||||
|
||||
# Slider
|
||||
self.manual_slider_var = tk.DoubleVar(value=float(self.shared_config.get('manual_brix', '10.0')))
|
||||
self.manual_slider = ttk.Scale(manual_frame, from_=0, to=100, orient=tk.HORIZONTAL,
|
||||
self.manual_slider = ttk.Scale(manual_frame, orient=tk.HORIZONTAL, # from_ y to_ se configuran dinámicamente
|
||||
variable=self.manual_slider_var, command=self.on_slider_change,
|
||||
state=tk.DISABLED, length=200)
|
||||
self.manual_slider.grid(row=0, column=2, padx=5, pady=5, sticky="ew")
|
||||
self.manual_slider.grid(row=1, column=2, padx=5, pady=5, sticky="ew")
|
||||
|
||||
self.manual_send_button = ttk.Button(manual_frame, text="Enviar Manual",
|
||||
command=self.send_manual_value, state=tk.DISABLED)
|
||||
self.manual_send_button.grid(row=0, column=3, padx=5, pady=5, sticky="ew")
|
||||
self.manual_send_button.grid(row=1, column=3, padx=5, pady=5, sticky="ew")
|
||||
|
||||
manual_frame.columnconfigure(2, weight=1)
|
||||
|
||||
|
@ -108,15 +139,20 @@ class SimulatorTab:
|
|||
display_frame.grid(row=1, column=1, padx=10, pady=5, sticky="ew")
|
||||
|
||||
ttk.Label(display_frame, text="Brix:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
|
||||
self.current_brix_var = tk.StringVar(value="---")
|
||||
# self.current_brix_var inicializada en __init__
|
||||
ttk.Label(display_frame, textvariable=self.current_brix_var,
|
||||
font=("Courier", 14, "bold")).grid(row=0, column=1, padx=5, pady=5, sticky="w")
|
||||
|
||||
ttk.Label(display_frame, text="mA:").grid(row=1, column=0, padx=5, pady=5, sticky="w")
|
||||
self.current_ma_var = tk.StringVar(value="--.-- mA")
|
||||
# self.current_ma_var inicializada en __init__
|
||||
ttk.Label(display_frame, textvariable=self.current_ma_var,
|
||||
font=("Courier", 14, "bold")).grid(row=1, column=1, padx=5, pady=5, sticky="w")
|
||||
|
||||
ttk.Label(display_frame, text="Voltaje:").grid(row=2, column=0, padx=5, pady=5, sticky="w")
|
||||
# self.current_voltage_var inicializada en __init__
|
||||
ttk.Label(display_frame, textvariable=self.current_voltage_var,
|
||||
font=("Courier", 14, "bold")).grid(row=2, column=1, padx=5, pady=5, sticky="w")
|
||||
|
||||
# Log Frame
|
||||
log_frame = ttk.LabelFrame(self.frame, text="Log de Comunicación")
|
||||
log_frame.grid(row=2, column=0, columnspan=2, padx=10, pady=5, sticky="nsew")
|
||||
|
@ -127,7 +163,7 @@ class SimulatorTab:
|
|||
# Configurar pesos
|
||||
self.frame.columnconfigure(0, weight=1)
|
||||
self.frame.columnconfigure(1, weight=1)
|
||||
self.frame.rowconfigure(2, weight=1)
|
||||
self.frame.rowconfigure(2, weight=1) # Log frame
|
||||
|
||||
# Inicializar estado
|
||||
self.on_function_type_change()
|
||||
|
@ -136,7 +172,7 @@ class SimulatorTab:
|
|||
"""Crea y retorna el frame para el gráfico"""
|
||||
graph_frame = ttk.LabelFrame(self.frame, text="Gráfico Simulador")
|
||||
graph_frame.grid(row=3, column=0, columnspan=2, padx=10, pady=5, sticky="nsew")
|
||||
self.frame.rowconfigure(3, weight=1)
|
||||
self.frame.rowconfigure(3, weight=1) # Graph frame
|
||||
return graph_frame
|
||||
|
||||
def on_function_type_change(self, event=None):
|
||||
|
@ -146,7 +182,8 @@ class SimulatorTab:
|
|||
if self.simulating:
|
||||
self.stop_simulation()
|
||||
|
||||
self.manual_brix_entry.config(state=tk.NORMAL)
|
||||
self.manual_input_type_combo.config(state=tk.NORMAL)
|
||||
self.manual_value_entry.config(state=tk.NORMAL)
|
||||
self.manual_send_button.config(state=tk.NORMAL)
|
||||
self.manual_slider.config(state=tk.NORMAL)
|
||||
|
||||
|
@ -154,8 +191,10 @@ class SimulatorTab:
|
|||
self.samples_per_cycle_entry.config(state=tk.DISABLED)
|
||||
self.start_button.config(state=tk.DISABLED)
|
||||
self.stop_button.config(state=tk.DISABLED)
|
||||
self.on_manual_input_type_change() # Configurar según el tipo actual
|
||||
else:
|
||||
self.manual_brix_entry.config(state=tk.DISABLED)
|
||||
self.manual_input_type_combo.config(state=tk.DISABLED)
|
||||
self.manual_value_entry.config(state=tk.DISABLED)
|
||||
self.manual_send_button.config(state=tk.DISABLED)
|
||||
self.manual_slider.config(state=tk.DISABLED)
|
||||
|
||||
|
@ -165,46 +204,128 @@ class SimulatorTab:
|
|||
self.start_button.config(state=tk.NORMAL)
|
||||
self.stop_button.config(state=tk.DISABLED)
|
||||
|
||||
def on_slider_change(self, value):
|
||||
def on_manual_input_type_change(self, event=None):
|
||||
"""Maneja el cambio de tipo de entrada manual (Brix, mA, Voltaje)"""
|
||||
input_type = self.manual_input_type_var.get()
|
||||
min_val, max_val, default_val, label_text, precision = 0, 100, 10.0, "Valor Brix:", 2
|
||||
|
||||
if input_type == "Brix":
|
||||
try:
|
||||
min_val = float(self.shared_config['min_brix_map_var'].get())
|
||||
max_val = float(self.shared_config['max_brix_map_var'].get())
|
||||
if min_val >= max_val: min_val, max_val = 0.0, 80.0 # Fallback
|
||||
default_val = min_val + (max_val - min_val) / 4
|
||||
except (ValueError, KeyError, TypeError):
|
||||
min_val, max_val = 0.0, 80.0
|
||||
default_val = 10.0
|
||||
label_text = "Valor Brix:"
|
||||
precision = 2
|
||||
elif input_type == "mA":
|
||||
min_val, max_val = 0.0, 20.0
|
||||
default_val = 12.0
|
||||
label_text = "Valor mA:"
|
||||
precision = 3
|
||||
elif input_type == "Voltaje":
|
||||
min_val, max_val = 0.0, 10.0
|
||||
default_val = 5.0
|
||||
label_text = "Valor Voltaje:"
|
||||
precision = 2
|
||||
|
||||
self.manual_value_label.config(text=label_text)
|
||||
self.manual_slider.config(from_=min_val, to=max_val)
|
||||
|
||||
try:
|
||||
current_numeric_val = float(self.manual_value_var.get())
|
||||
if not (min_val <= current_numeric_val <= max_val):
|
||||
self.manual_value_var.set(f"{default_val:.{precision}f}")
|
||||
self.manual_slider_var.set(default_val)
|
||||
else:
|
||||
self.manual_slider_var.set(current_numeric_val)
|
||||
self.manual_value_var.set(f"{current_numeric_val:.{precision}f}")
|
||||
except ValueError:
|
||||
self.manual_value_var.set(f"{default_val:.{precision}f}")
|
||||
self.manual_slider_var.set(default_val)
|
||||
|
||||
def on_slider_change(self, value_str):
|
||||
"""Actualiza el valor del entry cuando cambia el slider"""
|
||||
self.manual_brix_var.set(f"{float(value):.1f}")
|
||||
value = float(value_str)
|
||||
input_type = self.manual_input_type_var.get()
|
||||
precision = 2
|
||||
if input_type == "Brix": precision = 2
|
||||
elif input_type == "mA": precision = 3
|
||||
elif input_type == "Voltaje": precision = 2
|
||||
self.manual_value_var.set(f"{value:.{precision}f}")
|
||||
|
||||
def update_slider_from_entry(self):
|
||||
"""Actualiza el slider cuando cambia el entry"""
|
||||
try:
|
||||
value = float(self.manual_brix_var.get())
|
||||
value = max(0, min(100, value))
|
||||
value = float(self.manual_value_var.get())
|
||||
input_type = self.manual_input_type_var.get()
|
||||
min_val, max_val, precision = 0,100,2
|
||||
|
||||
if input_type == "Brix":
|
||||
min_val = float(self.shared_config['min_brix_map_var'].get())
|
||||
max_val = float(self.shared_config['max_brix_map_var'].get())
|
||||
if min_val >= max_val: min_val, max_val = 0.0, 80.0
|
||||
precision = 2
|
||||
elif input_type == "mA": min_val, max_val, precision = 0.0, 20.0, 3
|
||||
elif input_type == "Voltaje": min_val, max_val, precision = 0.0, 10.0, 2
|
||||
|
||||
value = max(min_val, min(max_val, value)) # Clampear al rango
|
||||
self.manual_slider_var.set(value)
|
||||
self.manual_brix_var.set(f"{value:.1f}")
|
||||
except ValueError:
|
||||
pass
|
||||
self.manual_value_var.set(f"{value:.{precision}f}")
|
||||
except (ValueError, KeyError, TypeError):
|
||||
# Si el valor no es un número o shared_config no está listo, resetear al valor del slider
|
||||
current_slider_val = self.manual_slider_var.get()
|
||||
precision_fallback = 2
|
||||
if self.manual_input_type_var.get() == "mA": precision_fallback = 3
|
||||
self.manual_value_var.set(f"{current_slider_val:.{precision_fallback}f}")
|
||||
|
||||
def send_manual_value(self):
|
||||
"""Envía un valor manual único"""
|
||||
try:
|
||||
# Obtener valores de mapeo
|
||||
min_brix = float(self.shared_config['min_brix_map_var'].get())
|
||||
max_brix = float(self.shared_config['max_brix_map_var'].get())
|
||||
min_brix_map = float(self.shared_config['min_brix_map_var'].get())
|
||||
max_brix_map = float(self.shared_config['max_brix_map_var'].get())
|
||||
adam_address = self.adam_address_var.get()
|
||||
|
||||
if len(adam_address) != 2:
|
||||
messagebox.showerror("Error", "La dirección ADAM debe tener 2 caracteres.")
|
||||
return
|
||||
|
||||
manual_brix = float(self.manual_brix_var.get())
|
||||
if min_brix_map >= max_brix_map:
|
||||
messagebox.showerror("Error de Configuración", "Min Brix debe ser menor que Max Brix.")
|
||||
return
|
||||
|
||||
# Crear mensaje
|
||||
message, ma_value = ProtocolHandler.create_adam_message(adam_address, manual_brix, min_brix, max_brix)
|
||||
input_type = self.manual_input_type_var.get()
|
||||
manual_numeric_value = float(self.manual_value_var.get())
|
||||
|
||||
final_brix, final_ma, final_voltage = 0.0, 0.0, 0.0
|
||||
|
||||
if input_type == "Brix":
|
||||
final_brix = manual_numeric_value
|
||||
final_ma = ProtocolHandler.scale_to_ma(final_brix, min_brix_map, max_brix_map)
|
||||
final_voltage = ProtocolHandler.ma_to_voltage(final_ma)
|
||||
elif input_type == "mA":
|
||||
final_ma = manual_numeric_value
|
||||
final_brix = ProtocolHandler.ma_to_brix(final_ma, min_brix_map, max_brix_map)
|
||||
final_voltage = ProtocolHandler.ma_to_voltage(final_ma)
|
||||
elif input_type == "Voltaje":
|
||||
final_voltage = manual_numeric_value
|
||||
final_ma = ProtocolHandler.voltage_to_ma(final_voltage)
|
||||
final_brix = ProtocolHandler.ma_to_brix(final_ma, min_brix_map, max_brix_map)
|
||||
|
||||
message, calculated_ma_from_brix = ProtocolHandler.create_adam_message(adam_address, final_brix, min_brix_map, max_brix_map)
|
||||
|
||||
# Actualizar display
|
||||
self.current_brix_var.set(Utils.format_brix_display(manual_brix))
|
||||
self.current_ma_var.set(Utils.format_ma_display(ma_value))
|
||||
self.current_brix_var.set(Utils.format_brix_display(final_brix))
|
||||
self.current_ma_var.set(Utils.format_ma_display(final_ma))
|
||||
self.current_voltage_var.set(ProtocolHandler.format_voltage_display(final_voltage))
|
||||
|
||||
# Agregar al gráfico
|
||||
self.add_data_point(manual_brix, ma_value)
|
||||
self.add_data_point(final_brix, final_ma)
|
||||
|
||||
# Enviar por conexión temporal
|
||||
# Construct a dictionary of current config values for get_connection_params
|
||||
current_config_values = {
|
||||
'connection_type': self.shared_config['connection_type_var'].get(),
|
||||
'com_port': self.shared_config['com_port_var'].get(),
|
||||
|
@ -223,14 +344,13 @@ class SimulatorTab:
|
|||
|
||||
temp_conn.send_data(message)
|
||||
|
||||
# Intentar leer respuesta
|
||||
response = temp_conn.read_response(timeout=0.5)
|
||||
if response and response.strip():
|
||||
Utils.log_message(self.log_text, f"Respuesta: {ProtocolHandler.format_for_display(response)}")
|
||||
|
||||
parsed = ProtocolHandler.parse_adam_message(response)
|
||||
if parsed:
|
||||
brix_resp = ProtocolHandler.ma_to_brix(parsed['ma'], min_brix, max_brix)
|
||||
brix_resp = ProtocolHandler.ma_to_brix(parsed['ma'], min_brix_map, max_brix_map)
|
||||
Utils.log_message(self.log_text,
|
||||
f" -> Addr: {parsed['address']}, "
|
||||
f"mA: {parsed['ma']:.3f}, "
|
||||
|
@ -243,8 +363,8 @@ class SimulatorTab:
|
|||
temp_conn.close_connection()
|
||||
Utils.log_message(self.log_text, "Conexión cerrada.")
|
||||
|
||||
except ValueError as e:
|
||||
messagebox.showerror("Error", "Valores inválidos en la configuración.")
|
||||
except (ValueError, KeyError, TypeError) as e:
|
||||
messagebox.showerror("Error", f"Valores inválidos en la configuración o entrada: {e}")
|
||||
|
||||
def start_simulation(self):
|
||||
"""Inicia la simulación continua"""
|
||||
|
@ -252,7 +372,6 @@ class SimulatorTab:
|
|||
messagebox.showwarning("Advertencia", "La simulación ya está en curso.")
|
||||
return
|
||||
|
||||
# Validar configuración
|
||||
try:
|
||||
adam_address = self.adam_address_var.get()
|
||||
if len(adam_address) != 2:
|
||||
|
@ -269,13 +388,15 @@ class SimulatorTab:
|
|||
messagebox.showerror("Error", "Las muestras por ciclo deben ser mayor que 0.")
|
||||
return
|
||||
|
||||
except ValueError:
|
||||
messagebox.showerror("Error", "Valores inválidos en la configuración.")
|
||||
# Validar mapeo Brix
|
||||
float(self.shared_config['min_brix_map_var'].get())
|
||||
float(self.shared_config['max_brix_map_var'].get())
|
||||
|
||||
except (ValueError, KeyError, TypeError):
|
||||
messagebox.showerror("Error", "Valores inválidos en la configuración (ADAM, ciclo, muestras o mapeo Brix).")
|
||||
return
|
||||
|
||||
# Abrir conexión
|
||||
try:
|
||||
# Construct a dictionary of current config values for get_connection_params
|
||||
current_config_values = {
|
||||
'connection_type': self.shared_config['connection_type_var'].get(),
|
||||
'com_port': self.shared_config['com_port_var'].get(),
|
||||
|
@ -294,6 +415,7 @@ class SimulatorTab:
|
|||
|
||||
self.simulating = True
|
||||
self.simulation_step = 0
|
||||
self.start_time = time.time() # Reset start time for graph
|
||||
self.start_button.config(state=tk.DISABLED)
|
||||
self.stop_button.config(state=tk.NORMAL)
|
||||
self._set_entries_state(tk.DISABLED)
|
||||
|
@ -318,66 +440,59 @@ class SimulatorTab:
|
|||
self.start_button.config(state=tk.NORMAL)
|
||||
self.stop_button.config(state=tk.DISABLED)
|
||||
self._set_entries_state(tk.NORMAL)
|
||||
self.on_function_type_change()
|
||||
self.on_function_type_change() # Re-evaluar estado de controles manuales
|
||||
|
||||
Utils.log_message(self.log_text, "Simulación detenida.")
|
||||
self.current_brix_var.set("---")
|
||||
self.current_ma_var.set("--.-- mA")
|
||||
self.current_voltage_var.set("-.-- V")
|
||||
|
||||
def run_simulation(self):
|
||||
"""Thread principal de simulación"""
|
||||
try:
|
||||
# Obtener parámetros
|
||||
adam_address = self.adam_address_var.get()
|
||||
min_brix = float(self.shared_config['min_brix_map_var'].get())
|
||||
max_brix = float(self.shared_config['max_brix_map_var'].get())
|
||||
min_brix_map = float(self.shared_config['min_brix_map_var'].get())
|
||||
max_brix_map = float(self.shared_config['max_brix_map_var'].get())
|
||||
function_type = self.function_type_var.get()
|
||||
cycle_time = float(self.cycle_time_var.get())
|
||||
samples_per_cycle = int(self.samples_per_cycle_var.get())
|
||||
|
||||
# Calcular período entre muestras
|
||||
sample_period = cycle_time / samples_per_cycle
|
||||
|
||||
while self.simulating:
|
||||
# Calcular valor actual según la función
|
||||
current_brix = 0.0
|
||||
progress = (self.simulation_step % samples_per_cycle) / samples_per_cycle
|
||||
|
||||
if function_type == "Lineal":
|
||||
# Onda triangular
|
||||
cycle_progress = (self.simulation_step % (2 * samples_per_cycle)) / samples_per_cycle
|
||||
if cycle_progress > 1.0:
|
||||
cycle_progress = 2.0 - cycle_progress
|
||||
current_brix = min_brix + (max_brix - min_brix) * cycle_progress
|
||||
current_brix = min_brix_map + (max_brix_map - min_brix_map) * cycle_progress
|
||||
|
||||
elif function_type == "Sinusoidal":
|
||||
phase = progress * 2 * math.pi
|
||||
sin_val = (math.sin(phase) + 1) / 2
|
||||
current_brix = min_brix + (max_brix - min_brix) * sin_val
|
||||
current_brix = min_brix_map + (max_brix_map - min_brix_map) * sin_val
|
||||
|
||||
# Crear y enviar mensaje
|
||||
message, ma_value = ProtocolHandler.create_adam_message(adam_address, current_brix, min_brix, max_brix)
|
||||
message, ma_value = ProtocolHandler.create_adam_message(adam_address, current_brix, min_brix_map, max_brix_map)
|
||||
voltage_value = ProtocolHandler.ma_to_voltage(ma_value)
|
||||
|
||||
# Actualizar display
|
||||
self.current_brix_var.set(Utils.format_brix_display(current_brix))
|
||||
self.current_ma_var.set(Utils.format_ma_display(ma_value))
|
||||
self.current_voltage_var.set(ProtocolHandler.format_voltage_display(voltage_value))
|
||||
|
||||
# Agregar al gráfico
|
||||
self.frame.after(0, lambda b=current_brix, m=ma_value: self.add_data_point(b, m))
|
||||
|
||||
# Log y envío
|
||||
Utils.log_message(self.log_text, f"Enviando: {ProtocolHandler.format_for_display(message)}")
|
||||
|
||||
try:
|
||||
self.connection_manager.send_data(message)
|
||||
|
||||
# Leer respuesta sin bloquear demasiado
|
||||
response = self.connection_manager.read_response(timeout=0.1)
|
||||
if response and response.strip():
|
||||
Utils.log_message(self.log_text, f"Respuesta: {ProtocolHandler.format_for_display(response)}")
|
||||
|
||||
parsed = ProtocolHandler.parse_adam_message(response)
|
||||
if parsed:
|
||||
brix_resp = ProtocolHandler.ma_to_brix(parsed['ma'], min_brix, max_brix)
|
||||
brix_resp = ProtocolHandler.ma_to_brix(parsed['ma'], min_brix_map, max_brix_map)
|
||||
Utils.log_message(self.log_text,
|
||||
f" -> Addr: {parsed['address']}, "
|
||||
f"mA: {parsed['ma']:.3f}, "
|
||||
|
@ -385,21 +500,22 @@ class SimulatorTab:
|
|||
|
||||
except Exception as e:
|
||||
Utils.log_message(self.log_text, f"Error en comunicación: {e}")
|
||||
self.frame.after(0, self.stop_simulation_error)
|
||||
self.frame.after(0, self.stop_simulation_error) # Schedule GUI update from main thread
|
||||
break
|
||||
|
||||
self.simulation_step += 1
|
||||
time.sleep(sample_period)
|
||||
|
||||
except Exception as e:
|
||||
except Exception as e: # Catches errors in parameter fetching or main loop logic
|
||||
Utils.log_message(self.log_text, f"Error en simulación: {e}")
|
||||
self.frame.after(0, self.stop_simulation_error)
|
||||
if self.simulating: # Ensure stop is called only if an error occurs while simulating
|
||||
self.frame.after(0, self.stop_simulation_error)
|
||||
|
||||
def stop_simulation_error(self):
|
||||
"""Detiene la simulación debido a un error"""
|
||||
if self.simulating:
|
||||
messagebox.showerror("Error", "Error durante la simulación. Simulación detenida.")
|
||||
self.stop_simulation()
|
||||
"""Detiene la simulación debido a un error y muestra mensaje"""
|
||||
if self.simulating: # Solo actuar si la simulación estaba activa
|
||||
messagebox.showerror("Error de Simulación", "Error durante la simulación. Simulación detenida.")
|
||||
self.stop_simulation() # Llama al método normal de parada
|
||||
|
||||
def add_data_point(self, brix_value, ma_value):
|
||||
"""Agrega un punto de datos al gráfico"""
|
||||
|
@ -408,7 +524,6 @@ class SimulatorTab:
|
|||
self.brix_data.append(brix_value)
|
||||
self.ma_data.append(ma_value)
|
||||
|
||||
# Notificar a la aplicación principal para actualizar el gráfico
|
||||
if hasattr(self, 'graph_update_callback'):
|
||||
self.graph_update_callback()
|
||||
|
||||
|
@ -423,15 +538,15 @@ class SimulatorTab:
|
|||
|
||||
def _set_entries_state(self, state):
|
||||
"""Habilita/deshabilita los controles durante la simulación"""
|
||||
widgets = [
|
||||
sim_specific_widgets = [
|
||||
self.adam_address_entry,
|
||||
self.function_type_combo,
|
||||
self.cycle_time_entry,
|
||||
self.samples_per_cycle_entry
|
||||
]
|
||||
Utils.set_widgets_state(widgets, state)
|
||||
# No deshabilitar controles de modo manual aquí, se manejan en on_function_type_change
|
||||
Utils.set_widgets_state(sim_specific_widgets, state)
|
||||
|
||||
# También deshabilitar controles compartidos
|
||||
if 'shared_widgets' in self.shared_config:
|
||||
Utils.set_widgets_state(self.shared_config['shared_widgets'], state)
|
||||
|
||||
|
@ -442,7 +557,8 @@ class SimulatorTab:
|
|||
'function_type': self.function_type_var.get(),
|
||||
'cycle_time': self.cycle_time_var.get(),
|
||||
'samples_per_cycle': self.samples_per_cycle_var.get(),
|
||||
'manual_brix': self.manual_brix_var.get()
|
||||
'manual_input_type': self.manual_input_type_var.get(),
|
||||
'manual_value': self.manual_value_var.get()
|
||||
}
|
||||
|
||||
def set_config(self, config):
|
||||
|
@ -451,11 +567,15 @@ class SimulatorTab:
|
|||
self.function_type_var.set(config.get('function_type', 'Lineal'))
|
||||
self.cycle_time_var.set(config.get('cycle_time', '10.0'))
|
||||
self.samples_per_cycle_var.set(config.get('samples_per_cycle', '100'))
|
||||
self.manual_brix_var.set(config.get('manual_brix', '10.0'))
|
||||
|
||||
self.manual_input_type_var.set(config.get('manual_input_type', 'Brix'))
|
||||
self.manual_value_var.set(config.get('manual_value', '10.0'))
|
||||
|
||||
try:
|
||||
self.manual_slider_var.set(float(config.get('manual_brix', '10.0')))
|
||||
except:
|
||||
self.manual_slider_var.set(float(self.manual_value_var.get()))
|
||||
except ValueError:
|
||||
# Si el valor no es un float válido, intentar con un default o el valor del tipo
|
||||
# Esto se manejará mejor en on_manual_input_type_change
|
||||
pass
|
||||
|
||||
self.on_function_type_change()
|
||||
self.on_function_type_change() # Esto llamará a on_manual_input_type_change si es necesario
|
||||
|
|
Loading…
Reference in New Issue