"""
MicroPython IoT Weather Station Example for Wokwi.com
To view the data:
1. Go to http://www.hivemq.com/demos/websocket-client/
2. Click "Connect"
3. Under Subscriptions, click "Add New Topic Subscription"
4. In the Topic field, type "wokwi-weather" then click "Subscribe"
Now click on the DHT22 sensor in the simulation,
change the temperature/humidity, and you should see
the message appear on the MQTT Broker, in the "Messages" pane.
Copyright (C) 2022, Uri Shaked
https://wokwi.com/arduino/projects/322577683855704658
"""
import network #Importa la libreria "Network" de MicrpPython que maneja la conexion a red de la ESP32, disponible en https://docs.micropython.org/en/latest/library/network.html
import time #Importa la libreria "time" de Micropython que integra instrucciones para obtener la hora y fecha actuales, medir intervalos de tiempo y retrasos, disponible en https://docs.micropython.org/en/latest/library/time.html
from machine import Pin #Importa la clase "Pin" del modulo "machine", esta se utiliza para la interaccion con los pines GPIO de la ESP32
import dht #Importa la libreria "dht" que permite interactuar con el sensor de temperatura y humedad DHT22, disponible en https://docs.micropython.org/en/latest/esp32/quickref.html#dht-driver
import ujson #Importa la libreria "ujson" que permite convertir entre objetos Python y el formato de datos JSON, disponible en https://docs.micropython.org/en/v1.15/library/ujson.html
from umqtt.simple import MQTTClient #Importa la clase "MQTTClient" de la libreria "umqtt.simple" que permite comunicacion con el servidor MQTT, disponible en https://mpython.readthedocs.io/en/v2.2.1/library/mPython/umqtt.simple.html
# MQTT Server Parameters ---------- Las siguientes lineas definen variable que contienen los parametros para la conexion con el servidor MQTT
MQTT_CLIENT_ID = "micropython-weather-demo" #Se declara la variable "MQTT_CLIENT_ID" y se asigna el valor "micropython-weather-demo", esta variable representa el Id de identificacion del cliente para el servidor MQTT.
MQTT_BROKER = "broker.mqttdashboard.com" #Se declara la variable "MQTT_BROKER" y se asigna el valor "broker.mqttdashboard.com", esta variable corresponde a la direccion del Broker del servidor MQTT al ques se va a conectar.
MQTT_USER = "" #Se declara la variable "MQTT_USER" y se asigna un valor tipo String vacio, esta variable representa el cliente que se autentica en el servidor MQTT
MQTT_PASSWORD = "" #Se declara la variable "MQTT_PASSWORD" y se asigna un valor tipo String vacio, esta variable contiene la contraseña del usuario cliente para autenticarse en el servidor MQTT
MQTT_TOPIC = "wokwi-weather" #Se declara la variable "MQTT_TOPIC" y se agigna el valor "wokwi-weather", esta variable representa el tema "topic" al que el cliente se suscribe en el servidor MQTT
sensor = dht.DHT22(Pin(15)) #Se declara la variable "sensor" que almacena los datos de temperatura y humedad leidos del sendor DHT22 conectado al pin 15 de la ESP32.
print("Connecting to WiFi", end="") #Imprime en la consola el mensaje "Connecting to WiFi", el parametro end="" indica que despues del texto escrito no pondra un salto de linea sino un espacio en blanco
sta_if = network.WLAN(network.STA_IF) #Se crea una instancia "sta_if" del objeto de interfaz de red WLAN
sta_if.active(True) #Activa la la interfaz "sta_if"
sta_if.connect('Wokwi-GUEST', '') #Realiza la conexion de la interfaz a la red, los argumentos corresponden al SSID y la contraseña, en este caso SSID="Wokwi-GUEST" y no hay contraseña asignada
while not sta_if.isconnected(): #Entra en un ciclo de espera hasta que la ESP32 establece la conexion a la red WiFi
print(".", end="") #Imprime en consola un "." sin salto de linea
time.sleep(0.1) #Espera un tiempo de 0.1 segundo, mientras se realiza la conexion
print(" Connected!") #Al salir del ciclo de espera de la conexion imprime en consola el mensaje " Connected!"
print("Connecting to MQTT server... ", end="") #Imprime en consola el mensaje "Connecting to MQTT server... " sin salto de linea
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD) #Crea el objeto "client" correspondiente al cliente MQTT, los parametros corresponden al ID del cliente, la dirección del broker, el usuario y la contraseña, se que especificaron en las variables creadas anteriormente.
client.connect() #Ejecuta la funcion connect en el objeto cliente, esta funcion realiza la conexion del cliente con el servidor MQTT
print("Connected!") #Imprime en consola el mensaje "Connected!"
prev_weather = "" #Establece la variable "prev_weather" en blanco, esta variable almacena la lectura anterior del sensor DHT22
while True: #Se inicia la ejecucion de un bucle infinito para ejecutar indefinidamente el siguiente codigo
print("Measuring weather conditions... ", end="") #Imprime en consola el mensaje "Measuring weather conditions... " sin salto de linea
sensor.measure() #Ejecuta la funcion measure en el objeto sensor, esta funcion realiza la lectura del sensor DHT22
message = ujson.dumps({ #Crea un objeto JSON llamado "message" y coloca los datos de manera serial en una cadena usando el módulo "ujson"
"temp": sensor.temperature(), #El primer dato de la cadena corresponde a la lectura de la temperatura del sensor DHT22
"humidity": sensor.humidity(), #El siguiente dato de la cadena corresponde a la lectura de la humedad del sendor DHT22
})
if message != prev_weather: #Realiza una comparacion entre las variables message y prev_weather, si son diferentes se ejecuta el codigo
print("Updated!") #Imprime en consola el mensaje "Updated!"
print("Reporting to MQTT topic {}: {}".format(MQTT_TOPIC, message)) #Imprime en consola el mensaje "Reporting to MQTT topic" y lo concatena con la variable MQTT_TOPIC y la cadena message
client.publish(MQTT_TOPIC, message) #Ejecuta la funcion publish del cliente MQTT, esta funcion muestra al Broker el tema y los valores de temperatura y humedad leidos por el sensor (argumentos de la funcion)
prev_weather = message #Actualiza la variable "prev_weather" con los valores de temperatura y humedad leidos
else: #Si no se cumple la condicion message != prev_weather se ejecuta el siguiente codigo
print("No change") #Imprime en consola el mensaje "No change"
time.sleep(1) #Realiza una pausa de 1 segundo