#include <ESP8266WiFi.h> //the library used       //Use ESP8266 functions                                              
 #include <ESP8266HTTPClient.h>
 #include <LiquidCrystal_I2C.h>
 #include "WiFiUdp.h"
 #include "NTPClient.h"
 #include <ArduinoJson.h>
  #include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <dht11.h>
#define DHT11PIN 14// defining the pin for dht11 sensor
dht11 DHT11;
AsyncWebServer server(80);//starting the server for the custom message display feature
 const long utcOffsetInSeconds = 19800;//change according to your timezone 
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
String months[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};//for the months and day feature do not change
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
 
 #include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
  LiquidCrystal_I2C lcd(0x27,16,2);
  String APIKEY = "";     //open weather api key                            
String CityID = "1273294";                                 //Your City ID
  
  const char* ssid = "wifi name";              //WIFI SSID Name                             
  const char* password = "wifi password";        //WIFI Password
  const char* host = "api.thingspeak.com";  //We read the data from this host                                   
  const int httpPortRead = 80;                                           
                                                  
  const char* url1 = "/apps/thinghttp/send_request?api_key=5WX50KDX3R0IBCXQ";     //Change this URL Cases
  const char* url2 = "/apps/thinghttp/send_request?api_key=AHZYGT5QSWRDGCE5";   //Deaths
  const char* url3 = "/apps/thinghttp/send_request?api_key=KCHIW1XDQ4J8G3EE";   //Recovered
  int To_remove;      //There are some irrelevant data on the string and here's how I keep the index
                      //of those characters 
  String Cases,Deaths,Recovered,Time,Data_Raw,Data_Raw_1,Data_Raw_2,Data_Raw_3,Data_Raw_4,Data_Raw_5;  //Here I keep the numbers that I got
  WiFiClient client;      //Create a WiFi client and http client                                                     
  HTTPClient http;
  char servername[]="api.openweathermap.org";              // remote server we will connect to
String result;
int  counter = 60;                                      
String weatherDescription ="";
String weatherLocation = "";
String Country;
String cases = "cases";
float Temperature;
float Humidity;
float Pressure;
String inputMessage="request->getParam(PARAM_INPUT_1)->value()";
String inputMessage2="request->getParam(PARAM_INPUT_2)->value()";
String inputMessage3="request->getParam(PARAM_INPUT_3)->value()";
String inputMessage4="request->getParam(PARAM_INPUT_4)->value()";//for the custom message display
  const char* PARAM_INPUT_1 = "input1";
  const char* PARAM_INPUT_2 = "Alarm Hours";
  const char* PARAM_INPUT_3 = "Alarm Minutes";
  const char* PARAM_INPUT_4 = "Select Screen to display";
  const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>LCD CLOCK CONTROL PANNEL</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  </head><body>
  <form action="/get">
    input1: <input type="text" name="input1">
    <input type="submit" value="Submit">
  </form><br>
   <form action="/get">
    Alarm Hours: <input type="text" name="Alarm Hours">
    <input type="submit" value="Submit">
  </form><br>
   <form action="/get">
    Alarm Minutes: <input type="text" name="Alarm Minutes">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    Select Screen to show: <input type="text" name="Select Screen to display">
    <input type="submit" value="Submit">
  </form><br>
  </body></html>)rawliteral";
  void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");//making the webserver for the custom message display
}
 void setup() {
    lcd.begin(16, 2);
    lcd.init();
    lcd.backlight();
    lcd.setCursor(1, 0);
    lcd.print("SMART CLOCK"); //Change Your Country Name
    lcd.setCursor(1, 1);
    lcd.print("EEP");  //Change Name if you want
    
    Serial.begin(115200);
    WiFi.disconnect();             //Disconnect and reconnect to the Wifi you set                                                 
    delay(1000);                                                                  
    WiFi.begin(ssid, password);                                                   
    Serial.println("Connected to the WiFi network");   //Display feedback on the serial monitor                                        
    Serial.println(WiFi.localIP());
    timeClient.begin();
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });
  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputParam;
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    else  if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
     else  if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage3 = request->getParam(PARAM_INPUT_3)->value();
      inputParam = PARAM_INPUT_3;
    }
     else  if (request->hasParam(PARAM_INPUT_4)) {
      inputMessage4 = request->getParam(PARAM_INPUT_4)->value();
      inputParam = PARAM_INPUT_4;
    }
      else {
      inputMessage = "No message sent";
      
      inputParam = "none";
     
    }
    Serial.println(inputMessage);
    Serial.println(inputMessage2);
    Serial.println(inputMessage3);
     Serial.println(inputMessage4);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field (" 
                                     + inputParam + ") with value: " + inputMessage +
                                     "<br><a href=\"/\">Return to Home Page</a>");
  });
  server.onNotFound(notFound);
  server.begin();
    }
  
