import grovepi
import time
import math
from datetime import datetime
import tkinter as tk
from tkinter import ttk, messagebox
import threading
import os
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

# --- TUS VALORES R0 CALCULADOS ---
R0_MQ7 = 5451.23
R0_MQ4 = 21159.60
R0_MQ135 = 14967.54
# -----------------------------------

# --- CONFIGURACIÓN DE PINES Y CONSTANTES ---
MQ7_PIN = 0     
MQ4_PIN = 1     
MQ135_PIN = 2   
BUZZER_PIN = 7  
NOMBRE_ARCHIVO = 'database.txt' 
RL_VALUE = 10000.0
MAX_ANALOG = 1023.0
TIEMPO_LECTURA_MS = 1000 

# LÍMITES DE ESCALA PARA MEDIDORES PPM
MAX_CO_DISPLAY = 100        
MAX_PPM_DISPLAY = 2000      

# Variables de control de estado
MEDICION_ACTIVA = False 
ALARMA_ACTIVA = False

# --- VARIABLES GLOBALES DE UMBRAL ---
UMBRAL_CO_DEFECTO = 50.0 
UMBRAL_CH4_DEFECTO = 1000.0 
UMBRAL_AIRE_DEFECTO = 1000.0 

UMBRAL_CO = UMBRAL_CO_DEFECTO
UMBRAL_CH4 = UMBRAL_CH4_DEFECTO
UMBRAL_AIRE = UMBRAL_AIRE_DEFECTO

# --- DECLARACIÓN DE VARIABLES GLOBALES DE WIDGETS ---
# Declaradas para evitar NameError en las funciones
canvas_mq7 = None
canvas_mq4 = None
canvas_mq135 = None
estado_general_label = None
btn_iniciar_mediciones = None
btn_iniciar_inicio = None
notebook = None

# ----------------------------------------------------
# FUNCIONES MATEMÁTICAS Y DE SENSORES
# ----------------------------------------------------

def get_RS_resistance(analog_value):
    if analog_value == 0: return float('inf')
    return RL_VALUE * ((MAX_ANALOG / analog_value) - 1.0)

def MQ7_to_PPM(rs, R0):
    if R0 == 0: return 0.0
    ratio = rs / R0
    if ratio >= 0.783:
        return 10**((math.log10(ratio) - 0.783) / -1.531)
    return 0.0

def MQ4_to_PPM(rs, R0):
    if R0 == 0: return 0.0
    ratio = rs / R0
    if ratio <= 2.5:
        return 10**((math.log10(ratio) - 2.5) / -1.5)
    return 0.0

def MQ135_to_PPM(rs, R0):
    if R0 == 0: return 0.0
    ratio = rs / R0
    if ratio < 0.0000001:
        return 0.0
    if ratio <= 2.5:
        return 10**((math.log10(ratio) - 2.5) / -2.5)
    return 0.0

def calcular_aqi_co(ppm_co):
    """Calcula un AQI simplificado (Mantenido solo por consistencia de la función)."""
    ppm = ppm_co
    
    CO_GOOD_PPM = 4.4
    CO_FAIR_PPM = 9.4
    CO_POOR_PPM = 12.4

    if ppm <= CO_GOOD_PPM:
        aqi = int(round(ppm * (50 / CO_GOOD_PPM)))
    elif ppm <= CO_FAIR_PPM:
        aqi = 51 + int(round(((ppm - CO_GOOD_PPM) / (CO_FAIR_PPM - CO_GOOD_PPM)) * (100 - 51)))
    elif ppm <= CO_POOR_PPM:
        aqi = 101 + int(round(((ppm - CO_FAIR_PPM) / (CO_POOR_PPM - CO_FAIR_PPM)) * (150 - 101)))
    else:
        aqi = 151 + int(ppm * 10) 
    
    return aqi, "N/A", "gray" 


# ----------------------------------------------------
# FUNCIONES DE CONTROL DE LA GUI
# ----------------------------------------------------

def guardar_datos(ppm_7, ppm_4, ppm_135, estado_alarma):
    """Escribe los datos en el archivo database.txt."""
    try:
        timestamp_completo = datetime.now().strftime('%d-%m-%Y | %H:%M:%S')
        
        datos_a_escribir = f"""
FECHA: {timestamp_completo}
ALARMA: {estado_alarma}
---
MQ-7 (CO)   : {ppm_7:.2f} PPM
MQ-4 (CH4)  : {ppm_4:.2f} PPM
MQ-135 (Aire): {ppm_135:.2f} PPM
---------------------------------"""
        
        with open(NOMBRE_ARCHIVO, 'a', encoding="utf-8") as archivo:
            archivo.write(datos_a_escribir)
            archivo.write("\n")

    except Exception as e:
        print(f"Error de escritura en archivo: {e}")

