#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
//------------------Output--------------------------
#include <ESP32Servo.h>
Servo MyServo;
int servoPin = 21;

int LED1 = 22;
int LED2 = 23;

int LampMode, LampState, LDRState, FanMode, FanState, DoorMode, ServoValue,DoorState;
float temp, hum;
//------------------Input--------------------------
#include <DHT.h>
#define DHTPIN 14
#define DHTTYPE DHT11
long lastMsg = 0;
DHT dht(DHTPIN, DHTTYPE);

int LDR_D0 = 25;
int LDR_A0 = 34;
int LDRValueD0;
int LDRValueA0;


#include <UltrasonicSensor.h>
UltrasonicSensor ultrasonic(26, 27);
int distance;
//-------------------Config------------------------------------
#define ssid "Wokwi-GUEST"  //WIFI Name***
#define pass ""       //Password ***
const char* mqtt_server = "broker.mqttdashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);
void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  // WiFi.begin("Wokwi-GUEST", "");
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println(WiFi.status());
    Serial.print('.');
    delay(1000);
  }
  Serial.println("Connected");
  Serial.println(WiFi.status());
  Serial.println(WiFi.localIP());
  Serial.print("RRSI: ");
  Serial.println(WiFi.RSSI());
}

//-------------------void_setup------------------------------------
void setup() {
  Serial.begin(115200);
  initWiFi();
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  MyServo.attach(servoPin);
  MyServo.write(90);
  pinMode(LDR_D0, INPUT);
  dht.begin();
  ultrasonic.setTemperature(22);
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

//-------------------WiFi_Connect------------------------------------


//-------------------MQTT_Connect------------------------------------
void MQTT_Connect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("Your Name")) {  //***
      Serial.println("connected");
      client.subscribe("IOT/Sub/LampMode/Thanakon");    //***
      client.subscribe("IOT/Sub/LampState/Thanakon");   //***
      client.subscribe("IOT/Sub/LDRState/Thanakon");   //***
      client.subscribe("IOT/Sub/DoorMode/Thanakon");    //***
      client.subscribe("IOT/Sub/Door/Servo/Thanakon");  //***
      client.subscribe("IOT/Sub/FanMode/Thanakon");     //***
      client.subscribe("IOT/Sub/FanState/Thanakon");    //***
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      delay(2000);
    }
  }
}

//-------------------Callback_topic--------------------------------
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Received message: ");
  //----------------Lamp-----------------
  if (String(topic) == "IOT/Sub/LampMode/Thanakon") {  //***
    StaticJsonDocument<300> JSONLampMode;
    deserializeJson(JSONLampMode, payload);
    LampMode = JSONLampMode["LampMode"];
  }
  if (String(topic) == "IOT/Sub/LampState/Thanakon") {  //***
    StaticJsonDocument<300> JSONLampState;
    deserializeJson(JSONLampState, payload);
    LampState = JSONLampState["LampState"];
  }
  //----------------Fan-----------------
  if (String(topic) == "IOT/Sub/FanMode/Thanakon") {  //***
    StaticJsonDocument<300> JSONFanMode;
    deserializeJson(JSONFanMode, payload);
    FanMode = JSONFanMode["FanMode"];
  }
  if (String(topic) == "IOT/Sub/FanState/Thanakon") {  //***
    StaticJsonDocument<300> JSONFanState;
    deserializeJson(JSONFanState, payload);
    FanState = JSONFanState["FanState"];
  }
  //----------------Raindrop-----------------
  if (String(topic) == "IOT/Sub/DoorMode/Thanakon") {  //***
    StaticJsonDocument<300> JSONRainMode;
    deserializeJson(JSONRainMode, payload);
    DoorMode = JSONRainMode["DoorMode"];
  }
  if (String(topic) == "IOT/Sub/Door/Servo/Thanakon") {  //***
    StaticJsonDocument<300> JSONServo;
    deserializeJson(JSONServo, payload);
    ServoValue = JSONServo["ServoValue"];
  }
  if (String(topic) == "IOT/Sub/LDRStateState/Thanakon") {  //***
    StaticJsonDocument<300> JSONRainState;
    deserializeJson(JSONRainState, payload);
    LDRState = JSONRainState["LDRState"];
  }
  Serial.print("LampMode: ");
  Serial.println(LampMode);
  Serial.print("LampState: ");
  Serial.println(LampState);
  Serial.print("FanMode: ");
  Serial.println(FanMode);
  Serial.print("FanState: ");
  Serial.println(FanState);
  Serial.print("DoorMode: ");
  Serial.println(DoorMode);
  Serial.print("DoorState: ");
  Serial.println(DoorState);
  Serial.print("ServoValue: ");
  Serial.println(ServoValue);
}
//-------------------void_loop------------------------------------
void loop() {
  //----------------Rain-----------------
  if (DoorMode == 1) {  //Auto
    if (distance > 10) {
      MyServo.write(90);
      delay(500);
    } else if (distance <= 10 and (DoorMode == 1)) {
      MyServo.write(0);
      delay(500);
    }
  } else if (DoorMode == 0) {  //Manual
    if (ServoValue <= 90) {
      MyServo.write(ServoValue);
      delay(500);
    }
  }
  //----------------Fan-----------------
  if (FanMode == 0) {  //Manual
    if (FanState == 1) {
      digitalWrite(LED2, HIGH);
    } else {
      digitalWrite(LED2, LOW);
    }
  } else if (FanMode == 1) {  //Auto
    if (hum >= 60) {          //Adjust
      digitalWrite(LED2, HIGH);
    } else {
      digitalWrite(LED2, LOW);
    }
  }
  //----------------Lamp-----------------
  if (LampMode == 0) {  //Manual
    if (LampState == 1) {
      digitalWrite(LED1, HIGH);
    } else {
      digitalWrite(LED1, LOW);
    }
  } else if (LampMode == 1) {  //Auto
    if (LDRState == 1) {
      digitalWrite(LED1, HIGH);
    } else {
      digitalWrite(LED1, LOW);
    }
  }

  if (!client.connected()) {
    MQTT_Connect();
  }
  client.loop();
  // long now = millis();
  // if (now - lastMsg > 1000) {
  //   lastMsg = now;
  //   temp = dht.readTemperature();
  //   hum = dht.readHumidity();
  //   LDRValueD0 = digitalRead(LDR_D0);
  //   LDRValueA0 = analogRead(LDR_A0);
  //   int LDRValueMap = map(LDRValueA0, 0, 4095, 100, 0);
  //   distance = ultrasonic.distanceInCentimeters();
  //   delay(20);
  //   StaticJsonDocument<300> JSONdata;
  //   JSONdata["temperature"] = temp, 2;
  //   JSONdata["humidity"] = hum, 2;
  //   JSONdata["LDRValueA0"] = LDRValueMap, 2;
  //   JSONdata["Ultrasonic"] = distance, 2;

  //   char JSONmsg[300];
  //   serializeJson(JSONdata, JSONmsg);
  //   client.publish("IOT/Pub/PPTS", JSONmsg); //***
  // }
}
$abcdeabcde151015202530fghijfghij