/*
  Juni 2025
  Detum und Uhrzeit aus dem Internet mit NTP
  für ESP8266 (und ESP32) mit WLAN

  Sommer- und Winterzeit werden automatisch umgestellt
  https://werner.rothschopf.net/201802_arduino_esp8266_ntp.htm
  
*/

//#include <WiFi.h>          // Für ESP32
#include <ESP8266WiFi.h>    // Für ESP8266 (statt WiFi.h)
#include <time.h>         // ESP32/ESP8266 Systemzeit (time.h)

const char* ssid      = "HSB-Gast";
const char* password  = "";

/* Configuration of NTP */
#define MY_NTP_SERVER "at.pool.ntp.org"           // ntp Server
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"   // Zeitzonen Einstellung mit Sommer-Winterzeit

/* Globals */
time_t    now;              // this are the seconds since Epoch (1970) - UTC
tm        tm;               // the structure tm holds time information in a more convenient way

extern "C" uint8_t sntp_getreachability(uint8_t);   // für die Funktion getNtpServer

#define BUILT_IN_LED  2   // GPIO 2

// ------------------   NTP holen  ------------------------------
bool getNtpServer(bool reply = false) {
  uint32_t timeout {millis()};

  configTime(MY_TZ, MY_NTP_SERVER);   // Zeitzone einstellen https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv

  do {
    delay(25);
    if (millis() - timeout >= 1e3) {
      Serial.printf("Warten auf NTP-Antwort %02ld sec\n", (millis() - timeout) / 1000);
      delay(975);
    }
    sntp_getreachability(0) ? reply = true : 	// // Prüft ob einer der drei Server (0,1,2) erreichbar ist, wenn nicht false
	sntp_getreachability(1) ? reply = true : 
	sntp_getreachability(2) ? reply = true : false;
  } while (millis() - timeout <= 16e3 && !reply);
  return reply;
}


// ------------------  setup()  ------------------------------
void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.println("\n\nDatum und Uhrzeit aus dem Internet per NTP!\n\n");

  WiFi.begin(ssid, password);   // WLAN start

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

  Serial.println("\nVerbunden mit WLAN!");
  digitalWrite(BUILT_IN_LED, HIGH);

  Serial.print("\nWiFi connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("MAC address:  ");
  Serial.println(WiFi.macAddress());

   //The ESP8266 tries to reconnect automatically when the connection is lost
  WiFi.setAutoReconnect(true);
  WiFi.persistent(true);

  // Initialize a NTPClient to get time
  bool timeSync = getNtpServer();     // siehe oben
  Serial.printf("NTP Synchronisation %s!\n\n", timeSync ? "erfolgreich" : "fehlgeschlagen");

}


// ------------------  Anzeige von Datum und Uhrzeit ------------------
void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &tm);           // update the structure tm with the current time
  Serial.print("year:");
  Serial.print(tm.tm_year + 1900);  // years since 1900
  Serial.print("\tmonth:");
  Serial.print(tm.tm_mon + 1);      // January = 0 (!)
  Serial.print("\tday:");
  Serial.print(tm.tm_mday);         // day of month
  Serial.print("\thour:");
  Serial.print(tm.tm_hour);         // hours since midnight  0-23
  Serial.print("\tmin:");
  Serial.print(tm.tm_min);          // minutes after the hour  0-59
  Serial.print("\tsec:");
  Serial.print(tm.tm_sec);          // seconds after the minute  0-61*
  Serial.print("\twday");
  Serial.print(tm.tm_wday);         // days since Sunday 0-6
  if (tm.tm_isdst == 1)             // Daylight Saving Time flag
    Serial.print("\tDST");
  else
    Serial.print("\tstandard");
  Serial.println();

  //Serial.println("Datum:\t" + String(tm.tm_year +1900) +"."+ String(tm.tm_mon + 1) +"."+ String(tm.tm_mday) + "\t" + weekDays[tm.tm_wday]);
  //Serial.println("Uhrzeit:\t" + String(tm.tm_hour) +":"+ String(tm.tm_min) +":"+ String(tm.tm_sec));
  //Serial.println();
}


// ------------------  loop()  ------------------
void loop() {
  
  time(&now);                       // read the current time
  localtime_r(&now, &tm);           // update the structure tm with the current time

  showTime();     // Anzeige Datum Uhrzeit

  delay(1000);  // 1 Sekunde warten

}
