#include "WiFi.h"
#include "ThingsBoard.h"
#include "DHTesp.h"
#include "Arduino_MQTT_Client.h"
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);
// WiFi CONFIGURATIONS
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASS ""
WiFiClient esp32; // initialize esp32 as WiFiClient object
// THINGSBOARD CONFIGURATIONS
#define THINGSBOARD_TOKEN "SF1tzOxF7wvNsdRLl8gg"
#define THINGSBOARD_SERVER "thingsboard.cloud"
Arduino_MQTT_Client mqttClient(esp32); // initialize esp32 as MQTT Client object

constexpr uint16_t MAX_MESSAGE_SIZE = 256U; // set the max message size to be sent to TB
ThingsBoard tbcloud(mqttClient, MAX_MESSAGE_SIZE); // initialize the MQTT Client (esp32) object of TB

// DHT22 SENSOR CONFIGURATIONS
const int dhtPin = 15; // set pin 15 for DHT22
DHTesp dht22; // initialize dht22 as DHTesp sensor object

// FUNCTION TO CONNECT TO WOKWI DEFAULT WIFI
#include <DHT.h>
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

void connectToWiFi() {
  Serial.println("Connecting to WiFi...");
  int attempts = 0;

  while (WiFi.status() != WL_CONNECTED && attempts < 20) {
    WiFi.begin(WIFI_SSID, WIFI_PASS, 6);
    delay(500);
    Serial.print(".");
    attempts++;
  }
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("\nFailed to connect to WiFi.");
  } else {
    Serial.println("\nConnected to WiFi");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }
}
// FUNCTION TO CONNECT TO THINGSBOARD CLOUD VIA THINGSBOARD SERVER & TOKEN
void connectToThingsBoard() {
  if (!tbcloud.connected()) {
    Serial.println("Connecting to ThingsBoard server");
    if (!tbcloud.connect(THINGSBOARD_SERVER, THINGSBOARD_TOKEN)) {
      Serial.println("Failed to connect to ThingsBoard");
    }   else {
          Serial.println("Connected to ThingsBoard");
    }
  }
}
// FUNCTION TO SEND JSON DATA TO THINGSBOARD CLOUD
void sendDataToThingsBoard(float temp, int hum) {
  String jsonData = "{\"temperature\":" + String(temp) + ",\"humidity\":" + String(hum) + "}";
  tbcloud.sendTelemetryJson(jsonData.c_str());
  Serial.println("Data sent");
}

void setup() {
  Serial.begin(115200);
  dht22.setup(dhtPin, DHTesp::DHT22);
  connectToWiFi();
  connectToThingsBoard();

  dht.begin();
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("SUHU KELAS TI6B");
  delay(2000);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Temperatur");
  lcd.setCursor(0, 1);
  lcd.print("Kelembapan");
  delay(2000);
  lcd.clear();
}

void loop() {
  connectToWiFi();

  TempAndHumidity data = dht22.getTempAndHumidity();
  float temp = data.temperature;
  int hum = data.humidity;

  Serial.println(temp);
  Serial.println(hum);

  if (!tbcloud.connected()) {
    connectToThingsBoard();
  }

  sendDataToThingsBoard(temp, hum);
 
  delay(3000);
 
  tbcloud.loop();

  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  lcd.setCursor(0, 0);
  lcd.print(F("Suhu : "));
  lcd.print(temperature);
  lcd.setCursor(0, 1);
  lcd.print(F("Humidity: "));
  lcd.print(humidity);
  delay(1000);
}