/*
 * Modder:  @red9030
 * Title:   NTP+RTC+ESP32 Clock + LCD1602 I²C Arduino version.
 * Reference: https://github.com/PaulStoffregen/Time/blob/master/examples/TimeRTC/
 *           
 *  _   _     _   _ 
 * |_| |_| . |_| |_|
 * |_| |_| . |_| |_|
 * 
 * This example code is in the public domain
 */

/*
 * FILAS    ----
 * COLUMNAS ||||
*/

/*
 *****************************************************
 *    LIBRERIAS
 *****************************************************
*/
#include <Wire.h>        //Librería para conexión I2C

#include <TimeLib.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
#include <LiquidCrystal_I2C.h>

#include <WiFi.h>               //Librería para conexión wifi                
#include <ESP32Time.h>          //Librería para uso del RTC interno ESP32

/*
 *****************************************************
 *    VARIABLES
 *****************************************************
*/

#define I2C_address 0x27    // 0x27 , 0x3F , 0x20 , 0x38
const int lcdFilas = 2;     //FIlas del LCD
const int lcdColumnas = 16; //Columnas del LCD

LiquidCrystal_I2C LCD(I2C_address, lcdColumnas, lcdFilas);  // I2C address 0x27 (from DIYables LCD), 16 column and 2 rows

//Variables de tiempo RTC del esp32
ESP32Time rtc;  
struct tm timeinfo;
//Variables para conexión del servidor.
#define NTP_SERVER "pool.ntp.org"       //Servidor ntp para obtención de datos pool.ntp.org // ec.pool.ntp.org
#define UTC_OFFSET -18000               //UTC PAIS  x  3600seconds = hora del paìs buscado
#define UTC_OFFSET_DST 0

/*
 *****************************************************
 *    INICIO
 *****************************************************
*/
void setup() {
  Serial.begin(115200);
  while (!Serial) ; // wait until Arduino Serial Monitor opens
	setTime(19,15,50,30,12,2020);  //hr,min,sec,day,month,yr
	RTC.set(now());
 
  //LCD.begin(lcdColumnas,lcdFilas);     // initialize the lcd serial                 
  LCD.init();       // initialize the lcd i2c
  LCD.backlight();  // set up the LCD's 
  
  mensajesLCD(0);         //Mensaje en pantalla LCD: estableciendo conexión wifi
  WiFi.begin("Wokwi-GUEST", "", 6);
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    spinner();
  }
  mensajesLCD(1);             //Mensaje en pantalla LCD: Conexión wifi exitosa
  configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER); //Configuracion del time
}

/*
 *****************************************************
 *    REPETICIÓN
 *****************************************************
*/
void loop() {
 if (timeStatus() == timeSet) {
    printLocalTime();
    digitalClockDisplay();
  } else {
    Serial.println("The time has not been set.  Please run the Time");
    Serial.println("TimeRTCSet example, or DS1307RTC SetTime example.");
    Serial.println();
    delay(4000);
  }
  delay(1000);
}
/*
 *****************************************************
 *    FUNCIONES
 *****************************************************
*/

//Función que crea un emoticón de conexión.
void spinner() {                
  static int8_t counter = 0;
  const char* glyphs = "\xa1\xa5\xdb";
  LCD.setCursor(15, 1);
  LCD.print(glyphs[counter++]);
  if (counter == strlen(glyphs)) {
    counter = 0;
  }
}

//Obtiene la fecha y hora desde el servidor NTP
void printLocalTime() {   
  if (!getLocalTime(&timeinfo)) {
    rtc.setTimeStruct(timeinfo);
    LCD.setCursor(0, 1);
    LCD.println("Connection Err");
    Serial.println(getLocalTime(&timeinfo));
    return;
  }

}

//Imprime La fecha y hora desde el RTC  DS1307 a consola y a LCD
void digitalClockDisplay(){
  int hora=rtc.getHour(true);
  //hora=hour();
  int minuto=rtc.getMinute();
  //minuto=minute();
  int segundo=rtc.getSecond();
  //segundo=second();
  int dia=rtc.getDay();
  //dia=day();
  int mes=rtc.getMonth();
  //mes=month();
  int anio=rtc.getYear();
  //anio=year();
  int diasemana=rtc.getDayofWeek();

  //RTC.setTime(segundo,minuto,hora,dia,mes,anio);
  //RTC.set(segundo,minuto,hora,diasemana,dia,mes,anio);

  // digital clock display of the time on console
  Serial.print(hora);
  printDigits(minuto);
  printDigits(segundo);
  Serial.print(" ");
  Serial.print(dia);
  Serial.print(" ");
  Serial.print(mes+1);
  Serial.print(" ");
  Serial.print(anio);
  Serial.print(" eppoch: ");
  Serial.print(now());
 // Serial.print(" ");
 // Serial.print(typeid(timeinfo).name());
  Serial.println();

  // display the clock on LCD
  LCD.setCursor(0, 0);
  LCD.println("Fecha: ");
  LCD.setCursor(7, 0);
  LCD.print(dia);
  LCD.print('/');
  LCD.print(mes+1);
  LCD.print('/');
  LCD.print(anio);
  LCD.setCursor(0, 1);
  LCD.println("Hora: ");
  LCD.setCursor(6, 1);
  LCD.print(hora);
  LCD.print(':');
  LCD.print(minuto);
  LCD.print(':');
  LCD.print(segundo);
  
}

// Función de utilidad para la visualización del reloj digital: imprime antes de los dos puntos y el 0 inicial
void printDigits(int digits){
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

//Imprime mensajes de inicio en pantalla LCD
void mensajesLCD(int opc) {     
  switch(opc){
        case 0:              //Mensaje 1 (estableciendo conexión wifi)
                LCD.setCursor(0, 0);
                LCD.print("Connecting to ");
                LCD.setCursor(0, 1);
                LCD.print("WiFi ");
        break;
        case 1:             //Mensaje 2
                LCD.clear();
                LCD.setCursor(0, 0);
                LCD.println("Online");
                LCD.setCursor(0, 1);
                LCD.println("Updating time...");
        break;
        case 2:              //Mensaje 3
//mensajesLCD(2); //Mensaje en pantalla LCD: Hora y fecha

        break;
  }
}
GND5VSDASCLSQWRTCDS1307+