#include "DHT.h"
#include <WiFi.h>
#include <PubSubClient.h>

/* CONFIGURAÇÕES DO WIFI */
const char* ssid = "Wokwi-GUEST"; // Nome da rede WiFi
const char* password = ""; // Senha da rede WiFi

/* CONFIGURAÇÕES DO MQTT*/
const char* mqttServer = "broker.hivemq.com"; // Endereço do Broker MQTT
const int mqttPort = 1883; // Porta TCP do Broker MQTT
const char* mqttUser = ""; // Usuário MQTT
const char* mqttPassword = ""; // Senha MQTT

/* DEFINIÇÃO DOS PINOS E VARIÁVEIS*/
int pinoDHT = 4, pinoVent = 5;
int tempoDHT = 0;

float temp, umid;

DHT dht(pinoDHT, DHT22);

WiFiClient espClient; // Cliente de Rede WiFi
PubSubClient clientMqtt(espClient); // Cria uma instancia de um cliente MQTT

void setup() {

    // Configuração dos pinos do ESP32
    pinMode(pinoVent, OUTPUT);
    
    Serial.begin(9600); // Configura a porta serial
    dht.begin(); // Configura o sensor DHT
    WiFi.begin(ssid, password); // Configura o WiFi    

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print("Tentando se conectar na rede: ");
        Serial.println(ssid);
    }

    Serial.println("Conectado na Rede WiFi.");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
    
    clientMqtt.setServer(mqttServer, mqttPort);
    clientMqtt.setCallback(callback);

    /* Verifica se o cliente está conectado ao Broker */
    while (!clientMqtt.connected()) {
        
        Serial.println("Conectando ao Broker MQTT...");
        
        String clientId = "ESP32Client_" + String(random(0xffff), HEX);
        Serial.println("clientId = " + clientId);
        
        /* Conecta o cliente ao Broker MQTT.
           Configurações de credenciais e Last Will podem ser configuradas aqui*/
        if (clientMqtt.connect(clientId.c_str(), mqttUser, mqttPassword )) {
            
            Serial.println("O cliente " + clientId + " foi conectado com sucesso");
        } else {
          
            // Estado do cliente MQTT. Quando a conexão falhar pode ser usado para obter informações sobre a falha
            int clientState = clientMqtt.state();
            
            Serial.print("Falha ao se conectar. ");
            Serial.println("Estado do cliente: " + (String) clientState);
            
            delay(2000);
        }
    }

    // Serial.print("Tentando enviar a mensagem");
    
    clientMqtt.subscribe("unifor/cps/vent");

}

/* A função de callback é chamada quando uma mensagem chega, devido a assinatura de um tópico.
Ou seja, toda vez que chegar uma mensagem em um tópico inscrito por este cliente, a função
callback será chamada. */
void callback(char* topic, byte* payload, unsigned int length) {

    String strTopic = String(topic);
    String strPayload = "";

    for (int i = 0; i < length; i++) {
        strPayload += (char)payload[i];
    }
    
    Serial.print("Uma mensagem chegou no tópico: ");
    Serial.println(strTopic);

    Serial.print("Payload: ");
    Serial.println(strPayload);
    
    if( strTopic == "unifor/cps/vent") {
        if(strPayload == "on") {
            digitalWrite(pinoVent, HIGH);
            Serial.println("Ventilador ligado!");
        } else {
            digitalWrite(pinoVent, LOW);
            Serial.println("Ventilador desligado!");
        }
    }
}

void loop() {
    
    /* loop: função que deve ser chamada regularmente para permitir que o cliente
    processe as mensagens recebidas e mantenha sua conexão com o Broker.*/
    clientMqtt.loop();

    int tempoAtual = millis();

    if(tempoAtual - tempoDHT >= 2000) {
        temp = dht.readTemperature();
        umid = dht.readHumidity();
        
        tempoDHT = tempoAtual;
    }

    if(isnan(temp) || isnan(umid)) {
        Serial.println("Falha na Leitura do sensor");
    } else {
        Serial.print(temp);
        Serial.print(" C - ");
        Serial.print(umid);
        Serial.println("% UR");
    }

    String payload = (String) temp;
    clientMqtt.publish("unifor/cps/temp", payload.c_str());

    payload = (String) umid;
    clientMqtt.publish("unifor/cps/umid", payload.c_str());

    delay(500);
    
}
NOCOMNCVCCGNDINLED1PWRRelay Module