/* * TimerManager.cpp * * Created on: 12.07.2026 * Author: FSmilari */ #include "TimerManager.h" WiFiUDP ntpUDP; // Set up your base timezone offset in seconds (e.g., UTC+1 for Baar, Switzerland is 3600) const long gmtOffset_sec = 3600; // Set up DST offset in seconds (1 hour = 3600 seconds) const long daylightOffset_sec = 3600; TimerManager::TimerManager(ConfigManager &configManager) : configManager(configManager), ntpClient(ntpUDP, "pool.ntp.org", gmtOffset_sec) { } TimerManager::~TimerManager() { } void TimerManager::begin() { ntpClient.begin(); } void TimerManager::onTimerStatusChange(const char *timerStatus) { Config cfg = configManager.getConfig(); cfg.timer.on = String(timerStatus).equalsIgnoreCase("on"); configManager.saveConfig(cfg); } void TimerManager::onTimerIntervalChange(String timerIntervalName, const char *timerInterval) { TimeInterval interval; parseTimeInterval(timerInterval, interval); saveTimerInterval(timerIntervalName, interval.start, interval.end); } void TimerManager::saveTimerInterval(String timerIntervalName, uint32_t start, uint32_t end) { Config cfg = configManager.getConfig(); if (timerIntervalName.equals("timeInterval1")) { cfg.timer.timeInterval1.start = start; cfg.timer.timeInterval1.end = end; } else if (timerIntervalName.equals("timeInterval2")) { cfg.timer.timeInterval2.start = start; cfg.timer.timeInterval2.end = end; } configManager.saveConfig(cfg); } uint32_t TimerManager::timeToSeconds(uint8_t hour, uint8_t minute, uint8_t second) { return (uint32_t) hour * 3600UL + (uint32_t) minute * 60UL + second; } bool TimerManager::parseTimeInterval(const char *str, TimeInterval &interval) { unsigned int sh, sm, ss; unsigned int eh, em, es; if (sscanf(str, "%u:%u:%u - %u:%u:%u", &sh, &sm, &ss, &eh, &em, &es) != 6) { return false; } // Bereich prüfen if (sh > 23 || eh > 23 || sm > 59 || em > 59 || ss > 59 || es > 59) { return false; } interval.start = timeToSeconds(sh, sm, ss); interval.end = timeToSeconds(eh, em, es); return true; } bool TimerManager::isNowInTimeInterval() { Config cfg = configManager.getConfig(); ntpClient.update(); time_t localEpochTime = ntpClient.getEpochTime() + gmtOffset_sec; time_t localTime = ntpClient.getHours() * 3600 + ntpClient.getMinutes() * 60 + ntpClient.getSeconds(); bool isDst = isDST(month(localEpochTime), day(localEpochTime), weekday(localEpochTime)); if (isDst) { localTime += daylightOffset_sec; } Serial.print("isDST: "); Serial.println(isDst ? "true" : "false"); Serial.println(ntpClient.getFormattedTime()); Serial.print("localTime: "); Serial.println(secondsToFormatedTime(localTime)); return (isInInterval(localTime, cfg.timer.timeInterval1) || isInInterval(localTime, cfg.timer.timeInterval2)); } bool TimerManager::isDST(int month, int day, int weekday) { // DST is between last Sunday of March (month 3) and last Sunday of October (month 10) if (month > 3 && month < 10) return true; if (month == 3) { int lastSunday = 31 - (weekday - 1); // math to find the last Sunday if (day >= lastSunday) return true; } if (month == 10) { int lastSunday = 31 - (weekday - 1); if (day < lastSunday) return true; } return false; } bool TimerManager::isInInterval(uint32_t now, const TimeInterval &interval) { if (interval.start <= interval.end) { // normales Intervall return now >= interval.start && now < interval.end; } // Intervall geht über Mitternacht return now >= interval.start || now < interval.end; } String TimerManager::secondsToFormatedTime(uint32_t seconds) { uint8_t hour = seconds / 3600; seconds %= 3600; uint8_t minute = seconds / 60; uint8_t second = seconds % 60; char buffer[9]; // "HH:mm:ss" + '\0' snprintf(buffer, sizeof(buffer), "%02u:%02u:%02u", hour, minute, second); return String(buffer); }