void loop() {
  int chk = DHT11.read(DHT11PIN);
    if( http.begin(host,httpPortRead,url1))        //Connect to the host and the url                                      
      {
        int httpCode = http.GET();                //Check feedback if there's a response                                                  
        if (httpCode > 0)                                                              
        {
          if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) 
            {                
              
              Data_Raw = http.getString();   //Here we store the raw data string
            
              
              Data_Raw_1 = Data_Raw;                                    
              To_remove = Data_Raw_1.indexOf(">");                      // here I remove the /span data                                 
              Data_Raw_1.remove(0,To_remove+1);                        
              To_remove = Data_Raw_1.indexOf("<");                                                 
              Data_Raw_1.remove(To_remove,Data_Raw_1.length());           
              Cases=Data_Raw_1;
              Serial.print("Cases: ");  //I choosed to display it on the serial monitor to help you debug
              Serial.println(Cases); 
              
              Data_Raw_2=Data_Raw;
              To_remove = Data_Raw_2.indexOf("<span>");
              Data_Raw_2.remove(0,To_remove+6);
              Data_Raw_3=Data_Raw_2;
              To_remove = Data_Raw_2.indexOf("</span>");
              Data_Raw_2.remove(To_remove,Data_Raw_2.length());
              Deaths=Data_Raw_2;
              Serial.print("Deaths: ");
              Serial.println(Deaths);
            
              To_remove = Data_Raw_3.indexOf("<span>");
              Data_Raw_3.remove(0,To_remove+6);
              To_remove = Data_Raw_3.indexOf("<");
              Data_Raw_3.remove(To_remove,Data_Raw_3.length());
              Recovered=Data_Raw_3;
              
              Serial.print("Recovered: ");
              Serial.println(Recovered);
                                                                                       
            }
        }
        else //If we can't get data
        {
          Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }
        
        http.end();                                                                 
      } 
    else //If we can't connect to the HTTP
      {
        Serial.printf("[HTTP} Unable to connect\n");
      }
    while (WiFi.status() != WL_CONNECTED)     //In case the Wifi connexion is lost                                    
      { 
        
        WiFi.disconnect();                                                        
        delay(1000);                                                             
        
        WiFi.begin(ssid, password);                                              
        Serial.println("Reconnecting to WiFi..");       
        delay(10000);                                                             
      }
      timeClient.update();
      unsigned long epochTime = timeClient.getEpochTime();
  Serial.print("Epoch Time: ");
  Serial.println(epochTime);
  
  struct tm *ptm = gmtime ((time_t *)&epochTime); 
