/*
  01.07.2025
  17_HTU_WebServer_WebSocket.ino

  HTU21 Sensor: Temperatur, Luftfeuchtigkeit
  NTP Datum und Uhrzeit aus dem Internet
  Built_In_LED an GPIO2 wird gesteuert
  Webserver mit WebSocket Protokoll
  Datenaustausch mit MQTT-Broker

  OLED-Anzeige und Ausgabe am seriellen Monitor
  WiFi-Manager mit MQTT-Verbindungsdaten Eingabe, und speichern in LittleFS

  https://randomnerdtutorials.com/esp8266-nodemcu-websocket-server-arduino/


*/
#include <ESPAsyncWebServer.h>
#include "myHTML.h"

#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 <Wire.h>
#include <Adafruit_HTU21DF.h>  // Sensor

//#include <ESP8266WiFi.h>
//#include <ESPAsyncTCP.h>


// Replace with your network credentials
//const char* ssid = "HSB-Gast";
//const char* password = "";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

//#define BUILTIN_LED 2  // GPIO2 for D1mini LED

Adafruit_HTU21DF htu = Adafruit_HTU21DF();

// Sensor Variablen
float temp = 0;
float rel_hum = 0;
bool ledState = 0;    // LED Pin Ausgabe 0 = aus; 1 ein

// set now millis
unsigned long lastOLED_Time = 0;
unsigned long lastNTP_Time = 0;

const int interval_OLED = 8000;  // 8 sek
const int interval_NTP = 1000;  // 1 sek

String anzeigeStatus = "Sensor";  // { Sensor; Zeit} zur Anzeige am OLED


void setup() {
  Serial.begin(115200);
  Serial.println("\n\nDatum und Uhrzeit aus dem Internet per NTP!");
  Serial.println("WiFi-Manager für IoT ohne WebServer. \nStart mit AP und 192.168.4.1 wenn kein WLAN verfügbar.");
  Serial.println("Wenn das verfügbare WLAN Probleme macht, dann mit der Taste an GPIO14 (D5) den WiFi-Manager erzwingen\n");

  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, HIGH);  // LED off

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

void loop() {
  // check MQTT Client
  /*if (!client.connected()) {  // MQTT client
    reconnect();
  }
  client.loop();           // MQTT Client loop
*/

  ws.cleanupClients();     // WebSocket

  digitalWrite(BUILTIN_LED, !ledState);

  //******  diese Schleife wird für die OLED-Anzeige durchlaufen
  //******  Anzeigestatus wird in bestimmten Zeitintervall umgestellt
  if ((millis() - lastOLED_Time) > interval_OLED) {
    if (anzeigeStatus == "Zeit") {
      anzeigeStatus = "Sensor";
      // Sensor auslesen
      float temp = htu.readTemperature();
      float 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");

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

  //******  diese Schleife wird für die Uhrzeit-Aktualisierung pro Sekunde durchlaufen
  //******  Anzeige von Datum und Uhrzeit jede Sekunde wenn anzeigeStatus == "Zeit"
  if ((millis() - lastNTP_Time) > interval_NTP) {
    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 line
      snprintf(line2, sizeof(line2), txtTime.c_str());  // Überschreibt line
      snprintf(line3, sizeof(line3), txtDay.c_str());   // Überschreibt line
      showTextOLED(lines, 3);                           // line1, line2, line3 werden angezeigt. line4, line5 werden ignoriert
    }
    lastNTP_Time = millis();
  }
}

