Spaces:
Sleeping
Sleeping
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 = "mistralai/Mistral-7B-Instruct" # Puedes cambiar a LLaMA 2 | |
device = "cuda" if torch.cuda.is_available() else "cpu" | |
print("🔄 Cargando modelo de lenguaje...") | |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) | |
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME).to(device) | |
# Configuración de memoria conversacional con límite de contexto | |
memory = ConversationBufferMemory(max_human_messages=10, max_ai_messages=10) | |
# Cargar modelo de la colmena | |
modelo_path = "modelo_colmena.pkl" | |
if os.path.exists(modelo_path): | |
modelo_colmena = joblib.load(modelo_path) | |
else: | |
modelo_colmena = None | |
# 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() | |
if "data" in datos and isinstance(datos["data"], list) and datos["data"]: | |
return datos["data"][-1] # Devuelve solo el ú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 filtrar_datos_por_pregunta(mensaje, datos): | |
"""Filtra los datos de la colmena según la pregunta del usuario.""" | |
if "temperatura" in mensaje: | |
return f"🌡 Temperatura interior: {datos['temperaturaInterior']}°C, exterior: {datos['temperatura_exterior']}°C." | |
elif "humedad" in mensaje: | |
return f"💧 Humedad interior: {datos['humedadInterior']}%, exterior: {datos['humedad_exterior']}%." | |
elif "co2" in mensaje: | |
return f"🌿 CO2: {datos['co2']} ppm." | |
elif "ventilador" in mensaje: | |
estado = "ENCENDIDO" if int(datos['ver_ventilador']) == 1 else "APAGADO" | |
return f"🔄 Ventilador: {estado}." | |
elif "calefactor" in mensaje: | |
estado = "ENCENDIDO" if int(datos['ver_calefactor']) == 1 else "APAGADO" | |
return f"🔥 Calefactor: {estado}." | |
elif "ultrasonido" in mensaje: | |
estado = "ENCENDIDO" if int(datos['ver_ultrasonido']) == 1 else "APAGADO" | |
return f"🔊 Ultrasonido: {estado}." | |
else: | |
return "🤖 No entiendo la pregunta. Puedes preguntar sobre temperatura, humedad, CO2, ventilador, calefactor o ultrasonido." | |
def conversar_con_colmena(mensaje): | |
"""Genera una respuesta combinando el modelo de lenguaje con los datos de la colmena.""" | |
datos = obtener_datos_colmena() | |
if "error" in datos: | |
return datos["error"] | |
datos_relevantes = filtrar_datos_por_pregunta(mensaje.lower(), datos) | |
contexto = f"Datos actuales de la colmena: {datos_relevantes}\nUsuario: {mensaje}\nColmena:" | |
inputs = tokenizer(contexto, return_tensors="pt").to(device) | |
with torch.no_grad(): | |
output = model.generate(**inputs, max_length=150) # Limitar longitud | |
respuesta = tokenizer.decode(output[0], skip_special_tokens=True) | |
memory.save_context({"input": mensaje}, {"output": respuesta}) | |
return respuesta | |
iface = gr.Interface( | |
fn=conversar_con_colmena, | |
inputs="text", | |
outputs="text", | |
title="🐝 Chat con la Colmena", | |
description="Habla con la colmena en tiempo real sobre su estado." | |
) | |
iface.launch() | |