XA-vito commited on
Commit
562da15
·
verified ·
1 Parent(s): 60f3f22

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -108
app.py CHANGED
@@ -1,133 +1,95 @@
1
  import gradio as gr
2
  import joblib
3
  import numpy as np
4
- import os
5
  import requests
6
- import time
7
- import threading
8
- from datetime import datetime
9
- from sklearn.ensemble import RandomForestClassifier
10
 
11
- # Configuración de la API de Node-RED
12
- NODE_RED_URL = "https://appairedecolmena.es/colmena1/datos"
13
- USERNAME = "user"
14
- PASSWORD = "velutina"
15
 
16
- # Ruta del modelo
17
- modelo_path = "modelo_colmena.pkl"
 
18
 
19
- # Cargar el modelo si existe, si no, crearlo vacío
 
 
 
 
20
  if os.path.exists(modelo_path):
21
- modelo = joblib.load(modelo_path)
22
  else:
23
- modelo = RandomForestClassifier(n_estimators=100)
24
 
25
- # Variable para rastrear el último timestamp y datos recientes
26
- datos_recientes = None
27
- ultimo_timestamp = None
 
28
 
29
  def obtener_datos_colmena():
30
- """Obtiene los datos de Node-RED con autenticación."""
31
  try:
32
  respuesta = requests.get(NODE_RED_URL, auth=(USERNAME, PASSWORD), timeout=5)
33
  if respuesta.status_code == 200:
34
- return respuesta.json()
 
 
 
35
  else:
36
- print(f"⚠️ Error en la API de Node-RED: {respuesta.status_code}")
37
- return None
38
  except Exception as e:
39
- print("❌ No se pudo conectar a Node-RED:", e)
40
- return None
41
-
42
- def entrenar_nuevo_modelo(datos):
43
- """Entrena un nuevo modelo con los datos recibidos."""
44
- global modelo
45
 
46
- entrada = np.array([[float(datos["temperaturaInterior"]), float(datos["humedadInterior"]), float(datos["peso"]),
47
- float(datos["co2"]), float(datos["vco"]), float(datos["frecuencia"]),
48
- float(datos["voltaje"]), float(datos["temperatura_exterior"]),
49
- float(datos["humedad_exterior"]), float(datos["ver_tempSelect"])]])
50
-
51
- salida = np.array([[int(datos["ver_ultrasonido"]), int(datos["ver_calefactor"]), int(datos["ver_ventilador"])]])
52
- modelo.fit(entrada, salida)
53
- joblib.dump(modelo, modelo_path)
54
- print(" Modelo actualizado con nuevos datos.")
55
-
56
- def verificar_nuevos_datos():
57
- """Consulta Node-RED cada hora y aprende si hay datos nuevos."""
58
- global ultimo_timestamp, datos_recientes
59
-
60
- while True:
61
- datos = obtener_datos_colmena()
62
- if datos and "data" in datos and isinstance(datos["data"], list) and len(datos["data"]) > 0:
63
- ultimo_registro = datos["data"][-1]
64
- if "timestamp" in ultimo_registro:
65
- timestamp_actual = ultimo_registro["timestamp"]
66
- if timestamp_actual != ultimo_timestamp:
67
- print(f"📌 Nuevos datos detectados: {timestamp_actual}")
68
- entrenar_nuevo_modelo(ultimo_registro)
69
- datos_recientes = ultimo_registro
70
- ultimo_timestamp = timestamp_actual
71
- else:
72
- print("⏳ No hay datos nuevos, esperando la próxima consulta...")
73
- else:
74
- print(f"❌ No se encontró 'timestamp' en el último registro: {ultimo_registro}")
75
- else:
76
- print("❌ No hay datos válidos en la API de Node-RED.")
77
- time.sleep(3600)
78
-
79
- def predecir(temp, humedad, peso, co2, vco, frecuencia, voltaje, temp_ext, humedad_ext, ver_tempSelect):
80
- valores = [temp, humedad, peso, co2, vco, frecuencia, voltaje, temp_ext, humedad_ext, ver_tempSelect]
81
- valores_limpios = [0 if v is None or np.isnan(v) else v for v in valores]
82
- entrada = np.array([valores_limpios])
83
- prediccion = modelo.predict(entrada)[0]
84
- mensaje = f"🔹 Ultrasonido: {'ENCENDER' if prediccion[0] == 1 else 'APAGAR'}\n"
85
- mensaje += f"🔹 Calefactor: {'ENCENDER' if prediccion[1] == 1 else 'APAGAR'}\n"
86
- mensaje += f"🔹 Ventilador: {'ENCENDER' if prediccion[2] == 1 else 'APAGAR'}"
87
- return mensaje
88
-
89
- def chat_ia(mensaje_usuario):
90
- """Responde preguntas sobre la colmena basándose en los últimos datos disponibles."""
91
- global datos_recientes
92
- if datos_recientes is None:
93
- return "No hay datos recientes disponibles. Esperando actualización de Node-RED."
94
-
95
- mensaje_usuario = mensaje_usuario.lower()
96
- if "temperatura" in mensaje_usuario:
97
- return f"🌡 La temperatura interior es {datos_recientes['temperaturaInterior']}°C y la exterior {datos_recientes['temperatura_exterior']}°C."
98
- elif "humedad" in mensaje_usuario:
99
- return f"💧 La humedad interior es {datos_recientes['humedadInterior']}% y la exterior {datos_recientes['humedad_exterior']}%."
100
- elif "co2" in mensaje_usuario:
101
- return f"🌿 El nivel de CO2 es {datos_recientes['co2']} ppm."
102
- elif "ventilador" in mensaje_usuario:
103
- estado = "ENCENDIDO" if int(datos_recientes['ver_ventilador']) == 1 else "APAGADO"
104
- return f"🔄 El ventilador está {estado}."
105
- elif "calefactor" in mensaje_usuario:
106
- estado = "ENCENDIDO" if int(datos_recientes['ver_calefactor']) == 1 else "APAGADO"
107
- return f"🔥 El calefactor está {estado}."
108
- elif "ultrasonido" in mensaje_usuario:
109
- estado = "ENCENDIDO" if int(datos_recientes['ver_ultrasonido']) == 1 else "APAGADO"
110
- return f"🔊 El ultrasonido está {estado}."
111
  else:
