// Proses include library 
#include "DHTesp.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
#define led1 16
#define led2 17
#define led3 18

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Deklarasi variable
#define DHTPIN 26
DHTesp dht;

// Deklarasi gambar
const uint8_t gambarHujan[] PROGMEM = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x03, 0xb8, 0x00, 0x00, 0x06, 0x04, 0x00, 
	0x00, 0x7c, 0x06, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x00, 0x80, 0x03, 0x80, 0x01, 0x80, 0x00, 0xc0, 
	0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x10, 
	0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x30, 0x04, 0x00, 0x00, 0x60, 0x03, 0xff, 0xff, 0xc0, 
	0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc6, 0x00, 0x00, 0x39, 0xce, 0x00, 
	0x00, 0x4a, 0x5a, 0x00, 0x00, 0x7b, 0xda, 0x00, 0x00, 0x31, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

};

const uint8_t gambarCerah[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 
	0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x80, 
	0x01, 0x81, 0x81, 0x80, 0x00, 0xcf, 0xf3, 0x00, 0x00, 0x1f, 0xfa, 0x00, 0x00, 0x38, 0x1c, 0x00, 
	0x00, 0x70, 0x0e, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0xe0, 0x06, 0x00, 0x1e, 0xe0, 0x07, 0xf8, 
	0x1e, 0xe0, 0x07, 0x78, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x70, 0x0e, 0x00, 
	0x00, 0x38, 0x1c, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0xcf, 0xf3, 0x00, 0x00, 0xc1, 0x03, 0x80, 
	0x01, 0x81, 0x01, 0x80, 0x01, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 
	0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

};

const uint8_t gambarBerawan[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0xe0, 0x70, 0x00, 
	0x01, 0xc0, 0x38, 0x00, 0x03, 0x80, 0x1c, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x3f, 0x00, 
	0x06, 0x00, 0x7f, 0x80, 0x0e, 0x00, 0xe1, 0xc0, 0x3e, 0x01, 0xc0, 0x60, 0x70, 0x03, 0x80, 0x70, 
	0x60, 0x03, 0x00, 0x3c, 0xc0, 0x07, 0x00, 0x0e, 0xc0, 0x0f, 0x00, 0x06, 0xc0, 0x18, 0x00, 0x03, 
	0xc0, 0x30, 0x00, 0x03, 0x60, 0x30, 0x00, 0x03, 0x70, 0x30, 0x00, 0x03, 0x3f, 0xf0, 0x00, 0x07, 
	0x1f, 0xf8, 0x00, 0x0e, 0x00, 0x1f, 0xe6, 0x7c, 0x00, 0x07, 0xe6, 0x78, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

};

void setup() {
  // Inisiasi interface serial
  Serial.begin(115200);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  // Inisiasi sensor DHT
  dht.setup(DHTPIN, DHTesp::DHT22);

  // Inisialisasi OLED
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address I2C OLED: 0x3C
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  display.display();
  delay(2000);
  display.clearDisplay();
}

void loop() {
  // Deklarasi objek untuk menampung data temperatur dan kelembaban dari DHT22
  TempAndHumidity data = dht.getTempAndHumidity();
  
  // Ekstrak data temperature dan kelembaban
  float temp = data.temperature;
  float hum = data.humidity;
  
  // Menampilkan data di serial monitor
  Serial.println("Suhu: " + String(temp, 2) + "°C");
  Serial.println("Kelembaban: " + String(hum, 1) + "%");

  // Menampilkan data di OLED
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.println("Suhu: " + String(temp, 2) + " C");
  display.println("Kelembaban: " + String(hum, 1) + "%");

  // Menentukan kondisi cuaca dan menampilkan gambar sesuai kondisi cuaca
  if (temp > 30 && hum < 50) {
    display.drawBitmap(0, 24, gambarCerah, 32, 32, 1);
    display.println("Cuaca panas & kering");
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
  } 
  else if (temp > 30 && hum >= 50) {
    display.drawBitmap(50, 24, gambarBerawan, 32, 32, 1);
    display.println("Cuaca panas & lembab");
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
  } 
  else if (temp >= 20 && temp <= 30 && hum < 60) {
    display.drawBitmap(50, 24, gambarBerawan, 32, 32, 1);
    display.println("Cuaca sejuk & kering");
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
  } 
  else if (temp >= 20 && temp <= 30 && hum >= 60) {
    display.drawBitmap(85, 24, gambarHujan, 32, 32, 1);
    display.println("Cuaca sejuk & lembab");
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
  } 
  else if (temp < 20 && hum < 50) {
    display.drawBitmap(85, 24, gambarHujan, 32, 32, 1);
    display.println("Cuaca dingin & kering");
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
  } 
  else if (temp < 20 && hum >= 50) {
    display.drawBitmap(85, 24, gambarHujan, 32, 32, 1);
    display.println("Cuaca dingin & lembab");
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
  } 
  else {
    display.println("Cuaca tidak dapat ditentukan");
  }
  display.display();
  
  // Waktu jeda sampling data
  // Minimal 2 detik
  delay(5000);
}