// Template ID dan Device Name serta Auth Token untuk menyambungkan ke Blynk
#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "TMPLdDIfiYih"
#define BLYNK_DEVICE_NAME "IoT Sensor LDR"
#define BLYNK_AUTH_TOKEN "PrVSpO8tEhp_jlFCMA6QBvCtH53u42sp"

// library untuk memproses LED DOT Matrix
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Library untuk memproses wifi dan iot gateway Blynk
#include <WiFi.h>               // WiFi control for ESP32
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>   // Blynk SDK/Library

// Mendefinisikan jenis hardware
#define HARDWARE_TYPE  MD_MAX72XX::PAROLA_HW

// Mendefinisikan pin yang digunakan
#define MAX_DEVICES 4
#define CS_PIN 5
#define LDR_PIN 36
#define LED_PIN 22

MD_Parola Display = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

//Konfigurasi wifi
char ssid[] = "Wokwi-GUEST";
char pass[] = "";

// konstanta untuk perhitungan lux
const float GAMMA = 0.7;
const float RL10 = 50;

// fungsi untuk mengatur kata yang akan ditampilkan pada LED Matrix
void redled (float lux) {
  if (lux <= 10) {
      Serial.println(" => Malam");
      Display.displayText("malam", PA_CENTER, 10, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    } else if (lux <= 1000) {
      Serial.println(" => Pagi/Mendung");
      Display.displayText("Pagi", PA_CENTER, 10, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    } else if (lux <= 10000) {
      Serial.println(" => Siang");
      Display.displayText("Siang", PA_CENTER, 10, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    } else {
      Serial.println(" => Siang Sangat Terang");
      Display.displayText("sangat cerah", PA_CENTER, 10, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    }
    delay(150);
}

// fungsi untuk mengolah analog data, otomatisasi nyala LED dan mengirim data ke blynk
void sendData() {
  // mendeklarasikan nilai analog ke dalam variabel light
  int light = analogRead(LDR_PIN);
  //volt / tegangan
  float voltage = light / 4095. * 5;
  // hambatan
  float resistance = 2000 * voltage / (1 - voltage / 5);
  // lux merupakan satuan turunan SI dari pencahayaan dan daya pancar cahaya
  float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));

  Blynk.virtualWrite(V1, light); // Mengirim data light ke blynk
  Blynk.virtualWrite(V2, lux); // mengirim data lux ke blynk

  if (Display.displayAnimate()) {
    Serial.print("Sending data...");
    Serial.print(" analog: ");
    Serial.print(light);
    Serial.print(" lux: ");
    Serial.print(lux);

  if(lux <= 10){
    digitalWrite(LED_PIN, HIGH);          // turn on LED
    Blynk.virtualWrite(V3, 255);          // hidupkan LED di aplikasi
    redled(lux);
    }
  else {
    digitalWrite(LED_PIN, LOW);           // turn off LED
    Blynk.virtualWrite(V3, 0);           // matikan LED di aplikasi
    redled(lux);
    }

    Display.displayReset();
  }

}

// mendelarasikan fungsi timer blynk
BlynkTimer timer;

// fungsi untuk menerima data dari server/aplikasi
// berfungsi sebagai tombol on/off LED dari aplikasi/web
BLYNK_WRITE(V3) {
  if(param.asInt()==255){
    digitalWrite(LED_PIN, HIGH);
  }
  else{
    digitalWrite(LED_PIN, LOW);
  }
}

// fungsi utama yang akan dijalankan pertama kali
void setup() {
  pinMode(LDR_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  // Initialize serial for debugging
  Serial.begin(115200);

  delay(500);
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
  
  // Intialize the object:
  Display.begin();
  // Set the intensity (brightness) of the display (0-15):
  Display.setIntensity(0);
  // Clear the display:
  Display.displayClear();

  timer.setInterval(1L, sendData);
}

// fungsi loop yang akan dijalankan berulang kali
void loop() {
  Blynk.run();
  timer.run();

}