import time
import network
from machine import Pin
import dht
from umqtt.simple import MQTTClient
# ===== WiFi (Wokwi) =====
WIFI_SSID = "Wokwi-GUEST"
WIFI_PASS = ""
# ===== Adafruit IO MQTT =====
AIO_USERNAME = "IngenieraCreativa"
AIO_KEY = "TU_AIO_KEY" # <-- pega tu Active Key aquí (no la muestres)
AIO_SERVER = "io.adafruit.com"
AIO_PORT = 1883
TOPIC_TEMP = bytes(f"{AIO_USERNAME}/feeds/temp", "utf-8")
TOPIC_HUM = bytes(f"{AIO_USERNAME}/feeds/hum", "utf-8")
TOPIC_LED = bytes(f"{AIO_USERNAME}/feeds/led", "utf-8") # 1=manual ON, 0=AUTO
# ===== Hardware =====
LED_PIN = 2
LED = Pin(LED_PIN, Pin.OUT)
LED.value(0)
DHT_PIN = 15
sensor = dht.DHT22(Pin(DHT_PIN))
# ===== Confort (ajusta a tu gusto) =====
TEMP_ON = 30.0 # enciende alerta por calor
TEMP_OFF = 28.0 # apaga alerta cuando baje (histéresis)
HUM_ON = 70.0 # enciende alerta por humedad
HUM_OFF = 65.0 # apaga alerta cuando baje (histéresis)
# ===== Estado global =====
manual_override = False # True si led=1 desde dashboard
alert_on = False # estado de alerta automática (para histéresis)
last_led_msg = "0" # debug
def wifi_connect():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print("Conectando WiFi...")
wlan.connect(WIFI_SSID, WIFI_PASS)
t0 = time.time()
while not wlan.isconnected():
if time.time() - t0 > 20:
raise Exception("Timeout WiFi")
time.sleep(0.2)
print("WiFi OK:", wlan.ifconfig())
return wlan
def on_message(topic, msg):
global manual_override, last_led_msg
if topic == TOPIC_LED:
m = msg.decode().strip().lower()
last_led_msg = m
# 1 / on / true => manual ON
if m in ("1", "on", "true"):
manual_override = True
LED.value(1)
# 0 / off / false => vuelve a AUTO
elif m in ("0", "off", "false"):
manual_override = False
# si llega cualquier otra cosa, ignoramos
print("LED feed:", m, "| manual_override:", manual_override)
def mqtt_connect():
client = MQTTClient(
client_id=b"wokwi-esp32",
server=AIO_SERVER,
port=AIO_PORT,
user=AIO_USERNAME,
password=AIO_KEY,
keepalive=60
)
client.set_callback(on_message)
print("Conectando MQTT...")
client.connect()
print("MQTT OK")
client.subscribe(TOPIC_LED)
return client
def read_dht():
sensor.measure()
t = sensor.temperature()
h = sensor.humidity()
return t, h
def publish_float(client, topic, value, decimals=1):
payload = f"{value:.{decimals}f}"
client.publish(topic, payload)
return payload
def update_auto_alert(t, h):
"""
Histéresis:
- Si ya está ALERTA, no se apaga hasta que baje a OFF thresholds
- Si está OK, se enciende cuando supera ON thresholds
"""
global alert_on
if alert_on:
# apagar solo si TODO ya está en zona segura
if (t <= TEMP_OFF) and (h <= HUM_OFF):
alert_on = False
else:
# encender si cualquier condición supera umbral alto
if (t >= TEMP_ON) or (h >= HUM_ON):
alert_on = True
return alert_on
# ===== Main =====
wifi_connect()
client = mqtt_connect()
PUB_EVERY_S = 5
last_pub = 0
print("Iniciando loop... (temp/hum -> Adafruit IO, led -> manual override)")
while True:
# 1) Escuchar mensajes (toggle LED)
try:
client.check_msg()
except Exception as e:
print("check_msg error:", e)
# 2) Publicar y actualizar lógica cada PUB_EVERY_S
now = time.time()
if now - last_pub >= PUB_EVERY_S:
try:
t, h = read_dht()
# Publica feeds numéricos (para gauges)
p1 = publish_float(client, TOPIC_TEMP, t, decimals=1)
p2 = publish_float(client, TOPIC_HUM, h, decimals=1)
# Lógica de LED
if manual_override:
# Manual: LED forzado ON
LED.value(1)
mode = "MANUAL"
else:
# Auto: aplica umbrales + histéresis
alert = update_auto_alert(t, h)
LED.value(1 if alert else 0)
mode = "AUTO"
print("TX temp:", p1, "| hum:", p2,
"| mode:", mode,
"| alert_on:", alert_on,
"| led_feed:", last_led_msg)
last_pub = now
except Exception as e:
print("DHT/MQTT error:", e)
time.sleep(0.1)