// Zeit-bezogene Variablen und Includes #pragma once #include #include #include #include #include // Globale Zeitvariablen struct timeval tv; struct timezone tz; time_t now; struct tm timeinfo; void setupTimeAPI(AsyncWebServer& server); String getCurrentTimeJSON(); bool setSystemTime(long timestamp); // Hilfsfunktionen für Zeit-Management String getCurrentTimeJSON() { gettimeofday(&tv, &tz); now = tv.tv_sec; StaticJsonDocument<200> doc; doc["timestamp"] = (long)now; doc["success"] = true; // Zusätzliche Zeitinformationen gmtime_r(&now, &timeinfo); char timeStr[64]; strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &timeinfo); doc["formatted"] = String(timeStr); doc["year"] = timeinfo.tm_year + 1900; doc["month"] = timeinfo.tm_mon + 1; doc["day"] = timeinfo.tm_mday; doc["hour"] = timeinfo.tm_hour; doc["minute"] = timeinfo.tm_min; doc["second"] = timeinfo.tm_sec; String response; serializeJson(doc, response); return response; } bool setSystemTime(long timestamp) { struct timeval tv; tv.tv_sec = timestamp; tv.tv_usec = 0; if (settimeofday(&tv, NULL) == 0) { Serial.println("Zeit erfolgreich gesetzt: " + String(timestamp)); return true; } else { Serial.println("Fehler beim Setzen der Zeit"); return false; } } void setupTimeAPI(AsyncWebServer& server) { // API-Endpunkt: Aktuelle Zeit abrufen server.on("/api/time", HTTP_GET, [](AsyncWebServerRequest *request){ String response = getCurrentTimeJSON(); request->send(200, "application/json", response); }); // API-Endpunkt: Zeit setzen server.on("/api/set-time", HTTP_POST, [](AsyncWebServerRequest *request){ StaticJsonDocument<100> doc; if (request->hasParam("timestamp", true)) { String timestampStr = request->getParam("timestamp", true)->value(); long timestamp = timestampStr.toInt(); if (timestamp > 0) { bool success = setSystemTime(timestamp); doc["success"] = success; if (success) { doc["message"] = "Zeit erfolgreich gesetzt"; doc["timestamp"] = timestamp; } else { doc["message"] = "Fehler beim Setzen der Zeit"; } } else { doc["success"] = false; doc["message"] = "Ungültiger Timestamp"; } } else { doc["success"] = false; doc["message"] = "Timestamp-Parameter fehlt"; } String response; serializeJson(doc, response); request->send(200, "application/json", response); }); // Alternative Implementierung für manuelle Datum/Zeit-Eingabe server.on("/api/set-datetime", HTTP_POST, [](AsyncWebServerRequest *request){ StaticJsonDocument<150> doc; if (request->hasParam("year", true) && request->hasParam("month", true) && request->hasParam("day", true) && request->hasParam("hour", true) && request->hasParam("minute", true) && request->hasParam("second", true)) { struct tm timeinfo; timeinfo.tm_year = request->getParam("year", true)->value().toInt() - 1900; timeinfo.tm_mon = request->getParam("month", true)->value().toInt() - 1; timeinfo.tm_mday = request->getParam("day", true)->value().toInt(); timeinfo.tm_hour = request->getParam("hour", true)->value().toInt(); timeinfo.tm_min = request->getParam("minute", true)->value().toInt(); timeinfo.tm_sec = request->getParam("second", true)->value().toInt(); time_t timestamp = mktime(&timeinfo); if (timestamp != -1) { bool success = setSystemTime(timestamp); doc["success"] = success; if (success) { doc["message"] = "Zeit erfolgreich gesetzt"; doc["timestamp"] = (long)timestamp; } else { doc["message"] = "Fehler beim Setzen der Zeit"; } } else { doc["success"] = false; doc["message"] = "Ungültiges Datum/Zeit"; } } else { doc["success"] = false; doc["message"] = "Datum/Zeit-Parameter fehlen"; } String response; serializeJson(doc, response); request->send(200, "application/json", response); }); // Erweiterte Zeit-Informationen (optional) server.on("/api/time/info", HTTP_GET, [](AsyncWebServerRequest *request){ gettimeofday(&tv, &tz); now = tv.tv_sec; gmtime_r(&now, &timeinfo); StaticJsonDocument<400> doc; doc["timestamp"] = (long)now; doc["uptime"] = millis(); // Formatierte Zeitstrings char buffer[64]; strftime(buffer, sizeof(buffer), "%Y-%m-%d", &timeinfo); doc["date"] = String(buffer); strftime(buffer, sizeof(buffer), "%H:%M:%S", &timeinfo); doc["time"] = String(buffer); strftime(buffer, sizeof(buffer), "%A", &timeinfo); doc["weekday"] = String(buffer); strftime(buffer, sizeof(buffer), "%B", &timeinfo); doc["month_name"] = String(buffer); // Zusätzliche Infos doc["day_of_year"] = timeinfo.tm_yday + 1; doc["week_of_year"] = (timeinfo.tm_yday + 7 - timeinfo.tm_wday) / 7; doc["is_dst"] = timeinfo.tm_isdst; String response; serializeJson(doc, response); request->send(200, "application/json", response); }); Serial.println("Zeit-API initialisiert"); } // Hilfsfunktion: Zeit-Validierung bool isValidDateTime(int year, int month, int day, int hour, int minute, int second) { if (year < 2020 || year > 2099) return false; if (month < 1 || month > 12) return false; if (day < 1 || day > 31) return false; if (hour < 0 || hour > 23) return false; if (minute < 0 || minute > 59) return false; if (second < 0 || second > 59) return false; // Erweiterte Validierung für Monatstage int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // Schaltjahr-Prüfung if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) { daysInMonth[1] = 29; } return day <= daysInMonth[month - 1]; } uint64_t getCurrentTimestampMs() { struct timeval tv; gettimeofday(&tv, NULL); return (uint64_t)tv.tv_sec * 1000LL + (uint64_t)tv.tv_usec / 1000LL; }