#include <WiFi.h>   
#include <PubSubClient.h>
#include <DHTesp.h>

//library DHT22   https://github.com/dvarrel/DHT22/blob/main/examples/dht22test/dht22test.ino
#include <DHT22.h>
//define pin data
#define pinDATA 21 // SDA, or almost any other I/O pin

DHT22 dht22(pinDATA); 

//Parametros conexao ESP32 a rede WiFi
const char* ssid = "Wokwi-GUEST";
const char* password = "";
//Parâmetros MQTT
const char *mqtt_broker = "test.mosquitto.org"; 
const char *topic1 = "DHT11_TEMP";
const char *topic2 = "DHT11_HUM";
const char *mqtt_username = "";
const char *mqtt_password = "";
const int mqtt_port = 1883;

//Wifi-MQTT
WiFiClient espClient;  
PubSubClient client (espClient);
bool Connected =  0;
char msg_out1[20];
char msg_out2[20];

//Definição DHT
//DHT dht(15, DHT11); 

//Definição DHT
//const int DHT_PIN = 5;  
//DHTesp dht; 

//WiFiClient espClient;
//PubSubClient client(espClient);
unsigned long lastMsg = 0;
float temp = 0;
float hum = 0;

void setup(){
  Serial.begin(115200);
  setup_wifi(); 
  client.setServer(mqtt_broker, mqtt_port);
  //client.setCallback(callback); 
  //dht.setup(DHT_PIN, DHTesp::DHT22);
  delay(300);
}

void setup_wifi() { 
  Serial.print("Connecting to: ");
  Serial.println(ssid);
  //Conexão Wifi
  WiFi.mode(WIFI_STA); 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { 
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());   //initializes the pseudo-random number generator
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}
//Conexao inicial ou reconexao se houver perda de conectividade com MQTT
void reconnect() { 
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    //Gerar um Client ID aleatorio e diferente do que possa existir para evitar conflitos
    String clientId = "ESP32Client-GC";
    clientId += String(random(0xffff), HEX);
    if (client.connect(clientId.c_str())) {
      Serial.println("Connected");
      client.subscribe("tempVR");
      //client.publish("/ThinkIOT/Publish", "Welcome");
      //client.subscribe("/ThinkIOT/Subscribe"); 
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }}
}

void loop() {
  if (!client.connected()) {
    reconnect(); 
  }
  client.loop();  
  unsigned long now = millis();
  //ENviar dados para MQTT a cada 2 segundos
  if (now - lastMsg > 3000) { 
    lastMsg = now;
    //TempAndHumidity  data = dht.getTempAndHumidity();
    //DHT22
    Serial.println(dht22.debug()); //optionnal
    float t = dht22.getTemperature();
    float h = dht22.getHumidity();
    t += 0.1;
    h += 0.2;
    Serial.print("h=");Serial.print(h,1);Serial.print("\t");
    Serial.print("t=");Serial.println(t,1);
  if (dht22.getLastError() != dht22.OK) {
    Serial.print("last error :");
    Serial.println(dht22.getLastError());
  }
    String temp = String(t, 2);//String(data.temperature, 2);
    client.publish(topic1, temp.c_str());
    //Ou também pode ser usada a seguinte função para enviar para MQTT
    //dtostrf(temp,2,2,msg_out1);
    Serial.print("Temperatura: ");
    Serial.println(temp);

    String hum = String(h, 2);//String(data.humidity, 1); 
    client.publish(topic2, hum.c_str());   
    //Ou também pode ser usada a seguinte função para enviar para MQTT
    //dtostrf(hum,2,2,msg_out2);
    Serial.print("Umidade: ");
    Serial.println(hum);
  }
}