/*  funktioniert nicht
	01.07.2025
	16_HTU_OLED_NTP_WiFi-Manager2_WebServer.ino	
	ESP8266-WiFi-Manager mit MQTT und Webserver
	
	WiFi Manager für IoT mit myWiFi_Manager.h mit zusätzlichen MQTT Parametern in LittleFS gespeichert
	Die eingegebenen Verbindungsdaten werden im nichtflüchtigen Speicher des ESP gespeichert (LittleFS)
	***** ACHTUNG ******  LittleFS.format(); beim ersten Mal aufrufen. (Siehe im void startWiFi_Manager() )
	Es folgt Prüfung ob MQTT Verbindungseinstellung ok ist. 

	
	Mit OLED und Lib: u8g2.h   (•	myOLED_u8g2.h und myLogo_u8g2.h)
	BuiltIn-LED  
	Taster D5 (GPIO_14) bei WiFi-Setup (nach RESET) abgefragt
      Es wird der LittleFS-Speicher gelöscht und der Wifi_Manager Start erzwungen.
  
	Access Point: 192.168.4.1 lebt nur 5 Min.
	siehe auch RandomNerdTutorial WiFi-Manager
	
*/


#include "myOLED_u8g2.h"      // Auslagerung der OLED Funktionen
#include "myWiFi_Manager.h"   // WiFi-Manager mit MQTT-Erweiterung
#include "myNTP_Time.h"       // für NTP Internet Zeit-Datum
#include <ESPAsyncWebServer.h>

#include <Wire.h>   // für i2c
#include <Adafruit_HTU21DF.h>

#define ledPin  2   // // GPIO2 (NodeMCU) Built_In_LED – Anpassen für ESP32!

// AsyncWebServer
AsyncWebServer   server(80);

Adafruit_HTU21DF  htu = Adafruit_HTU21DF();     // Sensor Objekt erzeugen

//const long timeout = 15000;  // 15 Sekunden Timeout für Verbindungen
unsigned long startReconnect = 0;
const int intervalMQTT_Test = 60000;  // 1 min

unsigned long startPart1 = 0;
const int intervalPart1 = 10000;  // 10 sec

unsigned long lastOLEDTimer = 0;
const int delayOLED = 8000;  // 8 sek

unsigned long lastTimeTimer = 0;
const int delayTime = 1000;  // 1 sek

String anzeigeStatus = "Sensor";  // { Sensor Zeit}

// HTU21 Sensor Variablen
float temp = 0;
float rel_hum = 0;
bool ledState = false;

#include "myHTML.h"       // Auslagerung der Webserver WebPage 
#include "myWebServer.h"  // Auslagerung der Webserver Funktionen

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.println("\n\nDer HTU21 Sensor mit OLED-Ausgabe und NTP Uhrzeit aus dem Internet.");
  Serial.println("WiFi Manager für IoT ohne WebServer. \nStart mit AP und 192.168.4.1 wenn kein WLAN verfügbar.");
  Serial.println("Mit Erweiterung für MQTT Einstellungen");
  Serial.println("Wenn das verfügbare WLAN Probleme macht, dann mit der Taste an D5 (GPIO_14) den WiFi-Manager erzwingen\n");

  if (!htu.begin()) {         // Sensor start
    Serial.println("Couldn't find sensor!");
  }

  temp = htu.readTemperature();
  rel_hum = htu.readHumidity();

  initOLED();  // siehe myOLED.h
  showLogo();
  delay(displayDelay);

  showStartText();
  delay(displayDelay);
  delay(displayDelay);

  snprintf(line1, sizeof(line1), "Start WiFi-Manager");        // Überschreibt line1 , Zeichenlänge 30 wird geprüft
  snprintf(line2, sizeof(line2), "Press Button for new");      //
  snprintf(line3, sizeof(line3), "WiFi + MQTT Setting");       //
  snprintf(line4, sizeof(line4), "            ********    ");  //
  snprintf(line5, sizeof(line5), "            ********    ");  //
  showTextOLED(lines, 5);                                      // siehe "myOLED_u8g2.h"

  startWiFi_Manager();  // siehe  "myWiFi_Manager.h"

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

  delay(displayDelay);    // wegen OLED
  Serial.println("\nStart Loop.\n");

  startWebServer();   // siehe myWebServer.h

}