delay(1000);
  if(counter == 60)                                 //Get new data every 10 minutes
    {
      counter = 0;
      displayGettingData();
      delay(1000);
      getWeatherData();
    }else
    {
      counter++;
      displayWeather(weatherLocation,weatherDescription);
      delay(5000);
      displayConditions(Temperature,Humidity,Pressure);
      delay(5000);
    }
    
    
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Cases");
        lcd.setCursor(0,1);
        lcd.print(Cases);
        delay (10000);
    
    
        //change delay if you want
       
        lcd.clear();
        
        lcd.setCursor(0,0);
        lcd.print("Deaths");
        lcd.setCursor(0,1);
        lcd.print(Deaths);
        delay (10000);
     
          lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Recovered");
        lcd.setCursor(0,1);
        lcd.print(Recovered);
        delay (10000);
        
        lcd.clear();
        
        lcd.setCursor(0,0);
        lcd.print("Time is=");
        lcd.setCursor(0,1);
        lcd.print (timeClient.getHours());
        timeClient.update();
        lcd.setCursor(2,1);
        lcd.print(":");
         lcd.setCursor(3,1);
        lcd.print(timeClient.getMinutes());
         timeClient.update();
         lcd.setCursor(5,1);
        lcd.print(":");
         lcd.setCursor(6,1);
        lcd.print(timeClient.getSeconds());
         timeClient.update();
        
         
         delay (10000);
         lcd.clear();
         lcd.setCursor(0,0);
         lcd.print("Day is");
         lcd.setCursor(1,1);
         lcd.print(daysOfTheWeek[timeClient.getDay()]);
         delay (10000);
         lcd.clear();
         int monthDay = ptm->tm_mday;
  Serial.print("Month day: ");
  Serial.println(monthDay);
  int currentMonth = ptm->tm_mon+1;
  Serial.print("Month: ");
  Serial.println(currentMonth);
  String currentMonthName = months[currentMonth-1];
  Serial.print("Month name: ");
  Serial.println(currentMonthName);
  int currentYear = ptm->tm_year+1900;
  Serial.print("Year: ");
  Serial.println(currentYear);
         
         String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
         lcd.print("Current date: ");
         lcd.setCursor(1,1);
           lcd.print(currentDate);
           delay (10000);
           lcd.clear();
         lcd.setCursor(0,0);
        
       
         lcd.clear();
         lcd.print(inputMessage);
         
         delay(10000);
         lcd.clear();
         lcd.setCursor (0,0);
         lcd.print("Room Temperature");
         lcd.setCursor(0,1);
         lcd.print((float)DHT11.temperature, 2);
         lcd.setCursor(5,1);
         lcd.print("C");
         delay (10000);
         lcd.clear();
         lcd.setCursor (0,0);
         lcd.print("Room Humidity");
         lcd.setCursor(0,1);
         lcd.print((float)DHT11.humidity, 2);
         lcd.setCursor(5,1);
         lcd.print("%");
         delay (10000);
         lcd.clear();
}
      void getWeatherData()                                //client function to send/receive GET request data.
{
  if (client.connect(servername, 80))   
          {                                         //starts client connection, checks for connection
          client.println("GET /data/2.5/weather?id="+CityID+"&units=metric&APPID="+APIKEY);
          client.println("Host: api.openweathermap.org");
          client.println("User-Agent: ArduinoWiFi/1.1");
          client.println("Connection: close");
          client.println();
          } 
  else {
         Serial.println("connection failed");        //error message if no client connect
          Serial.println();
       }
  while(client.connected() && !client.available()) 
  delay(1);                                          //waits for data
  while (client.connected() || client.available())    
       {                                             //connected or data available
         char c = client.read();                     //gets byte from ethernet buffer
         result = result+c;
       }
client.stop();                                      //stop client
result.replace('[', ' ');
result.replace(']', ' ');
Serial.println(result);
char jsonArray [result.length()+1];
result.toCharArray(jsonArray,sizeof(jsonArray));
jsonArray[result.length() + 1] = '\0';
StaticJsonBuffer<1024> json_buf;
JsonObject &root = json_buf.parseObject(jsonArray);
if (!root.success())
  {
    Serial.println("parseObject() failed");
  }
String location = root["name"];
String country = root["sys"]["country"];
float temperature = root["main"]["temp"];
float humidity = root["main"]["humidity"];
String weather = root["weather"]["main"];
String description = root["weather"]["description"];
float pressure = root["main"]["pressure"];
weatherDescription = description;
weatherLocation = location;
Country = country;
Temperature = temperature;
Humidity = humidity;
Pressure = pressure;
//for taking the external weather conditions
}
void displayWeather(String location,String description)
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(location);
  lcd.print(", ");
  lcd.print(Country);
  lcd.setCursor(0,1);
  lcd.print(description);
}
void displayConditions(float Temperature,float Humidity, float Pressure)
{
 lcd.clear();                            //Printing Temperature
 lcd.print("T:"); 
 lcd.print(Temperature,1);
 lcd.print((char)223);
 lcd.print("C "); 
                                         
 lcd.print(" H:");                       //Printing Humidity
 lcd.print(Humidity,0);
 lcd.print(" %"); 
 
 lcd.setCursor(0,1);                     //Printing Pressure
 lcd.print("P: ");
 lcd.print(Pressure,1);
 lcd.print(" hPa");
}
void displayGettingData()
{
  lcd.clear();
  lcd.print("Getting data");
}
//thats all in the code
Comments