#include <Servo.h>

const int ldrPin = A0;
const int hujanPin = 2;
const int buzzer = 3;
const int green = 6;
const int red = 7;
const int servoPin = 12;

String status = "terbuka"; // Membuat variabel string untuk menampilkan status apakah "terbuka" atau "tertutup"
int position; // Membuat variabel untuk menentukan posisi, 90 untuk buka dan 160 untuk tutup
const int threshold = 150; // ambang batas cahaya

// Variabel untuk kalkulasi cahaya
const float GAMMA = 0.7;
const float RL10 = 50;

Servo myServo;

void setup() {
  Serial.begin(9600);
  myServo.attach(servoPin);
  // Menginisialisasi pin-pin yang akan digunakan
  pinMode(ldrPin, INPUT);
  pinMode(hujanPin, INPUT);
  pinMode(green, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(buzzer, OUTPUT);
}

void loop() {
  // Mengambil inputan dari sensor LDR, dan memasukkan kedalam variabel analogValue untuk dilakukan kalkulasi
  int analogValue = analogRead(ldrPin);
  // Mengkalkulasi nilai cahaya berdasarkan inputan dari analogValue
  float voltage = analogValue / 1024. * 5;
  float resistance = 2000 * voltage / (1 - voltage / 5);
  float cahaya = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));

  // Mengambil inputan dari sensor hujan, dan memasukkan kedalam variabel sensorHujan
  int sensorHujan = digitalRead(hujanPin);

  // Menampilkan nilai status ke serial monitor
  Serial.print("Status: ");
  Serial.println(status);
  // Nyalakan lampu hijau ketika dalam status idle atau tidak melakukan apa-apa
  digitalWrite(green, HIGH);

  // sensorHujan bernilai 0 jika terjadi hujan
  // cahaya gelap jika cahaya bernilai 150 kebawah

  // Jika atap saat ini terbuka & hujan & cahaya gelap, maka tutup atap 
  if(status == "terbuka" && sensorHujan == 0 && cahaya < threshold){
    tutupAtap();
    status = "tertutup";
  }

  // Jika atap saat ini terbuka & hujan, maka tutup atap 
  if(status == "terbuka" && sensorHujan == 0){
    tutupAtap();
    status = "tertutup";
  }

  // Jika atap saat ini terbuka & cahaya gelap, maka tutup atap 
  if(status == "terbuka" && cahaya < threshold){
    tutupAtap();
    status = "tertutup";
  }

  // Jika atap saat ini tertutup & tidak hujan & cahaya terang, maka buka atap
  else if (status == "tertutup" && sensorHujan == 1 && cahaya >= threshold) {
    bukaAtap();
    status = "terbuka";
  }

  // Ketika proses buka / tutup selesai, matikan lampu merah
  digitalWrite(red, LOW);
}

// Membuat fungsi untuk membunyikan buzzer
void bunyi() {
  digitalWrite(buzzer, HIGH);
  delay(100);
  digitalWrite(buzzer, LOW);
  delay(100);
}

// Membuat fungsi untuk membuka atap
void bukaAtap() {
  // Matikan lampu hijau dan nyalakan lampu merah ketika proses buka
  digitalWrite(green, LOW);
  digitalWrite(red, HIGH);
  bunyi(); // Memanggil fungsi bunyi()
  // Lakukan proses buka atap menggunakan servo
  for (position = 160; position >= 90; position -= 1) {
    myServo.write(position);
    delay(15);
  }
  position = 90; // Set position ke 90 derajat (buka)
}

// Membuat fungsi untuk menutup atap
void tutupAtap() {
  // Matikan lampu hijau dan nyalakan lampu merah ketika proses tutup
  digitalWrite(green, LOW);
  digitalWrite(red, HIGH);
  bunyi(); // Memanggil fungsi bunyi()
  // Lakukan proses tutup atap menggunakan servo
  for (position = 90; position <= 160; position += 1) {
    myServo.write(position);
    delay(15);
  }
  position = 160; // Set position ke 160 derajat (tutup)
}