Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -5,29 +5,22 @@ import numpy as np
|
|
5 |
import requests
|
6 |
import torch
|
7 |
import os
|
|
|
|
|
|
|
8 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
9 |
-
from langchain.memory import ConversationBufferMemory
|
10 |
|
11 |
# Configuración del modelo de lenguaje
|
12 |
MODEL_NAME = "PlanTL-GOB-ES/roberta-base-bne"
|
13 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
14 |
-
HF_TOKEN = os.getenv("HF_TOKEN")
|
15 |
|
16 |
if not HF_TOKEN:
|
17 |
raise ValueError("❌ ERROR: No se encontró HF_TOKEN. Asegúrate de definirlo en las variables de entorno.")
|
18 |
|
19 |
print("🔄 Cargando modelo de lenguaje...")
|
20 |
-
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME
|
21 |
-
|
22 |
-
model = AutoModelForCausalLM.from_pretrained(
|
23 |
-
MODEL_NAME,
|
24 |
-
torch_dtype=torch.float32, # ⚠️ Float32 es mejor para CPU
|
25 |
-
device_map="auto",
|
26 |
-
token=HF_TOKEN
|
27 |
-
)
|
28 |
-
|
29 |
-
# Memoria conversacional
|
30 |
-
memory = ConversationBufferMemory()
|
31 |
|
32 |
# API de Node-RED
|
33 |
NODE_RED_URL = "https://appairedecolmena.es/colmena1/datos"
|
@@ -35,69 +28,88 @@ USERNAME = "user"
|
|
35 |
PASSWORD = "velutina"
|
36 |
|
37 |
def obtener_datos_colmena():
|
38 |
-
"""Obtiene los datos más recientes de Node-RED
|
39 |
try:
|
40 |
respuesta = requests.get(NODE_RED_URL, auth=(USERNAME, PASSWORD), timeout=5)
|
41 |
if respuesta.status_code == 200:
|
42 |
datos = respuesta.json()
|
43 |
-
print("🔍 Datos recibidos de Node-RED:", datos) # ⬅️ Muestra los datos en la terminal
|
44 |
if "data" in datos and isinstance(datos["data"], list) and datos["data"]:
|
45 |
-
return datos["data"]
|
46 |
return {"error": "No hay datos recientes en Node-RED."}
|
47 |
else:
|
48 |
return {"error": f"Error en la API: {respuesta.status_code}"}
|
49 |
except Exception as e:
|
50 |
return {"error": str(e)}
|
51 |
|
52 |
-
def
|
53 |
-
"""
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
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.
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
76 |
|
77 |
-
|
78 |
-
output = model.generate(
|
79 |
-
**inputs,
|
80 |
-
max_new_tokens=100, # 🔽 Limitamos la respuesta para que sea rápida
|
81 |
-
do_sample=True,
|
82 |
-
top_k=40, # 🔽 Controla la aleatoriedad
|
83 |
-
temperature=0.6, # 🔽 Mantiene precisión en la respuesta
|
84 |
-
pad_token_id=tokenizer.eos_token_id
|
85 |
-
)
|
86 |
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
if
|
91 |
-
return "
|
92 |
-
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
94 |
|
95 |
iface = gr.Interface(
|
96 |
fn=conversar_con_colmena,
|
97 |
inputs="text",
|
98 |
-
outputs="text",
|
99 |
title="🐝 Chat con la Colmena",
|
100 |
-
description="Consulta el estado de la colmena y
|
101 |
)
|
102 |
|
103 |
iface.launch()
|
@@ -106,4 +118,3 @@ iface.launch()
|
|
106 |
|
107 |
|
108 |
|
109 |
-
|
|
|
5 |
import requests
|
6 |
import torch
|
7 |
import os
|
8 |
+
import json
|
9 |
+
import matplotlib.pyplot as plt
|
10 |
+
from io import BytesIO
|
11 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
|
12 |
|
13 |
# Configuración del modelo de lenguaje
|
14 |
MODEL_NAME = "PlanTL-GOB-ES/roberta-base-bne"
|
15 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
16 |
+
HF_TOKEN = os.getenv("HF_TOKEN")
|
17 |
|
18 |
if not HF_TOKEN:
|
19 |
raise ValueError("❌ ERROR: No se encontró HF_TOKEN. Asegúrate de definirlo en las variables de entorno.")
|
20 |
|
21 |
print("🔄 Cargando modelo de lenguaje...")
|
22 |
+
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
|
23 |
+
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME).to(device)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
# API de Node-RED
|
26 |
NODE_RED_URL = "https://appairedecolmena.es/colmena1/datos"
|
|
|
28 |
PASSWORD = "velutina"
|
29 |
|
30 |
def obtener_datos_colmena():
|
31 |
+
"""Obtiene los datos más recientes de Node-RED."""
|
32 |
try:
|
33 |
respuesta = requests.get(NODE_RED_URL, auth=(USERNAME, PASSWORD), timeout=5)
|
34 |
if respuesta.status_code == 200:
|
35 |
datos = respuesta.json()
|
|
|
36 |
if "data" in datos and isinstance(datos["data"], list) and datos["data"]:
|
37 |
+
return datos["data"]
|
38 |
return {"error": "No hay datos recientes en Node-RED."}
|
39 |
else:
|
40 |
return {"error": f"Error en la API: {respuesta.status_code}"}
|
41 |
except Exception as e:
|
42 |
return {"error": str(e)}
|
43 |
|
44 |
+
def analizar_tendencia(datos, variable):
|
45 |
+
"""Analiza la tendencia de una variable específica."""
|
46 |
+
valores = [float(d[variable]) for d in datos if variable in d]
|
47 |
+
timestamps = [d["timestamp"] for d in datos if variable in d]
|
48 |
+
promedio = np.mean(valores)
|
49 |
+
maximo = np.max(valores)
|
50 |
+
minimo = np.min(valores)
|
51 |
+
|
52 |
+
respuesta = f"📊 **Análisis de {variable}:**\n"
|
53 |
+
respuesta += f"- Promedio: {promedio:.2f}\n"
|
54 |
+
respuesta += f"- Máximo: {maximo:.2f}\n"
|
55 |
+
respuesta += f"- Mínimo: {minimo:.2f}\n"
|
56 |
+
|
57 |
+
return respuesta, valores, timestamps
|
58 |
+
|
59 |
+
def generar_grafico(valores, timestamps, variable):
|
60 |
+
"""Genera un gráfico de la variable analizada."""
|
61 |
+
plt.figure(figsize=(10, 5))
|
62 |
+
plt.plot(timestamps, valores, marker='o', linestyle='-')
|
63 |
+
plt.xlabel("Tiempo")
|
64 |
+
plt.ylabel(variable)
|
65 |
+
plt.title(f"Tendencia de {variable}")
|
66 |
+
plt.xticks(rotation=45)
|
67 |
+
plt.grid()
|
68 |
|
69 |
+
buf = BytesIO()
|
70 |
+
plt.savefig(buf, format="png")
|
71 |
+
buf.seek(0)
|
72 |
+
return buf
|
73 |
+
|
74 |
+
def interpretar_instruccion(mensaje, datos):
|
75 |
+
"""Interpreta la consulta del usuario y ejecuta el análisis solicitado."""
|
76 |
+
mensaje = mensaje.lower()
|
|
|
|
|
77 |
|
78 |
+
# Mapeo de variables con términos comunes
|
79 |
+
variable_map = {
|
80 |
+
"temperatura": "temperaturaInterior",
|
81 |
+
"humedad": "humedadInterior",
|
82 |
+
"co2": "co2",
|
83 |
+
"peso": "peso"
|
84 |
+
}
|
85 |
|
86 |
+
for key, var in variable_map.items():
|
87 |
+
if key in mensaje:
|
88 |
+
respuesta, valores, timestamps = analizar_tendencia(datos, var)
|
89 |
+
grafico = generar_grafico(valores, timestamps, var)
|
90 |
+
return respuesta, grafico
|
91 |
|
92 |
+
return "🤖 No entiendo la consulta. Pregunta sobre el estado de la colmena o análisis de variables."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
+
def conversar_con_colmena(mensaje):
|
95 |
+
"""Genera una respuesta combinando el modelo de lenguaje con análisis de datos."""
|
96 |
+
datos = obtener_datos_colmena()
|
97 |
+
if "error" in datos:
|
98 |
+
return datos["error"]
|
99 |
+
|
100 |
+
resultado = interpretar_instruccion(mensaje, datos)
|
101 |
+
if isinstance(resultado, tuple):
|
102 |
+
texto, grafico = resultado
|
103 |
+
return texto, grafico
|
104 |
+
else:
|
105 |
+
return resultado
|
106 |
|
107 |
iface = gr.Interface(
|
108 |
fn=conversar_con_colmena,
|
109 |
inputs="text",
|
110 |
+
outputs=["text", "image"],
|
111 |
title="🐝 Chat con la Colmena",
|
112 |
+
description="Consulta el estado de la colmena y pide análisis de datos."
|
113 |
)
|
114 |
|
115 |
iface.launch()
|
|
|
118 |
|
119 |
|
120 |
|
|