Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -22,7 +22,8 @@ if os.path.exists(modelo_path):
|
|
22 |
else:
|
23 |
modelo = RandomForestClassifier(n_estimators=100)
|
24 |
|
25 |
-
# Variable para rastrear el último timestamp
|
|
|
26 |
ultimo_timestamp = None
|
27 |
|
28 |
def obtener_datos_colmena():
|
@@ -30,9 +31,7 @@ def obtener_datos_colmena():
|
|
30 |
try:
|
31 |
respuesta = requests.get(NODE_RED_URL, auth=(USERNAME, PASSWORD), timeout=5)
|
32 |
if respuesta.status_code == 200:
|
33 |
-
|
34 |
-
#print(f"📡 Datos recibidos de Node-RED: {datos}") # Agregar este print
|
35 |
-
return datos
|
36 |
else:
|
37 |
print(f"⚠️ Error en la API de Node-RED: {respuesta.status_code}")
|
38 |
return None
|
@@ -40,86 +39,95 @@ def obtener_datos_colmena():
|
|
40 |
print("❌ No se pudo conectar a Node-RED:", e)
|
41 |
return None
|
42 |
|
43 |
-
|
44 |
def entrenar_nuevo_modelo(datos):
|
45 |
"""Entrena un nuevo modelo con los datos recibidos."""
|
46 |
global modelo
|
47 |
|
48 |
-
# Convertir los datos en un array
|
49 |
entrada = np.array([[float(datos["temperaturaInterior"]), float(datos["humedadInterior"]), float(datos["peso"]),
|
50 |
float(datos["co2"]), float(datos["vco"]), float(datos["frecuencia"]),
|
51 |
float(datos["voltaje"]), float(datos["temperatura_exterior"]),
|
52 |
float(datos["humedad_exterior"]), float(datos["ver_tempSelect"])]])
|
53 |
|
54 |
-
# Salidas: [ultrasonido, calefactor, ventilador]
|
55 |
salida = np.array([[int(datos["ver_ultrasonido"]), int(datos["ver_calefactor"]), int(datos["ver_ventilador"])]])
|
56 |
-
|
57 |
-
# Reentrenar el modelo
|
58 |
modelo.fit(entrada, salida)
|
59 |
-
|
60 |
-
# Guardar el nuevo modelo
|
61 |
joblib.dump(modelo, modelo_path)
|
62 |
print("✅ Modelo actualizado con nuevos datos.")
|
63 |
|
64 |
def verificar_nuevos_datos():
|
65 |
"""Consulta Node-RED cada hora y aprende si hay datos nuevos."""
|
66 |
-
global ultimo_timestamp
|
67 |
|
68 |
while True:
|
69 |
datos = obtener_datos_colmena()
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
if timestamp_actual != ultimo_timestamp:
|
81 |
-
print(f"📌 Nuevos datos detectados: {timestamp_actual}")
|
82 |
-
entrenar_nuevo_modelo(ultimo_registro) # Usar el último registro
|
83 |
-
ultimo_timestamp = timestamp_actual
|
84 |
-
else:
|
85 |
-
print("⏳ No hay datos nuevos, esperando la próxima consulta...")
|
86 |
else:
|
87 |
-
print(
|
88 |
else:
|
89 |
-
print(f"❌
|
90 |
-
|
91 |
-
|
92 |
time.sleep(3600)
|
93 |
|
94 |
-
|
95 |
-
|
96 |
-
# Iniciar el proceso en segundo plano
|
97 |
-
thread = threading.Thread(target=verificar_nuevos_datos, daemon=True)
|
98 |
-
thread.start()
|
99 |
-
|
100 |
-
# Función para hacer predicciones con el modelo
|
101 |
def predecir(temp, humedad, peso, co2, vco, frecuencia, voltaje, temp_ext, humedad_ext, ver_tempSelect):
|
102 |
valores = [temp, humedad, peso, co2, vco, frecuencia, voltaje, temp_ext, humedad_ext, ver_tempSelect]
|
103 |
-
valores_limpios = [0 if v is None or np.isnan(v) else v for v in valores]
|
104 |
-
|
105 |
entrada = np.array([valores_limpios])
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
mensaje
|
110 |
-
mensaje += f"\n🔹 Calefactor: {'ENCENDER' if prediccion[1] == 1 else 'APAGAR'}"
|
111 |
-
mensaje += f"\n🔹 Ventilador: {'ENCENDER' if prediccion[2] == 1 else 'APAGAR'}"
|
112 |
-
|
113 |
return mensaje
|
114 |
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
|
124 |
-
# Lanzar la API
|
125 |
iface.launch()
|
|
|
|
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():
|
|
|
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
|
|
|
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 |
+
|