112
  return "🤖 No entiendo la pregunta. Puedes preguntar sobre temperatura, humedad, CO2, ventilador, calefactor o ultrasonido."
113
 
114
- # Iniciar proceso de actualización de datos
115
- thread = threading.Thread(target=verificar_nuevos_datos, daemon=True)
116
- thread.start()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
- # Interfaz de Gradio con dos funciones: predicción y chat
119
- iface = gr.TabbedInterface([
120
- gr.Interface(fn=predecir,
121
- inputs=["number", "number", "number", "number", "number", "number", "number", "number", "number", "number"],
122
- outputs="text",
123
- title="🐝 IA Inteligente para Colmenas",
124
- description="Introduce los datos de la colmena y la IA predecirá si es necesario activar ventilador, calefactor y ultrasonidos."),
125
- gr.Interface(fn=chat_ia,
126
- inputs="text",
127
- outputs="text",
128
- title="💬 Chat con la IA de la Colmena",
129
- description="Haz preguntas sobre el estado de la colmena y la IA responderá basándose en los datos más recientes.")
130
- ], title="🐝 Colmena Inteligente")
131
 
132
  iface.launch()
133
 
 
1
  import gradio as gr
2
  import joblib
3
  import numpy as np
 
4
  import requests
5
+ import torch
6
+ import os
7
+ from transformers import AutoModelForCausalLM, AutoTokenizer
8
+ from langchain.memory import ConversationBufferMemory
9
 
10
+ # Configuración del modelo de lenguaje
11
+ MODEL_NAME = "mistralai/Mistral-7B-Instruct" # Puedes cambiar a LLaMA 2
12
+ device = "cuda" if torch.cuda.is_available() else "cpu"
 
13
 
14
+ print("🔄 Cargando modelo de lenguaje...")
15
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
16
+ model = AutoModelForCausalLM.from_pretrained(MODEL_NAME).to(device)
17
 
