first commit

This commit is contained in:
Carsten Graf
2025-06-01 11:51:02 +02:00
commit 2d2ee0a41a
22 changed files with 3241 additions and 0 deletions

198
src/timesync.h Normal file
View File

@@ -0,0 +1,198 @@
// 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];
}