def aplicar_umbrales():
    """Lee y valida los valores de los Entry y los actualiza globalmente."""
    global UMBRAL_CO, UMBRAL_CH4, UMBRAL_AIRE
    try:
        UMBRAL_CO = float(entry_co_var.get())
        UMBRAL_CH4 = float(entry_ch4_var.get())
        UMBRAL_AIRE = float(entry_aire_var.get())
        
        if UMBRAL_CO <= 0 or UMBRAL_CH4 <= 0 or UMBRAL_AIRE <= 0:
            raise ValueError("Los umbrales deben ser mayores que cero.")

        tk.messagebox.showinfo("Configuración", "Umbrales guardados con éxito.")

    except ValueError as e:
        tk.messagebox.showerror("Error de Configuración", f"Valor inválido: {e}. Use números.")

def reset_umbrales():
    """Restaura los umbrales a los valores de seguridad por defecto."""
    entry_co_var.set(UMBRAL_CO_DEFECTO)
    entry_ch4_var.set(UMBRAL_CH4_DEFECTO)
    entry_aire_var.set(UMBRAL_AIRE_DEFECTO)
    aplicar_umbrales() 

def limpiar_historial():
    """Borra el archivo database.txt para iniciar un nuevo historial."""
    if os.path.exists(NOMBRE_ARCHIVO):
        os.remove(NOMBRE_ARCHIVO)
        tk.messagebox.showinfo("Historial", f"Historial '{NOMBRE_ARCHIVO}' limpiado con éxito.")
    else:
        tk.messagebox.showinfo("Historial", "El archivo de historial ya estaba vacío.")

# --- FUNCIONES DE DIBUJO Y NAVEGACIÓN ---

def dibujar_medidor_ppm(canvas, ppm_valor, umbral, max_escala, titulo):
    """Dibuja el medidor radial para un valor PPM dado. (Lógica de umbral corregida)"""
    if canvas is None: return 
    ancho = 200
    alto = 120
    centro_x = ancho / 2
    centro_y = alto 
    radio = 80
    
    canvas.delete("all")
    canvas.config(bg="#F0F0F0") 
    
    escala_angular = 180 / max_escala
    
    # 1. Dibujar el arco de fondo
    canvas.create_arc(centro_x - radio, centro_y - radio, 
                      centro_x + radio, centro_y + radio,
                      start=0, extent=180, style=tk.ARC, outline="#DDDDDD", width=15)
    
    # 2. Ángulo del Valor Medido (Arco verde/rojo)
    angulo_valor_ppm = min(ppm_valor, max_escala) * escala_angular
    angulo_inicio_valor = 180 - angulo_valor_ppm # 180 = 0 PPM
    
    color = "red" if ppm_valor >= umbral else "green"
    
    # Dibujar el arco de valor medido
    canvas.create_arc(centro_x - radio, centro_y - radio, 
                      centro_x + radio, centro_y + radio,
                      start=angulo_inicio_valor, extent=angulo_valor_ppm,
                      style=tk.ARC, outline=color, width=15)

    # 3. Ángulo del Umbral (Línea roja punteada)
    angulo_umbral_total = umbral * escala_angular
    
    # CORRECCIÓN DEFINITIVA: 
    # Queremos que 0 PPM esté en 180 grados. 
    # Queremos que Max PPM esté en 0 grados.
    # El ángulo que necesitamos para cos/sin es 180 - (Valor * Escala)
    angulo_umbral_pos = 180 - angulo_umbral_total
    
    # Convertir a radianes
    rad_umbral = math.radians(angulo_umbral_pos)
    
    # Coordenadas de la punta de la línea de umbral
    punta_x_u = centro_x - (radio - 25) * math.cos(rad_umbral)
    punta_y_u = centro_y - (radio - 25) * math.sin(rad_umbral)
    
    # Dibujar la línea de umbral
    canvas.create_line(centro_x, centro_y, punta_x_u, punta_y_u, 
                       fill="red", width=2, dash=(3, 3)) 
    
    # 4. Dibujar el valor central y etiquetas (Más grande y visible)
    canvas.create_text(centro_x, centro_y - 45, text=titulo, 
                       font=("Helvetica", 12, "bold"), fill="#333333")
    canvas.create_text(centro_x, centro_y - 20, text=f"{ppm_valor:.1f}", 
                       font=("Helvetica", 24, "bold"), fill=color) 
    canvas.create_text(centro_x, centro_y + 5, text="PPM", 
                       font=("Helvetica", 12), fill="#333333") 
    
    canvas.create_text(centro_x - radio - 10, centro_y - 5, text="0", fill="#333333")
    canvas.create_text(centro_x + radio + 5, centro_y - 5, text=str(max_escala), fill="#333333")


