// mengakses file-file library
#include <WiFi.h>           //library bekerja dengan wifi
//#include <WiFiClient.h>
#include <PubSubClient.h>   //library MQTT
#include <LiquidCrystal_I2C.h> // Library for LCD


// pin 18 diberi alias greenLED

LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 20 column and 4 rows



// data akun konek ke SSID
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// data akun MQTT server/broker
const char* hostname = "broker.hivemq.com";
int PORTNUM = 1883;
const char* topicMQTT = "rekal/lcd";

// membuat object untuk mengelola koneksi wifi
WiFiClient espClient;

//membuat object untuk mengelola layanan MQTT
//diberi nama clientMQTT
PubSubClient clientMQTT(espClient);

// Device ID / ID perangkat ESP32 yang digunakan
const char* espClientName = "esp32Client_123456N99";

// function konek ke Wifi SSID
void setup_wifi()
{
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED )
  {
    delay(1000);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("Terkoneksi ke : ");
  Serial.println(ssid);
  Serial.print("IP Address : ");
  Serial.println(WiFi.localIP());
}

// function untuk konek ke MQTT Server
void connectMQTT()
{
  while(!clientMQTT.connected() )
  {
    Serial.println("Sedang konek ke MQTT ...");
    if (clientMQTT.connect(espClientName) ) //, mqttUser, mqttPassword) )
    {
      Serial.println("Terkoneksi MQTT Server");
      //memanggil function MQTTSubscribe()
      MQTTSubscribe();
    }
    else
    {
      Serial.print("Gagal koneksi ke MQTT Server: ");
      Serial.print(clientMQTT.state() );
      delay(2000);
    }
  }
}

// function membaca data dari publisher
// membaca pesan yang masuk
// data yang diterima:
//   topic    bertipe string
//   payload  bertipe byte, pesan yang diterima
//   length   bertipe integer, panjang data
void callback(String topic, byte* payload, unsigned int length)
{
  // variabel untuk menyimpan data sementara dalam tipe string
  // nama variabel messageTemp
  String messageTemp;

  //menampilkan pesan di Serial
  Serial.print("Pesan diterima di topic : ");
  Serial.println(topic);
 // Serial.print(" length is: ");
 // Serial.println(length);

  Serial.print("Isi pesan yang diterima dari broker: ");
  for (int i = 0; i<length; i++)
  {
    Serial.print( (char)payload[i] );
    lcd.setCursor(i, 1); 
    lcd.write( (char)payload[i] );
    //messageTemp += (char)payload[i];
  }
  Serial.println("");
}

// function untuk setup sebagai subscriber
void MQTTSubscribe() 
{
  // mendaftar jadi subscriber pada topic topicMQTT
  clientMQTT.subscribe(topicMQTT);
}

//function koneksi ke MQTT server
void setup_MQTT() 
{
  // konek ke MQTT Server
  clientMQTT.setServer(hostname, PORTNUM);

  // mengarahkan pembacaan pesan di subecri
  clientMQTT.setCallback(callback); 

}

// Konfigurasi umum
void setup() 
{
  //konfigurasi Serial monitor
  Serial.begin(9600);
  delay(5000);
  lcd.init(); //initialize the lcd
  lcd.backlight(); //open the backlight 

  //lcd.setCursor(0, 0); 
  //lcd.print("LCD 20x4");      
  //koneksi Wifi
  setup_wifi();

  //Koneksi MQTT Broker
  setup_MQTT();
}

void loop() 
{
  // cek koneksi ke MQTT
  if ( !clientMQTT.connected() )
  {
    //Konek ke MQTT server
    connectMQTT();
  }
  clientMQTT.loop();

}