void loop() {
  // MQTT Verbindung in bestimmten Intervallen prüfen und wiederherstellen, wenn nötig.  kein delay() verwenden
  if (millis() > startReconnect + intervalMQTT_Test) {
    // Teste zuerst die WLAN Netzwerkverbindung
    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("Keine WiFi-Verbindung!");
      WiFi.reconnect();
    } else {
      publishMessage(mqtt_DeviceSSID_Topic, WiFi.SSID().c_str(), retain);                    // MQTT Daten Ausgabe
      publishMessage(mqtt_DeviceIP_Topic, WiFi.localIP().toString().c_str(), retain);       // MQTT Daten Ausgabe            
    }

    // Teste die MQTT Verbindung
    if (!mqttClient.connected()) {
      reconnectMQTT();  // siehe myWiFi_Manager
    } else {
      snprintf(line4, sizeof(line4), "%s", config.mqtt_server);  // MQTT-Server-Adresse
      snprintf(line5, sizeof(line5), "MQTT: %s", brokerIP.toString().c_str());  // IP Adresse vom Broker
      showTextOLED(lines, 5);  // siehe "myOLED_u8g2.h"
    }

    startReconnect = millis();
  }

  mqttClient.loop();

  //******  diese Schleife wird für die OLED-Anzeige durchlaufen,  der Anzeigestatus wird in bestimmten Zeitintervall umgestellt
  if ((millis() - lastOLEDTimer) > delayOLED) {
    if (anzeigeStatus == "Zeit") {
      anzeigeStatus = "Sensor";
      // Sensor auslesen
      temp = htu.readTemperature();
      rel_hum = htu.readHumidity();

      showSensor("HTU21-Sens", temp, rel_hum);  // siehe myOLED.h

      Serial.print("\nTemp: ");    Serial.print(temp);      Serial.print(" °C\t\t");
      Serial.print("Humidity: ");  Serial.print(rel_hum);   Serial.println(" %\n");


      publishMessage(mqtt_TimeStamp_Topic, printTimeStamp().c_str(), retain);     // Zeitstempel aus myNTP_Time.h
      publishMessage(mqtt_DHT_Temp_Topic, String(temp, 1).c_str(), retain);       // MQTT Daten Ausgabe
      publishMessage(mqtt_DHT_Luft_Topic, String(rel_hum, 0).c_str(), retain);

    } else if (anzeigeStatus == "Sensor") {
      anzeigeStatus = "Zeit";
    }
    lastOLEDTimer = millis();
  }

  //******  diese Schleife wird für die Uhrzeit-Aktualisierung pro Sekunde durchlaufen
  //******  Anzeige von Datum und Uhrzeit jede Sekunde wenn anzeigeStatus == "Zeit"
  if ((millis() - lastTimeTimer) > delayTime) {
    if (anzeigeStatus == "Zeit") {
      //showTime();   // Anzeige Datum Uhrzeit

      time(&now);                      // read the current time
      localtime_r(&now, &tm);          // update the structure tm with the current time
      String txtDate = printDateDE();  // siehe myNTP_Time.h
      Serial.print("\t");
      String txtTime = printTime();  // siehe myNTP_Time.h
      Serial.println("\t" + weekDays[tm.tm_wday]);

      txtDate = "  " + txtDate;
      txtTime = "    " + txtTime;
      String txtDay = weekDays[tm.tm_wday];

      snprintf(line1, sizeof(line1), txtDate.c_str());  // Überschreibt line1 mit "Hallo", Zeichenlänge wird geprüft
      snprintf(line2, sizeof(line2), txtTime.c_str());  // Überschreibt line1 mit "Hallo", Zeichenlänge wird geprüft
      snprintf(line3, sizeof(line3), txtDay.c_str());   // Überschreibt line1 mit "Hallo", Zeichenlänge wird geprüft
      showTextOLED(lines, 3);                           // line1, line2, line3 werden angezeigt. line4, line5 werden ignoriert
    }
    lastTimeTimer = millis();
  }  

  if (millis() > startPart1 + intervalPart1) {
    // YOUR CODE
    Serial.println("RUN YOUR CODE");
    startPart1 = millis();
  }

}


//