18
+ # Configuración de memoria conversacional con límite de contexto
19
+ memory = ConversationBufferMemory(max_human_messages=10, max_ai_messages=10)
20
+
21
+ # Cargar modelo de la colmena
22
+ modelo_path = "modelo_colmena.pkl"
23
  if os.path.exists(modelo_path):
24
+ modelo_colmena = joblib.load(modelo_path)
25
  else:
26
+ modelo_colmena = None
27
 
28
+ # API de Node-RED
29
+ NODE_RED_URL = "https://appairedecolmena.es/colmena1/datos"
30
+ USERNAME = "user"
31
+ PASSWORD = "velutina"
32
 
33
  def obtener_datos_colmena():
34
+ """Obtiene los datos más recientes de Node-RED con autenticación."""
35
  try:
36
  respuesta = requests.get(NODE_RED_URL, auth=(USERNAME, PASSWORD), timeout=5)
37
  if respuesta.status_code == 200:
38
+ datos = respuesta.json()
39
+ if "data" in datos and isinstance(datos["data"], list) and datos["data"]:
40
+ return datos["data"][-1] # Devuelve solo el último registro
41
+ return {"error": "No hay datos recientes en Node-RED."}
42
  else:
43
+ return {"error": f"Error en la API: {respuesta.status_code}"}
 
44
  except Exception as e:
45
+ return {"error": str(e)}
 
 
 
 
 
46
 
47
+ def filtrar_datos_por_pregunta(mensaje, datos):
48
+ """Filtra los datos de la colmena según la pregunta del usuario."""
49
+ if "temperatura" in mensaje:
50
+ return f"🌡 Temperatura interior: {datos['temperaturaInterior']}°C, exterior: {datos['temperatura_exterior']}°C."
51
+ elif "humedad" in mensaje:
52
+ return f"💧 Humedad interior: {datos['humedadInterior']}%, exterior: {datos['humedad_exterior']}%."
53
+ elif "co2" in mensaje:
54
+ return f"🌿 CO2: {datos['co2']} ppm."
55
+ elif "ventilador" in mensaje:
56
+ estado = "ENCENDIDO" if int(datos['ver_ventilador']) == 1 else "APAGADO"
57
+ return f"🔄 Ventilador: {estado}."
58
+ elif "calefactor" in mensaje:
59
+ estado = "ENCENDIDO" if int(datos['ver_calefactor']) == 1 else "APAGADO"
60
+ return f"🔥 Calefactor: {estado}."
61
+ elif "ultrasonido" in mensaje:
62
+ estado = "ENCENDIDO" if int(datos['ver_ultrasonido']) == 1 else "APAGADO"
63
+ return f"🔊 Ultrasonido: {estado}."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  else:
65
  return "🤖 No entiendo la pregunta. Puedes preguntar sobre temperatura, humedad, CO2, ventilador, calefactor o ultrasonido."
66
 
67
+ def conversar_con_colmena(mensaje):
68
+ """Genera una respuesta combinando el modelo de lenguaje con los datos de la colmena."""
69
+ datos = obtener_datos_colmena()
70
+ if "error" in datos:
71
+ return datos["error"]
72
+
73
+ datos_relevantes = filtrar_datos_por_pregunta(mensaje.lower(), datos)
74
+
75
+ contexto = f"Datos actuales de la colmena: {datos_relevantes}\nUsuario: {mensaje}\nColmena:"
76
+ inputs = tokenizer(contexto, return_tensors="pt").to(device)
77
+
78
+ with torch.no_grad():
79
+ output = model.generate(**inputs, max_length=150) # Limitar longitud
80
+
81
+ respuesta = tokenizer.decode(output[0], skip_special_tokens=True)
82
+ memory.save_context({"input": mensaje}, {"output": respuesta})
83
+
84
+ return respuesta
85
 
86
+ iface = gr.Interface(
87
+ fn=conversar_con_colmena,
88
+ inputs="text",
89
+ outputs="text",
90
+ title="🐝 Chat con la Colmena",
91
+ description="Habla con la colmena en tiempo real sobre su estado."
92
+ )
 
 
 
 
 
 
93
 
94
  iface.launch()
95