| @@ -30,6 +30,7 @@ | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/ArduinoJson/src}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/Adafruit_NeoPixel}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/NTPClient}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/arduino_time-master}""/> | |||
| </option> | |||
| <inputType id="io.sloeber.compiler.cpp.sketch.input.1770649762" name="CPP source files" superClass="io.sloeber.compiler.cpp.sketch.input"/> | |||
| </tool> | |||
| @@ -46,6 +47,7 @@ | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/ArduinoJson/src}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/Adafruit_NeoPixel}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/NTPClient}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/arduino_time-master}""/> | |||
| </option> | |||
| <inputType id="io.sloeber.compiler.c.sketch.input.1705705" name="C Source Files" superClass="io.sloeber.compiler.c.sketch.input"/> | |||
| </tool> | |||
| @@ -62,6 +64,7 @@ | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/ArduinoJson/src}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/Adafruit_NeoPixel}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/NTPClient}""/> | |||
| <listOptionValue builtIn="false" value=""${workspace_loc:/LEDLamp/libraries/arduino_time-master}""/> | |||
| </option> | |||
| <inputType id="io.sloeber.compiler.S.sketch.input.1190005390" name="Assembly source files" superClass="io.sloeber.compiler.S.sketch.input"/> | |||
| </tool> | |||
| @@ -102,7 +105,7 @@ | |||
| </toolChain> | |||
| </folderInfo> | |||
| <sourceEntries> | |||
| <entry excluding="libraries/WebSockets/travis|libraries/?*/**/?xamples/**|libraries/?*/**/?xtras/**|libraries/?*/**/test*/**|libraries/?*/**/third-party/**|libraries/**/._*|libraries/?*/utility/*/*" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> | |||
| <entry excluding="libraries/arduino_time-master/TimeAlarms|libraries/arduino_time-master/Time|libraries/arduino_time-master/DS1307RTC|libraries/WebSockets/travis|libraries/?*/**/?xamples/**|libraries/?*/**/?xtras/**|libraries/?*/**/test*/**|libraries/?*/**/third-party/**|libraries/**/._*|libraries/?*/utility/*/*" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> | |||
| </sourceEntries> | |||
| </configuration> | |||
| </storageModule> | |||
| @@ -86,5 +86,10 @@ | |||
| <type>2</type> | |||
| <locationURI>ECLIPSE_HOME/arduinoPlugin/libraries/WebSockets/2.7.2</locationURI> | |||
| </link> | |||
| <link> | |||
| <name>libraries/arduino_time-master</name> | |||
| <type>2</type> | |||
| <location>C:/Users/FSmilari/Documents/Arduino/libraries/arduino_time-master</location> | |||
| </link> | |||
| </linkedResources> | |||
| </projectDescription> | |||
| @@ -262,8 +262,11 @@ void handleSTAMode() { | |||
| WiFi.begin(configManager.getConfig().ssid, configManager.getConfig().pass); | |||
| connectStart = millis(); | |||
| setState(STATE_CONNECTING); | |||
| return; | |||
| } | |||
| //TODO: TimerManager::isNowInTimeInterval() | |||
| driveLEDStrip(); | |||
| } | |||
| @@ -86,6 +86,10 @@ void LEDStripManager::off() { | |||
| digitalWrite(LED_STRIP_DATA_PIN, LOW); | |||
| } | |||
| bool LEDStripManager::isOn() { | |||
| return digitalRead(LED_STRIP_POWER_PIN) == HIGH; | |||
| } | |||
| void LEDStripManager::setBrightness(uint8_t brightness) { | |||
| strip.setBrightness(brightness); | |||
| strip.show(); | |||
| @@ -111,7 +115,7 @@ void LEDStripManager::onModeChange(LEDModes mode) { | |||
| cfg.mode = mode; | |||
| configManager.saveConfig(cfg); | |||
| // Handle only single action modes here. For Animations use loop functions with nonblocking timers | |||
| // Handle only single action modes here. For Animations use loop functions with nonblocking timers | |||
| switch (mode) { | |||
| case LM_SINGLE_COLOR: | |||
| this->setBrightness(cfg.brightness); | |||
| @@ -299,7 +303,6 @@ void LEDStripManager::fade() { | |||
| static uint8_t currentColor = 0; | |||
| static uint32_t stateStart = millis(); | |||
| if (digitalRead(LED_STRIP_POWER_PIN) == HIGH) { | |||
| uint32_t holdTime = cfg.fadingHoldTime; | |||
| @@ -20,6 +20,7 @@ class LEDStripManager { | |||
| void show(); | |||
| void on(); | |||
| void off(); | |||
| bool isOn(); | |||
| void setBrightness(uint8_t brightness); | |||
| void setPixel(uint16_t index, uint8_t red, uint8_t green, uint8_t blue, uint8_t white); | |||
| void setAll(uint8_t red, uint8_t green, uint8_t blue, uint8_t white); | |||
| @@ -6,9 +6,18 @@ | |||
| */ | |||
| #include "TimerManager.h" | |||
| #include "ConfigManager.h" | |||
| TimerManager::TimerManager(ConfigManager &configManager) : configManager(configManager) { | |||
| WiFiUDP ntpUDP; | |||
| // Set up your base timezone offset in seconds (e.g., UTC+2 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", 3600) { | |||
| ntpClient.begin(); | |||
| } | |||
| TimerManager::~TimerManager() { | |||
| @@ -61,3 +70,62 @@ bool TimerManager::parseTimeInterval(const char *str, TimeInterval &interval) { | |||
| return true; | |||
| } | |||
| bool TimerManager::isNowInTimeInterval() { | |||
| Config cfg = configManager.getConfig(); | |||
| ntpClient.update(); | |||
| uint32_t epochTime = ntpClient.getEpochTime(); | |||
| time_t localTime = epochTime + gmtOffset_sec; | |||
| if (isDST(month(localTime), day(localTime), weekday(localTime))) { | |||
| localTime += daylightOffset_sec; | |||
| } | |||
| Serial.print("localTime: "); | |||
| Serial.println(secondsToFormatedTime(localTime)); | |||
| return (isInInterval(localTime, cfg.timeInterval1) || isInInterval(localTime, cfg.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; | |||
| uint8_t _seconds = 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); | |||
| } | |||
| @@ -9,6 +9,8 @@ | |||
| #define TIMERMANAGER_H_ | |||
| #include "ConfigManager.h" | |||
| #include "NTPClient.h" | |||
| #include <WiFiUdp.h> | |||
| class TimerManager { | |||
| @@ -18,15 +20,17 @@ class TimerManager { | |||
| void onTimerIntervalChange(String timerIntervalName, const char *timerInterval); | |||
| void saveTimerInterval(String timerIntervalName, uint32_t start, uint32_t end); | |||
| bool isNowInTimeInterval(); | |||
| private: | |||
| ConfigManager &configManager; | |||
| NTPClient ntpClient; | |||
| uint32_t timeToSeconds(uint8_t hour, uint8_t minute, uint8_t second); | |||
| bool parseTimeInterval(const char *str, TimeInterval &interval); | |||
| bool isDST(int month, int day, int weekday); | |||
| bool isInInterval(uint32_t now, const TimeInterval &interval); | |||
| String secondsToFormatedTime(uint32_t seconds); | |||
| }; | |||
| #endif /* TIMERMANAGER_H_ */ | |||
| @@ -2,7 +2,7 @@ | |||
| //This is a automatic generated file | |||
| //Please do not modify this file | |||
| //If you touch this file your change will be overwritten during the next build | |||
| //This file has been generated on 2026-07-12 21:54:14 | |||
| //This file has been generated on 2026-07-13 20:13:32 | |||
| #include "Arduino.h" | |||
| #include "Arduino.h" | |||