import accelerate import gradio as gr import joblib import numpy as np import requests import torch import os from transformers import AutoModelForCausalLM, AutoTokenizer from langchain.memory import ConversationBufferMemory # Configuración del modelo de lenguaje MODEL_NAME = "PlanTL-GOB-ES/roberta-base-bne" device = "cuda" if torch.cuda.is_available() else "cpu" HF_TOKEN = os.getenv("HF_TOKEN") # Token de Hugging Face if not HF_TOKEN: raise ValueError("❌ ERROR: No se encontró HF_TOKEN. Asegúrate de definirlo en las variables de entorno.") print("🔄 Cargando modelo de lenguaje...") tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, token=HF_TOKEN) model = AutoModelForCausalLM.from_pretrained( MODEL_NAME, torch_dtype=torch.float32, # ⚠️ Float32 es mejor para CPU device_map="auto", token=HF_TOKEN ) # Memoria conversacional memory = ConversationBufferMemory() # API de Node-RED NODE_RED_URL = "https://appairedecolmena.es/colmena1/datos" USERNAME = "user" PASSWORD = "velutina" def obtener_datos_colmena(): """Obtiene los datos más recientes de Node-RED con autenticación.""" try: respuesta = requests.get(NODE_RED_URL, auth=(USERNAME, PASSWORD), timeout=5) if respuesta.status_code == 200: datos = respuesta.json() print("🔍 Datos recibidos de Node-RED:", datos) # ⬅️ Muestra los datos en la terminal if "data" in datos and isinstance(datos["data"], list) and datos["data"]: return datos["data"][-1] # Último registro return {"error": "No hay datos recientes en Node-RED."} else: return {"error": f"Error en la API: {respuesta.status_code}"} except Exception as e: return {"error": str(e)} def conversar_con_colmena(mensaje): """Genera una respuesta basada en el estado de la colmena sin reglas fijas.""" datos = obtener_datos_colmena() if "error" in datos: return datos["error"] contexto = f""" Datos actuales de la colmena: - Temperatura interior: {datos.get("temperaturaInterior", "Desconocida")}°C - Humedad interior: {datos.get("humedadInterior", "Desconocida")}% - Nivel de CO₂: {datos.get("co2", "Desconocido")} ppm - Estado del ventilador: {"Encendido" if datos.get("ver_ventilador") == "1" else "Apagado"} - Estado del calefactor: {"Encendido" if datos.get("ver_calefactor") == "1" else "Apagado"} - Estado del ultrasonido: {"Encendido" if datos.get("ver_ultrasonido") == "1" else "Apagado"} Basándote en estos datos, responde como un experto en apicultura y monitoreo de colmenas. Explica cómo está la colmena y si hay algún problema que deba resolverse. Usuario: {mensaje} Colmena: """ inputs = tokenizer(contexto, return_tensors="pt").to(device) print(f"🔄 Enviando entrada al modelo: {contexto}") with torch.no_grad(): output = model.generate( **inputs, max_new_tokens=100, # 🔽 Limitamos la respuesta para que sea rápida do_sample=True, top_k=40, # 🔽 Controla la aleatoriedad temperature=0.6, # 🔽 Mantiene precisión en la respuesta pad_token_id=tokenizer.eos_token_id ) respuesta = tokenizer.decode(output[0], skip_special_tokens=True).strip() print(f"✅ Respuesta generada por la IA: '{respuesta}'") if not respuesta: return "🤖 No pude generar una respuesta. Inténtalo de nuevo con otra pregunta." return respuesta iface = gr.Interface( fn=conversar_con_colmena, inputs="text", outputs="text", title="🐝 Chat con la Colmena", description="Consulta el estado de la colmena y recibe respuestas generadas por IA en tiempo real." ) iface.launch()