205 lines
5.9 KiB
C
205 lines
5.9 KiB
C
// Zeit-bezogene Variablen und Includes
|
|
#pragma once
|
|
#include <Arduino.h>
|
|
#include <ESPAsyncWebServer.h>
|
|
#include <ArduinoJson.h>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
|
|
// 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;
|
|
}
|