#include "DHTesp.h"
#include <WiFi.h>
#include <PubSubClient.h>

const int LCR_pin = 35;
const int LIGHT_pin = 2;
const int DHT_pin = 18;
const int Water_pump = 12;
const int Soil_pin = 33;  

const char* ssid = "Wokwi-GUEST";
const char* password = "";


const char* host = "maker.ifttt.com";
const int port = 80;
const char* request = "https://maker.ifttt.com/trigger/Notification/with/key/cfX2JeBj5ZVcP9X3avsLHG?value1=";


WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
DHTesp dhtSensor;

//***Set server***
const char* mqttServer = "broker.hivemq.com"; 
int portMQTT = 1883;

void wifiConnect() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" Connected!");
}

void mqttConnect() {
  while(!mqttClient.connected()) {
    Serial.println("Attemping MQTT connection...");
    String clientId = "ESP32Client-";
    clientId += String(random(0xffff), HEX);
    if(mqttClient.connect(clientId.c_str())) {
      Serial.println("Connected");

      //***Subscribe all topic you need***
    }
    else {
      Serial.println("Try again in 5 seconds");
      delay(5000);
    }
  }
}

//MQTT Receiver
void callback(char* topic, byte* message, unsigned int length) {
  Serial.println(topic);
  String strMsg;
  for(int i=0; i<length; i++) {
    strMsg += (char)message[i];
  }
  Serial.println(strMsg);
  //***Code here to process the received package***
}

void sendRequest(float value1) {
  WiFiClient client;
  while(!client.connect(host, port)) {
    Serial.println("connection fail");
    delay(1000);
  }
  client.print(String("GET ") + request + String(value1,0) + " HTTP/1.1\r\n"
              + "Host: " + host + "\r\n"
              + "Connection: close\r\n\r\n");
  delay(500);

  while(client.available()) {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
}


void setup() {
  Serial.begin(115200);
  pinMode(LIGHT_pin, OUTPUT);
  pinMode(LCR_pin, INPUT);
  dhtSensor.setup(DHT_pin,DHTesp::DHT22);
  Serial.print("Connecting to WiFi");
  wifiConnect();
  mqttClient.setServer(mqttServer, portMQTT);
  mqttClient.setCallback(callback);
  mqttClient.setKeepAlive( 90 );
}

/* Light */
float caculate_lux(){
  // These constants should match the photoresistor's "gamma" and "rl10" attributes
  const float GAMMA = 0.7;
  const float RL10 = 50;

  // Convert the analog value into lux value:
  int analogValue = analogRead(LCR_pin);
  float voltage = analogValue / 4096. * 5;
  float resistance = 2000 * voltage / (1 - voltage / 5);
  float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
  return lux;
}

void control_led(){
  float lux = caculate_lux();
  Serial.println("Lux: " + String(lux,2) + " lux");
  if (lux>5000){
    analogWrite(LIGHT_pin,0);
  }
  else if (lux<1000){
    analogWrite(LIGHT_pin,255);
  }
  else {
    analogWrite(LIGHT_pin,(lux-1000)*255/4000);
  }
}

/* Temperature and Huminity */
float get_temperature(){
  TempAndHumidity data = dhtSensor.getTempAndHumidity();
  float temperature = data.temperature;
  Serial.println("Temp: " + String(temperature,2) + "°C");
  return temperature;
}

float get_humidity(){
  TempAndHumidity data = dhtSensor.getTempAndHumidity();
  float humidity = data.humidity;
  Serial.println("Humidity: " + String(humidity,2) + "%");
  return humidity;
}

float get_soilmoist(){
  int value = analogRead(Soil_pin);
  float soil_moist_Percent = map(value, 0, 4096, 0, 100);
  // Serial.println("Soil moisture:" + String(soil_moist_Percent,2) + "%");
  return soil_moist_Percent;
}

/*** Send the data to the Website ***/
void giveSoilMoist(){
  char buffer[50];
  int temp = int(get_soilmoist());
  Serial.println("Soil moisture:" + String(temp) + "%");
  sprintf(buffer,"%d",temp);
  mqttClient.publish("21127230/soilmoist",buffer);
}

void giveTemperature(){
  char buffer[50];
  int temp = int(get_temperature());
  sprintf(buffer,"%d",temp);
  mqttClient.publish("21127230/temperature",buffer);
}

void giveHumidity(){
  char buffer[50];
  int temp = int(get_humidity());
  sprintf(buffer,"%d",temp);
  mqttClient.publish("21127230/humidity",buffer);
}

void giveLightness(){
  char buffer[50];
  int temp = int(caculate_lux());
  sprintf(buffer,"%d",temp);
  mqttClient.publish("21127230/lightness",buffer);
}


void loop() {
  float value1 = get_soilmoist();
  if (value1<=30){
    sendRequest(value1);
    Serial.println();
    Serial.println(" Water Pump ON");
    digitalWrite(Water_pump, HIGH);
    Serial.println();
  }
  else {
    digitalWrite(Water_pump, LOW);
    Serial.println(" Water Pump OFF");

  }
  Serial.println("************************");
  if(!mqttClient.connected()) {
    mqttConnect();
  }
  mqttClient.loop();
  giveSoilMoist();
  giveTemperature();
  giveHumidity();
  giveLightness();
  control_led();
  delay(5000);
}
$abcdeabcde151015202530354045505560fghijfghij