#if defined(ESP8266) //deklarasi library WiFi karena programnya dibuat universal untuk board ESP8266 dan board ESP32 maka menggunakan if untuk dicek terlebih dahulu jenis board yang digunakan
#include <ESP8266WiFi.h> //apabila menggunakan board ESP8266 menggunakan library ESP8266WiFi.h
#elif defined(ESP32)
#include <WiFi.h> //apabila menggunakan board ESP32 maka menggunakan library WiFi.h
#endif

#include "ThingsBoard.h"
#include "DHTesp.h"

#define WIFI_SSID           "Wokwi-GUEST" //deklarasi ssid wifi yang digunakan, disesuiakan dengan wifi yang digunakan
#define WIFI_PASSWORD       "" //deklarasi password wifi yang digunakan

// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
#define TOKEN               "Q1xIxFU9iLCiiFtz1dhq" //deklarasi token device yang digunakan untuk menguhubungkan esp32 dengan device pada thingsboard, tokennya disesuaikan dengan device yang digunakan bisa di cek langsung ketika membuka device pada thingsboard
#define THINGSBOARD_SERVER  "thingsboard.cloud" //alamat server dari thingsboard, jika menggunakan server probadi alamatnya bisa disesuaikan, apabila menggunakan server yang disediakan thingsboard alamatnya adalah thingsboar.cloud

const int DHT_PIN = 15; //deklarasi nomor pin dht

DHTesp dhtSensor; //mengubah perintah DHTesp menjadi dhtSensor, boleh diubah-ubah

// Deklarasi Thingsboard client dan mengubah perintah WiFiClient menjadi espClient
WiFiClient espClient; 
// Deklarasi untuk mengubah perintah Thingsboard menjadi tb dan memasukkan perintah WiFiClient yang sudah diubah menjadi espClient ke dalam library Thingsboard
ThingsBoard tb(espClient);

int status = WL_IDLE_STATUS; //deklarasi status wifi yang dimasukkan dalam variabel status

void connect() //void mengoneksikan esp dengan wifi pertama kali
{
  Serial.println("Connecting to AP ...");
  // attempt to connect to WiFi network

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {

    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected to AP");
}

void reconnect() { //peintah recconect wifi apabila esp terputus dengan jaringan wifinya
  // Loop until we're reconnected
  status = WiFi.status();
  if ( status != WL_CONNECTED) {
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("Connected to AP");
  }
}

void setup() {
  // initialize serial for debugging
  Serial.begin(115200); //inisialisasi dengan serial monitor dengan baudrate 115200
  Serial.println();
  connect(); //memanggil void connect untuk mengoneksikan esp32 dengan jaringan wifi
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22); //inisialisasi sensor dht
}

void loop() {
  delay(1000);

  if (WiFi.status() != WL_CONNECTED) { //perintah untuk reconnect apabila esp32 disconnect dengan wifi
    reconnect();
  }

  if (!tb.connected()) { //perintah untuk koneksi ke server thingsboard/device thingsboard
    // Connect to the ThingsBoard
    Serial.print("Connecting to: ");
    Serial.print(THINGSBOARD_SERVER);
    Serial.print(" with token ");
    Serial.println(TOKEN);
    if (!tb.connect(THINGSBOARD_SERVER, TOKEN)) {
      Serial.println("Failed to connect");
      return;
    }
  }

  Serial.println("Sending data...");

  // Uploads new telemetry to ThingsBoard using MQTT.
  // See https://thingsboard.io/docs/reference/mqtt-api/#telemetry-upload-api
  // for more details

  TempAndHumidity data = dhtSensor.getTempAndHumidity(); //perintah untuk membaca data dari sensor dht22
  tb.sendTelemetryInt("Suhu", data.temperature); //perintah kirim data temperature ke thingsboard dengan menggunakan tipe data integer, key yang digunakan adalah suhu data yang dikirimkan adalah data.temperature, jika ingin mengirim data dari sensor lain bisa disesuaikan
  tb.sendTelemetryFloat("Kelembapan", data.humidity);//perintah kirim data humidity ke thingsboard dengan menggunakan tipe data float, key yang digunakan adalah kelembaban data yang dikirimkan adalah data.humidity
  Serial.print("Suhu : ");
  Serial.print(data.temperature);
  Serial.print("Kelembapan : ");
  Serial.println(data.humidity);

  tb.loop(); //perintah untuk menjalankan fungsi dari library thingsboard
}