def abrir_historial():
    notebook.select(historial_frame)
    generar_grafico() 

def abrir_configuracion():
    notebook.select(opciones_frame)

def abrir_mediciones():
    notebook.select(mediciones_frame)
    
def salir_limpiar():
    grovepi.digitalWrite(BUZZER_PIN, 0)
    root.destroy()
    
# --- Funciones de Medición y Control ---

def iniciar_medicion():
    """Inicia el ciclo de lectura de sensores."""
    global MEDICION_ACTIVA
    if not MEDICION_ACTIVA:
        aplicar_umbrales() 
        MEDICION_ACTIVA = True
        # Actualizar ambos botones de inicio/detención
        btn_iniciar_mediciones.config(text="Detener Medición", command=detener_medicion, style='Red.TButton')
        btn_iniciar_inicio.config(text="Detener Medición", command=detener_medicion, style='Red.TButton')
        estado_general_label.config(text="Monitor Activo", background="blue")
        root.after(0, actualizar_sensores) # Inicia el bucle de Tkinter

def detener_medicion():
    """Detiene el ciclo de lectura de sensores."""
    global MEDICION_ACTIVA
    MEDICION_ACTIVA = False
    # Actualizar ambos botones de inicio/detención
    btn_iniciar_mediciones.config(text="Empezar Medición", command=iniciar_medicion, style='Green.TButton')
    btn_iniciar_inicio.config(text="Empezar Medición", command=iniciar_medicion, style='Green.TButton')
    estado_general_label.config(text="Monitor Detenido", background="gray")


# ----------------------------------------------------
# GENERACIÓN DE GRÁFICOS (Se mantiene igual)
# ----------------------------------------------------

def generar_grafico():
    """Lee el archivo de texto y genera TRES gráficos con Matplotlib, con escala optimizada."""
    
    def leer_datos_y_estructurar_todos():
        datos = []
        try:
            with open(NOMBRE_ARCHIVO, 'r', encoding='utf-8') as f:
                contenido = f.read()
            
            patrones = contenido.split("---------------------------------")
            for patron in patrones:
                if 'MQ-7 (CO)' in patron:
                    try:
                        fecha_str = patron.split("FECHA: ")[1].split('\n')[0].strip()
                        
                        ppm_7 = float(patron.split('MQ-7 (CO)   : ')[1].split(' PPM')[0].strip())
                        ppm_4 = float(patron.split('MQ-4 (CH4)  : ')[1].split(' PPM')[0].strip())
                        ppm_135 = float(patron.split('MQ-135 (Aire): ')[1].split(' PPM')[0].strip())
                        
                        fecha = datetime.strptime(fecha_str, '%d-%m-%Y | %H:%M:%S')
                        
                        datos.append({
                            'Fecha': fecha, 'PPM_CO': ppm_7, 'PPM_CH4': ppm_4, 'PPM_AIRE': ppm_135
                        })
                    except Exception:
                        continue 
        except FileNotFoundError:
            return pd.DataFrame({'Fecha': [], 'PPM_CO': [], 'PPM_CH4': [], 'PPM_AIRE': []})
        
        return pd.DataFrame(datos)

    df = leer_datos_y_estructurar_todos()
    
    if df.empty:
        tk.messagebox.showwarning("Gráfico", "No hay datos suficientes para graficar.")
        return

    # 2. Configurar Matplotlib para Tkinter (Figura con 3 subplots)
    fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(8, 8)) 
    plt.subplots_adjust(hspace=0.4) 

    # 3. Datos y Umbrales
    sensores_info = [
        {'col': 'PPM_CO', 'titulo': 'MQ-7 (Monóxido de Carbono)', 'umbral': UMBRAL_CO},
        {'col': 'PPM_CH4', 'titulo': 'MQ-4 (Metano)', 'umbral': UMBRAL_CH4},
        {'col': 'PPM_AIRE', 'titulo': 'MQ-135 (Calidad del Aire)', 'umbral': UMBRAL_AIRE}
    ]

    # 4. Generar cada gráfico
    for i, info in enumerate(sensores_info):
        ax = axes[i]
        
        ax.plot(df['Fecha'], df[info['col']], marker='', linestyle='-', label=info['titulo'])
        ax.axhline(info['umbral'], color='red', linestyle='--', label=f'Alarma ({info["umbral"]:.0f} PPM)')
        
        ax.set_title(info['titulo'], fontsize=10)
        ax.set_ylabel('PPM', fontsize=8)
        
        # --- LÓGICA DE ESCALA OPTIMIZADA (AJUSTA EL EJE Y) ---
        max_val_data = df[info['col']].max()
        
        if max_val_data < info['umbral']:
            y_lim_max = max_val_data * 1.2 
            if y_lim_max < 5: y_lim_max = 5 
        else:
            y_lim_max = max_val_data * 1.2
            
        ax.set_ylim(0, y_lim_max)
        # -----------------------------------------------------
        
        ax.legend(fontsize=7, loc='upper left')
        
        # CORRECCIÓN CLAVE: Mostrar la marca de tiempo en todos los ejes
        ax.tick_params(axis='x', labelbottom=True) 
        for tick in ax.get_xticklabels():
            tick.set_rotation(30)
            tick.set_ha('right')

    # 5. Integrar el gráfico en la GUI
    for widget in historial_frame.winfo_children():
        widget.destroy()

    canvas = FigureCanvasTkAgg(fig, master=historial_frame)
    canvas_widget = canvas.get_tk_widget()
    canvas_widget.pack(fill=tk.BOTH, expand=True)
    canvas.draw()
    tk.Label(historial_frame, text="Gráficos generados de los tres sensores con escala optimizada.").pack(pady=5)


