#include <WiFi.h>
#include <MQTT.h>
#include <HTTPClient.h>
#include <LiquidCrystal_I2C.h>
#include <Stepper.h>
#include <PubSubClient.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include<DHT.h>
DHT dht(13, DHT22);
#define RelayPin 32
#define Lsensor 34
#define Tsensor 35
#define Soilsensor 2

const int stepsPerRevolution = 400;
Stepper stepper(stepsPerRevolution, 33, 25, 26, 27);

int ledPin = 23;
int brightness = 0;
int pumpState = 0;
int ventState = 0;

WiFiClient TCPclient;
MQTTClient MQTTclient;
PubSubClient client(TCPclient);
char* MQTThostName = "plant-care-project.cloud.shiftr.io";

void setup() {

  lcd.init();
  lcd.backlight();
  stepper.setSpeed(60);
  lcd.setCursor(0, 0);
  lcd.print("Connecting to ");
  lcd.setCursor(0, 1);
  lcd.print("WiFi ");

  Serial.begin(9600);
  pinMode(RelayPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(19, OUTPUT);
  pinMode(18, OUTPUT);
  pinMode(5, OUTPUT);
  WiFi.mode(WIFI_STA);
  WiFi.begin("Wokwi-GUEST", "");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("WiFi connected");

  // IPAddress MQTThostIP(34, 77, 13, 55);
  // MQTTclient.begin(MQTThostIP, 1883, TCPclient);

  // if (MQTTclient.connect("valentinDovbyshev", "public", "public")) {
  //   lcd.setCursor(1, 1);
  //   lcd.print("Connected to");
  //   lcd.setCursor(3, 2);
  //   lcd.print("MQTT broker.");
  //   Serial.println("Connected to MQTT broker.");
  // }
  IPAddress MQTThostIP(34, 77, 13, 55);
  MQTTclient.begin(MQTThostIP, 1883, TCPclient);

  if (MQTTclient.connect("valentinDovbyshev", "plant-care-project", "oDUFqWObrkAP09FZ")) {
    lcd.setCursor(1, 1);
    lcd.print("Connected to");
    lcd.setCursor(3, 2);
    lcd.print("MQTT broker.");
    Serial.println("Connected to MQTT broker.");
  }

  MQTTclient.onMessage(color);
  MQTTclient.subscribe("color");

  delay(1500);

  dht.begin();
  lcd.clear();
}

void loop() {
  MQTTclient.loop();
  ventState = 0;
  
  int temperature = dht.readTemperature();
  int humidity= dht.readHumidity();
  int light = 1023 - analogRead(Lsensor);
  int lightpercent= light * 0.097;
  int Tsoil= 1023 - analogRead(Tsensor);
  Tsoil= Tsoil * 0.097;
  int soil_mes= analogRead(Soilsensor);
  soil_mes= soil_mes* 0.097;
  brightness=map(lightpercent, 0, 1024, 0, 255);

  if (temperature > 30.0) {
    moveStepper();
    ventState = 1;
  }

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("temperature:");
  lcd.setCursor(13,0);
  lcd.print(temperature);
  lcd.setCursor(16,0);
  lcd.print("C");
  char tempString[8];
  itoa(temperature, tempString, 10);
  MQTTclient.publish("Temperature", tempString);

  lcd.setCursor(0,1);
  lcd.print("humidity:");
  lcd.setCursor(10,1);
  lcd.print(humidity);
  lcd.setCursor(13,1);
  lcd.print("%");
  char humString[8];
  itoa(humidity, humString, 10);
  MQTTclient.publish("Humidity", humString);
  
  lcd.setCursor(0,2);
  lcd.print("vent:");
  lcd.setCursor(6,2);
  if (ventState == 1) {
    lcd.print("ON");
    MQTTclient.publish("Vent", "ON");
  }
  else {
    lcd.print("OFF");
    MQTTclient.publish("Vent", "OFF");
  }

  lcd.setCursor(0,3);
  lcd.print("pump:");
  lcd.setCursor(6,3);
  if (pumpState == 1) {
    lcd.print("ON");
    MQTTclient.publish("Pump", "On");
  }
  else {
    lcd.print("OFF");
    MQTTclient.publish("Pump", "OFF");
  }

  Serial.println(Tsoil);
  delay(50);

  if(light < 30){
    lcd.backlight();
    analogWrite(ledPin, HIGH);
  }
  else{
    lcd.noBacklight();
    analogWrite(ledPin, LOW);
  }

  if(humidity <= 50){
    digitalWrite(RelayPin, HIGH);
    pumpState = 1;
    delay(1000);
  }
  else{
    digitalWrite(RelayPin, LOW);
    pumpState = 0;
    delay(1000);
  }

  if (temperature > 30.0) {
    moveStepper();
  }
}

void moveStepper() {
  stepper.step(stepsPerRevolution);
}

void color(String& topic, String& payload) {
  uint32_t colorValue = strtol(payload.c_str() + 1, NULL, 16); 
  
  uint8_t red = (colorValue >> 16) & 0xFF;
  uint8_t green = (colorValue >> 8) & 0xFF;
  uint8_t blue = colorValue & 0xFF;
  
  analogWrite(19, 255 - red);
  analogWrite(18, 255 - green);
  analogWrite(5, 255 - blue); 

  Serial.println(payload);
}
$abcdeabcde151015202530fghijfghij
NOCOMNCVCCGNDINLED1PWRRelay Module