Fixed OTA problems, Clock Alerts and MQTT Logs. V151

This commit is contained in:
2026-01-19 19:02:25 +02:00
parent 7e279c6e45
commit 11b98166d1
10 changed files with 200 additions and 44 deletions

View File

@@ -2,6 +2,7 @@
#include "../OutputManager/OutputManager.hpp"
#include "../ConfigManager/ConfigManager.hpp"
#include "../Networking/Networking.hpp"
#include "../Player/Player.hpp" // 🔥 Include for Player class definition
#include "SD.h"
#include <time.h>
@@ -47,6 +48,19 @@ void Timekeeper::setNetworking(Networking* networking) {
LOG_INFO("Timekeeper connected to Networking");
}
void Timekeeper::setPlayer(Player* player) {
_player = player;
LOG_INFO("Timekeeper connected to Player for playback coordination");
}
void Timekeeper::interruptActiveAlert() {
if (alertInProgress.load()) {
LOG_INFO("⚡ ALERT INTERRUPTED by user playback - marking as complete");
alertInProgress.store(false);
// Alert will stop naturally on next check in fireAlertBell loop
}
}
void Timekeeper::setRelayWriteFunction(void (*func)(int, int)) {
relayWriteFunc = func;
LOG_WARNING("Using LEGACY relay function - consider upgrading to OutputManager");
@@ -532,26 +546,46 @@ void Timekeeper::checkClockAlerts() {
if (!_configManager || !_configManager->getClockEnabled()) {
return; // Clock is disabled - skip all alert functionality
}
// Check if we have required dependencies
if (!_outputManager || !rtc.isrunning()) {
return;
}
// 🔥 CRITICAL: Check if Player is busy - if so, SKIP alert completely
if (_player && _player->isPlaying) {
// Player is active (playing, paused, stopping, etc.) - skip alert entirely
// Mark this alert as processed to prevent it from firing when playback ends
DateTime now = rtc.now();
int currentMinute = now.minute();
if (currentMinute == 0) {
lastHour = now.hour(); // Mark hour as processed
} else if (currentMinute == 30) {
lastMinute = 30; // Mark half-hour as processed
} else if (currentMinute == 15 || currentMinute == 45) {
lastMinute = currentMinute; // Mark quarter-hour as processed
}
LOG_DEBUG("⏭️ SKIPPING clock alert - Player is busy (playing/paused)");
return;
}
// Get current time
DateTime now = rtc.now();
int currentHour = now.hour();
int currentMinute = now.minute();
int currentSecond = now.second();
// Only trigger alerts on exact seconds (0-2) to avoid multiple triggers
if (currentSecond > 2) {
// Only trigger alerts in first 30 seconds of the minute
// The lastHour/lastMinute tracking prevents duplicate triggers
if (currentSecond > 30) {
return;
}
// Get clock configuration
const auto& clockConfig = _configManager->getClockConfig();
// Check if alerts are disabled
if (clockConfig.alertType == "OFF") {
return;
@@ -624,22 +658,34 @@ void Timekeeper::fireAlertBell(uint8_t bellNumber, int count) {
}
const auto& clockConfig = _configManager->getClockConfig();
// Mark alert as in progress
alertInProgress.store(true);
for (int i = 0; i < count; i++) {
// 🔥 Check for interruption by user playback
if (!alertInProgress.load()) {
LOG_INFO("⚡ Alert interrupted at ring %d/%d - stopping immediately", i + 1, count);
return;
}
// Get bell duration from bell configuration
uint16_t bellDuration = _configManager->getBellDuration(bellNumber);
LOG_DEBUG("🔔 Alert bell #%d ring %d/%d (duration: %dms)",
LOG_DEBUG("🔔 Alert bell #%d ring %d/%d (duration: %dms)",
bellNumber + 1, i + 1, count, bellDuration);
// Fire the bell using OutputManager
_outputManager->fireOutputForDuration(bellNumber, bellDuration);
// Wait between rings (only if there's more than one ring)
if (i < count - 1) {
vTaskDelay(pdMS_TO_TICKS(clockConfig.alertRingInterval));
}
}
// Mark alert as complete
alertInProgress.store(false);
}
void Timekeeper::checkBacklightAutomation() {
@@ -688,7 +734,7 @@ bool Timekeeper::isInSilencePeriod() {
}
const auto& clockConfig = _configManager->getClockConfig();
// Get current time
DateTime now = rtc.now();
char currentTimeStr[6];
@@ -697,14 +743,22 @@ bool Timekeeper::isInSilencePeriod() {
// Check daytime silence period
if (clockConfig.daytimeSilenceEnabled) {
if (isTimeInRange(currentTime, clockConfig.daytimeSilenceOnTime, clockConfig.daytimeSilenceOffTime)) {
bool inDaytime = isTimeInRange(currentTime, clockConfig.daytimeSilenceOnTime, clockConfig.daytimeSilenceOffTime);
LOG_DEBUG("🔇 Daytime silence check: current=%s, range=%s-%s, inRange=%s",
currentTime.c_str(), clockConfig.daytimeSilenceOnTime.c_str(),
clockConfig.daytimeSilenceOffTime.c_str(), inDaytime ? "YES" : "NO");
if (inDaytime) {
return true;
}
}
// Check nighttime silence period
if (clockConfig.nighttimeSilenceEnabled) {
if (isTimeInRange(currentTime, clockConfig.nighttimeSilenceOnTime, clockConfig.nighttimeSilenceOffTime)) {
bool inNighttime = isTimeInRange(currentTime, clockConfig.nighttimeSilenceOnTime, clockConfig.nighttimeSilenceOffTime);
LOG_DEBUG("🌙 Nighttime silence check: current=%s, range=%s-%s, inRange=%s",
currentTime.c_str(), clockConfig.nighttimeSilenceOnTime.c_str(),
clockConfig.nighttimeSilenceOffTime.c_str(), inNighttime ? "YES" : "NO");
if (inNighttime) {
return true;
}
}