# ----------------------------------------------------
# BUCLE PRINCIPAL DE LECTURA (ACTUALIZA LA GUI)
# ----------------------------------------------------

def actualizar_sensores():
    """Bucle principal de lectura y actualización de la GUI."""
    global ALARMA_ACTIVA, MEDICION_ACTIVA, UMBRAL_CO, UMBRAL_CH4, UMBRAL_AIRE
    
    if not MEDICION_ACTIVA:
        return

    try:
        # LECTURA Y CÁLCULO DE SENSORES
        ppm_7 = MQ7_to_PPM(get_RS_resistance(grovepi.analogRead(MQ7_PIN)), R0_MQ7)
        ppm_4 = MQ4_to_PPM(get_RS_resistance(grovepi.analogRead(MQ4_PIN)), R0_MQ4)
        ppm_135 = MQ135_to_PPM(get_RS_resistance(grovepi.analogRead(MQ135_PIN)), R0_MQ135)
        
        # -------------------------------------------------------
        # LÓGICA DE ALARMA MULTI-SENSOR
        # -------------------------------------------------------
        alerta_co = ppm_7 >= UMBRAL_CO
        alerta_ch4 = ppm_4 >= UMBRAL_CH4
        alerta_aire = ppm_135 >= UMBRAL_AIRE
        
        if alerta_co or alerta_ch4 or alerta_aire:
            ALARMA_ACTIVA = True
            grovepi.digitalWrite(BUZZER_PIN, 1)
            estado_alarma_texto = "!!! ALERTA GENERAL !!!"
            color_alarma = "red"
            
            detalle = []
            if alerta_co: detalle.append("CO")
            if alerta_ch4: detalle.append("CH4")
            if alerta_aire: detalle.append("AIR")
            estado_alarma_texto += " (" + ", ".join(detalle) + ")"

        else:
            ALARMA_ACTIVA = False
            grovepi.digitalWrite(BUZZER_PIN, 0)
            estado_alarma_texto = "Monitor Activo"
            color_alarma = "green"
            
        # 2. GUARDAR DATOS 
        guardar_datos(ppm_7, ppm_4, ppm_135, estado_alarma_texto)
            
        # 3. ACTUALIZACIÓN DE LA GUI
        
        # Actualización de Medidores PPM 
        dibujar_medidor_ppm(canvas_mq7, ppm_7, UMBRAL_CO, MAX_CO_DISPLAY, "Monóxido Carbono (CO)")
        dibujar_medidor_ppm(canvas_mq4, ppm_4, UMBRAL_CH4, MAX_PPM_DISPLAY, "Metano (CH4)")
        dibujar_medidor_ppm(canvas_mq135, ppm_135, UMBRAL_AIRE, MAX_PPM_DISPLAY, "Calidad del Aire")

        estado_general_label.config(text=estado_alarma_texto, background=color_alarma)
        hora_var.set(datetime.now().strftime('%H:%M:%S'))

    except IOError:
        estado_general_label.config(text="Error de Conexión I/O", background="orange")
    except Exception as e:
        estado_general_label.config(text="Error", background="red")
        print(f"Error durante la lectura: {e}")
        detener_medicion()

    if MEDICION_ACTIVA:
        root.after(TIEMPO_LECTURA_MS, actualizar_sensores)


# ----------------------------------------------------
# CONFIGURACIÓN DE LA INTERFAZ GRÁFICA (TKINTER)
# ----------------------------------------------------

try:
    grovepi.pinMode(BUZZER_PIN, "OUTPUT")
except:
    pass 

root = tk.Tk()
root.title("KEL AviGasDetector")

# Establecer tamaño DINÁMICO (Escalable)
root.geometry("400x600") 
root.resizable(True, True) 

# --- Estilos Mejorados (Themed Tkinter) ---
style = ttk.Style()
style.theme_use('clam') 
style.configure('TNotebook.Tab', font=('Helvetica', 10, 'bold'))
style.configure('Red.TButton', foreground='white', background='#CC0000', font=('Helvetica', 10, 'bold'))
style.map('Red.TButton', background=[('active', '#FF3333')])
style.configure('Green.TButton', foreground='white', background='#006600', font=('Helvetica', 10, 'bold'))
style.map('Green.TButton', background=[('active', '#009900')])
style.configure('Dashboard.TButton', font=('Helvetica', 12), padding=10)

notebook = ttk.Notebook(root)
notebook.pack(pady=5, padx=5, expand=True, fill='both')

# --- Variables de control (Instanciadas globalmente) ---
mq7_var = tk.StringVar(root)
mq4_var = tk.StringVar(root)
mq135_var = tk.StringVar(root)
hora_var = tk.StringVar(root, value="")
entry_co_var = tk.StringVar(root, value=UMBRAL_CO_DEFECTO)
entry_ch4_var = tk.StringVar(root, value=UMBRAL_CH4_DEFECTO)
entry_aire_var = tk.StringVar(root, value=UMBRAL_AIRE_DEFECTO)


# -----------------------------------------------------
# --- PESTAÑA 1: INICIO/ACCESO ---
# -----------------------------------------------------
inicio_frame = ttk.Frame(notebook, padding="10")
notebook.add(inicio_frame, text='Inicio')

ttk.Label(inicio_frame, text="KEL AviGasDetector", font=("Helvetica", 20, "bold"), foreground="#007bff").pack(pady=30)
ttk.Label(inicio_frame, text="Monitor de Calidad del Aire", font=("Helvetica", 14)).pack(pady=5)
ttk.Label(inicio_frame, text="Seleccione una opción:", font=("Helvetica", 12)).pack(pady=20)

# Botones de Acción de Inicio
btn_iniciar_inicio = ttk.Button(inicio_frame, text="Empezar Medición", command=iniciar_medicion, style='Green.TButton')
btn_iniciar_inicio.pack(pady=10, ipadx=20, ipady=10)

ttk.Button(inicio_frame, text="VER HISTORIAL", command=abrir_historial, style='Dashboard.TButton').pack(pady=10, ipadx=20, ipady=5)
ttk.Button(inicio_frame, text="CONFIGURACIÓN", command=abrir_configuracion, style='Dashboard.TButton').pack(pady=10, ipadx=20, ipady=5)


# -----------------------------------------------------
# --- PESTAÑA 2: MEDICIONES (DASHBOARD 3 MEDIDORES) ---
# -----------------------------------------------------
mediciones_frame = ttk.Frame(notebook, padding="10")
notebook.add(mediciones_frame, text='Mediciones')

ttk.Label(mediciones_frame, text="Monitor PPM en Tiempo Real", font=("Helvetica", 16, "bold")).pack(pady=10)

# Contenedor para los 3 Canvas
medidores_grid = ttk.Frame(mediciones_frame)
medidores_grid.pack(pady=10, padx=10)

# Medidor MQ-7
canvas_mq7 = tk.Canvas(medidores_grid, width=200, height=120, bg="#F0F0F0")
canvas_mq7.grid(row=0, column=0, padx=5, pady=5)
dibujar_medidor_ppm(canvas_mq7, 0, UMBRAL_CO, MAX_CO_DISPLAY, "Monóxido Carbono (CO)")

# Medidor MQ-4
canvas_mq4 = tk.Canvas(medidores_grid, width=200, height=120, bg="#F0F0F0")
canvas_mq4.grid(row=0, column=1, padx=5, pady=5)
dibujar_medidor_ppm(canvas_mq4, 0, UMBRAL_CH4, MAX_PPM_DISPLAY, "Metano (CH4)")

# Medidor MQ-135 (Debajo de MQ-7)
canvas_mq135 = tk.Canvas(medidores_grid, width=200, height=120, bg="#F0F0F0")
canvas_mq135.grid(row=1, column=0, padx=5, pady=5)
dibujar_medidor_ppm(canvas_mq135, 0, UMBRAL_AIRE, MAX_PPM_DISPLAY, "Calidad del Aire")

# Etiqueta de Estado de Alarma Principal
estado_general_label = tk.Label(mediciones_frame, text="Presiona COMENZAR", font=("Helvetica", 14, "bold"), background="gray", foreground="white", width=30)
estado_general_label.pack(pady=15)

# Botón de Control
btn_iniciar_mediciones = ttk.Button(mediciones_frame, text="Empezar Medición", command=iniciar_medicion, style='Green.TButton')
btn_iniciar_mediciones.pack(pady=10)


# -----------------------------------------------------
# --- PESTAÑA 3: HISTORIAL Y GRÁFICOS ---
# -----------------------------------------------------
historial_frame = ttk.Frame(notebook, padding="10")
notebook.add(historial_frame, text='Historial y Gráficos')

ttk.Label(historial_frame, text="Visualización de Datos Históricos", font=("Helvetica", 14, "bold")).pack(pady=5)
ttk.Button(historial_frame, text="Generar TRES Gráficos por Sensor", command=generar_grafico).pack(pady=10)
ttk.Button(historial_frame, text="Limpiar Historial de Archivo", command=limpiar_historial, style='Red.TButton').pack(pady=5)


# -----------------------------------------------------
# --- PESTAÑA 4: OPCIONES (CONFIGURACIÓN) ---
# -----------------------------------------------------
opciones_frame = ttk.Frame(notebook, padding="10")
notebook.add(opciones_frame, text='Opciones de Alarma')

ttk.Label(opciones_frame, text="Configuración de Umbrales de Seguridad (PPM)", font=("Helvetica", 14, "bold")).pack(pady=10)

# Función auxiliar para crear filas de configuración
def crear_fila_umbral(parent, label_text, entry_var, unidad, defecto):
    frame = ttk.Frame(parent)
    frame.pack(fill='x', padx=5, pady=5)
    
    ttk.Label(frame, text=label_text, width=20, anchor='w').pack(side='left')
    ttk.Entry(frame, textvariable=entry_var, width=10).pack(side='left', padx=5)
    ttk.Label(frame, text=f"{unidad} (Defecto: {defecto:.0f} PPM)").pack(side='left')

# Filas de configuración
crear_fila_umbral(opciones_frame, "MQ-7 (CO):", entry_co_var, "PPM", UMBRAL_CO_DEFECTO)
crear_fila_umbral(opciones_frame, "MQ-4 (CH4):", entry_ch4_var, "PPM", UMBRAL_CH4_DEFECTO)
crear_fila_umbral(opciones_frame, "MQ-135 (Aire/CO2):", entry_aire_var, "PPM", UMBRAL_AIRE_DEFECTO)

# Botones de Acción
action_frame = ttk.Frame(opciones_frame)
action_frame.pack(pady=20)

ttk.Button(action_frame, text="GUARDAR Umbrales", command=aplicar_umbrales, style='Green.TButton').pack(side='left', padx=10)
ttk.Button(action_frame, text="Restaurar Defecto", command=reset_umbrales, style='Red.TButton').pack(side='left', padx=10)


# Botón de Salida Global
ttk.Button(root, text="SALIR (Cerrar Programa y Limpiar)", command=salir_limpiar, style='Red.TButton').pack(pady=10)

# Iniciar los valores por defecto en los Entry fields al inicio
entry_co_var.set(UMBRAL_CO_DEFECTO)
entry_ch4_var.set(UMBRAL_CH4_DEFECTO)
entry_aire_var.set(UMBRAL_AIRE_DEFECTO)

root.mainloop()