mirror of
https://github.com/mfactory-osaka/ESPTimeCast.git
synced 2026-02-19 11:54:56 -05:00
Added Home Assistant brightness endpoint and support static display for short messages (≤8 chars).
This commit is contained in:
@@ -3494,160 +3494,160 @@ void loop() {
|
||||
}
|
||||
|
||||
|
||||
// --- Custom Message Display Mode (displayMode == 6) ---
|
||||
if (displayMode == 6) {
|
||||
|
||||
// 1. Initial Check: If message is empty, skip mode 6.
|
||||
if (strlen(customMessage) == 0) {
|
||||
advanceDisplayMode();
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
// --- Custom Message Display Mode (displayMode == 6) ---
|
||||
if (displayMode == 6) {
|
||||
|
||||
// --- CHARACTER REPLACEMENT AND PADDING (Common to both short and long) ---
|
||||
const size_t MAX_NON_SCROLLING_CHARS = 8;
|
||||
String msg = String(customMessage);
|
||||
|
||||
// Replace standard digits 0–9 with your custom font character codes
|
||||
for (int i = 0; i < msg.length(); i++) {
|
||||
if (isDigit(msg[i])) {
|
||||
int num = msg[i] - '0';
|
||||
msg[i] = 145 + ((num + 9) % 10);
|
||||
// 1. Initial Check: If message is empty, skip mode 6.
|
||||
if (strlen(customMessage) == 0) {
|
||||
advanceDisplayMode();
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// --- CHECK FOR TIMEOUT (Applies to temporary short & long messages) ---
|
||||
bool timedOut = false;
|
||||
// Check if a time limit (messageDisplaySeconds > 0) has been exceeded
|
||||
if (messageDisplaySeconds > 0 && (millis() - messageStartTime) >= (messageDisplaySeconds * 1000UL)) {
|
||||
Serial.printf("[MESSAGE] HA message timed out after %d seconds.\n", messageDisplaySeconds);
|
||||
timedOut = true;
|
||||
}
|
||||
// --- CHARACTER REPLACEMENT AND PADDING (Common to both short and long) ---
|
||||
const size_t MAX_NON_SCROLLING_CHARS = 8;
|
||||
String msg = String(customMessage);
|
||||
|
||||
// --- CHECK FOR SCROLL/CYCLE LIMIT BEFORE DISPLAYING ---
|
||||
// Scrolls complete applies to long messages.
|
||||
bool scrollsComplete = (messageScrollTimes > 0) && (currentScrollCount >= messageScrollTimes);
|
||||
// Replace standard digits 0–9 with your custom font character codes
|
||||
for (int i = 0; i < msg.length(); i++) {
|
||||
if (isDigit(msg[i])) {
|
||||
int num = msg[i] - '0';
|
||||
msg[i] = 145 + ((num + 9) % 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Cycles complete applies to short messages.
|
||||
extern int currentDisplayCycleCount; // Use the dedicated short message counter
|
||||
bool cyclesComplete = (messageScrollTimes > 0) && (currentDisplayCycleCount >= messageScrollTimes);
|
||||
// --- CHECK FOR TIMEOUT (Applies to temporary short & long messages) ---
|
||||
bool timedOut = false;
|
||||
// Check if a time limit (messageDisplaySeconds > 0) has been exceeded
|
||||
if (messageDisplaySeconds > 0 && (millis() - messageStartTime) >= (messageDisplaySeconds * 1000UL)) {
|
||||
Serial.printf("[MESSAGE] HA message timed out after %d seconds.\n", messageDisplaySeconds);
|
||||
timedOut = true;
|
||||
}
|
||||
|
||||
// --- CHECK FOR SCROLL/CYCLE LIMIT BEFORE DISPLAYING ---
|
||||
// Scrolls complete applies to long messages.
|
||||
bool scrollsComplete = (messageScrollTimes > 0) && (currentScrollCount >= messageScrollTimes);
|
||||
|
||||
// Cycles complete applies to short messages.
|
||||
extern int currentDisplayCycleCount; // Use the dedicated short message counter
|
||||
bool cyclesComplete = (messageScrollTimes > 0) && (currentDisplayCycleCount >= messageScrollTimes);
|
||||
|
||||
|
||||
// --- ADVANCE MODE CHECK (Check if HA parameters are complete) ---
|
||||
// If either timer or cycle/scroll count is finished, we clean up the temporary message.
|
||||
if (scrollsComplete || cyclesComplete) {
|
||||
Serial.println(F("[MESSAGE] HA-controlled message finished."));
|
||||
// --- ADVANCE MODE CHECK (Check if HA parameters are complete) ---
|
||||
// If either timer or cycle/scroll count is finished, we clean up the temporary message.
|
||||
if (scrollsComplete || cyclesComplete) {
|
||||
Serial.println(F("[MESSAGE] HA-controlled message finished."));
|
||||
|
||||
// Reset common counters
|
||||
currentScrollCount = 0;
|
||||
messageStartTime = 0;
|
||||
currentDisplayCycleCount = 0; // Reset the cycle counter
|
||||
// Reset common counters
|
||||
currentScrollCount = 0;
|
||||
messageStartTime = 0;
|
||||
currentDisplayCycleCount = 0; // Reset the cycle counter
|
||||
|
||||
// CRITICAL LOGIC: RESTORE PERSISTENT MESSAGE (Exit Mode 6 Logic)
|
||||
if (strlen(lastPersistentMessage) > 0) {
|
||||
// A persistent message exists, restore it
|
||||
strncpy(customMessage, lastPersistentMessage, sizeof(customMessage));
|
||||
messageScrollSpeed = GENERAL_SCROLL_SPEED;
|
||||
messageDisplaySeconds = 0;
|
||||
messageScrollTimes = 0;
|
||||
Serial.printf("[MESSAGE] Restored persistent message: '%s'. Staying in mode 6.\n", customMessage);
|
||||
} else {
|
||||
// No persistent message to restore. Clear the temporary HA message and Exit mode 6.
|
||||
customMessage[0] = '\0';
|
||||
Serial.println(F("[MESSAGE] No persistent message to restore. Advancing display mode."));
|
||||
// CRITICAL LOGIC: RESTORE PERSISTENT MESSAGE (Exit Mode 6 Logic)
|
||||
if (strlen(lastPersistentMessage) > 0) {
|
||||
// A persistent message exists, restore it
|
||||
strncpy(customMessage, lastPersistentMessage, sizeof(customMessage));
|
||||
messageScrollSpeed = GENERAL_SCROLL_SPEED;
|
||||
messageDisplaySeconds = 0;
|
||||
messageScrollTimes = 0;
|
||||
Serial.printf("[MESSAGE] Restored persistent message: '%s'. Staying in mode 6.\n", customMessage);
|
||||
} else {
|
||||
// No persistent message to restore. Clear the temporary HA message and Exit mode 6.
|
||||
customMessage[0] = '\0';
|
||||
Serial.println(F("[MESSAGE] No persistent message to restore. Advancing display mode."));
|
||||
advanceDisplayMode();
|
||||
}
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// BRANCH A: NON-SCROLLING (Short Message: strlen <= 8)
|
||||
// ----------------------------------------------------------------------
|
||||
if (msg.length() <= MAX_NON_SCROLLING_CHARS) {
|
||||
|
||||
// Determine the duration: use HA seconds if set, otherwise use weatherDuration.
|
||||
unsigned long durationMs = (messageDisplaySeconds > 0)
|
||||
? (messageDisplaySeconds * 1000UL)
|
||||
: weatherDuration;
|
||||
|
||||
// If HA seconds is set, we use the timedOut check at the top.
|
||||
// If only scrollTimes is set, we still display for weatherDuration before incrementing the cycle count.
|
||||
|
||||
Serial.printf("[MESSAGE] Displaying timed short message: '%s' for %lu ms. Advancing mode.\n", customMessage, durationMs);
|
||||
|
||||
P.setTextAlignment(PA_CENTER);
|
||||
P.setCharSpacing(1);
|
||||
P.print(msg.c_str());
|
||||
|
||||
// Block execution for the specified duration (non-HA uses weatherDuration)
|
||||
unsigned long displayUntil = millis() + durationMs;
|
||||
while (millis() < displayUntil) {
|
||||
yield();
|
||||
}
|
||||
|
||||
// --- CYCLE TRACKING FOR SCROLLTIMES ---
|
||||
// Increment the counter if the HA message is configured to clear by scroll count.
|
||||
if (messageScrollTimes > 0) {
|
||||
currentDisplayCycleCount++;
|
||||
Serial.printf("[MESSAGE] Short message cycle complete. Count: %d/%d\n", currentDisplayCycleCount, messageScrollTimes);
|
||||
}
|
||||
|
||||
// After display, the message content must persist, but the display must cycle.
|
||||
Serial.println(F("[MESSAGE] Short message duration complete. Advancing display mode."));
|
||||
advanceDisplayMode();
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// BRANCH B: SCROLLING (Long Message: strlen > 8) - (Existing Logic)
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// --- Determine if we need left padding based on previous mode ---
|
||||
bool addPadding = false;
|
||||
bool humidityVisible = showHumidity && weatherAvailable && strlen(openWeatherApiKey) == 32 && strlen(openWeatherCity) > 0 && strlen(openWeatherCountry) > 0;
|
||||
|
||||
// If coming from CLOCK mode
|
||||
if (prevDisplayMode == 0 && (showDayOfWeek || colonBlinkEnabled)) {
|
||||
addPadding = true;
|
||||
} else if (prevDisplayMode == 1 && humidityVisible) {
|
||||
addPadding = true;
|
||||
}
|
||||
// Apply padding (4 spaces) if needed
|
||||
if (addPadding) {
|
||||
msg = " " + msg;
|
||||
}
|
||||
|
||||
// --- Display scrolling message ---
|
||||
P.setTextAlignment(PA_LEFT);
|
||||
P.setCharSpacing(1);
|
||||
textEffect_t actualScrollDirection = getEffectiveScrollDirection(PA_SCROLL_LEFT, flipDisplay);
|
||||
extern int messageScrollSpeed;
|
||||
|
||||
// START SCROLL CYCLE
|
||||
P.displayScroll(msg.c_str(), PA_LEFT, actualScrollDirection, messageScrollSpeed);
|
||||
|
||||
// BLOCKING WAIT: Completes 1 full scroll
|
||||
while (!P.displayAnimate()) yield();
|
||||
|
||||
// SCROLL COUNT INCREMENT
|
||||
if (messageScrollTimes > 0) {
|
||||
currentScrollCount++;
|
||||
Serial.printf("[MESSAGE] Scroll complete. Count: %d/%d\n", currentScrollCount, messageScrollTimes);
|
||||
}
|
||||
|
||||
// If no HA parameters are set, this is a persistent/infinite scroll, so advance mode after 1 scroll cycle.
|
||||
// If HA parameters ARE set, the mode relies on the check at the top to break out.
|
||||
if (messageDisplaySeconds == 0 && messageScrollTimes == 0) {
|
||||
P.setTextAlignment(PA_CENTER);
|
||||
advanceDisplayMode();
|
||||
}
|
||||
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// BRANCH A: NON-SCROLLING (Short Message: strlen <= 8)
|
||||
// ----------------------------------------------------------------------
|
||||
if (msg.length() <= MAX_NON_SCROLLING_CHARS) {
|
||||
|
||||
// Determine the duration: use HA seconds if set, otherwise use weatherDuration.
|
||||
unsigned long durationMs = (messageDisplaySeconds > 0)
|
||||
? (messageDisplaySeconds * 1000UL)
|
||||
: weatherDuration;
|
||||
|
||||
// If HA seconds is set, we use the timedOut check at the top.
|
||||
// If only scrollTimes is set, we still display for weatherDuration before incrementing the cycle count.
|
||||
|
||||
Serial.printf("[MESSAGE] Displaying timed short message: '%s' for %lu ms. Advancing mode.\n", customMessage, durationMs);
|
||||
|
||||
P.setTextAlignment(PA_CENTER);
|
||||
P.setCharSpacing(1);
|
||||
P.print(msg.c_str());
|
||||
|
||||
// Block execution for the specified duration (non-HA uses weatherDuration)
|
||||
unsigned long displayUntil = millis() + durationMs;
|
||||
while (millis() < displayUntil) {
|
||||
yield();
|
||||
}
|
||||
|
||||
// --- CYCLE TRACKING FOR SCROLLTIMES ---
|
||||
// Increment the counter if the HA message is configured to clear by scroll count.
|
||||
if (messageScrollTimes > 0) {
|
||||
currentDisplayCycleCount++;
|
||||
Serial.printf("[MESSAGE] Short message cycle complete. Count: %d/%d\n", currentDisplayCycleCount, messageScrollTimes);
|
||||
}
|
||||
|
||||
// After display, the message content must persist, but the display must cycle.
|
||||
Serial.println(F("[MESSAGE] Short message duration complete. Advancing display mode."));
|
||||
advanceDisplayMode();
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// BRANCH B: SCROLLING (Long Message: strlen > 8) - (Existing Logic)
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// --- Determine if we need left padding based on previous mode ---
|
||||
bool addPadding = false;
|
||||
bool humidityVisible = showHumidity && weatherAvailable && strlen(openWeatherApiKey) == 32 && strlen(openWeatherCity) > 0 && strlen(openWeatherCountry) > 0;
|
||||
|
||||
// If coming from CLOCK mode
|
||||
if (prevDisplayMode == 0 && (showDayOfWeek || colonBlinkEnabled)) {
|
||||
addPadding = true;
|
||||
} else if (prevDisplayMode == 1 && humidityVisible) {
|
||||
addPadding = true;
|
||||
}
|
||||
// Apply padding (4 spaces) if needed
|
||||
if (addPadding) {
|
||||
msg = " " + msg;
|
||||
}
|
||||
|
||||
// --- Display scrolling message ---
|
||||
P.setTextAlignment(PA_LEFT);
|
||||
P.setCharSpacing(1);
|
||||
textEffect_t actualScrollDirection = getEffectiveScrollDirection(PA_SCROLL_LEFT, flipDisplay);
|
||||
extern int messageScrollSpeed;
|
||||
|
||||
// START SCROLL CYCLE
|
||||
P.displayScroll(msg.c_str(), PA_LEFT, actualScrollDirection, messageScrollSpeed);
|
||||
|
||||
// BLOCKING WAIT: Completes 1 full scroll
|
||||
while (!P.displayAnimate()) yield();
|
||||
|
||||
// SCROLL COUNT INCREMENT
|
||||
if (messageScrollTimes > 0) {
|
||||
currentScrollCount++;
|
||||
Serial.printf("[MESSAGE] Scroll complete. Count: %d/%d\n", currentScrollCount, messageScrollTimes);
|
||||
}
|
||||
|
||||
// If no HA parameters are set, this is a persistent/infinite scroll, so advance mode after 1 scroll cycle.
|
||||
// If HA parameters ARE set, the mode relies on the check at the top to break out.
|
||||
if (messageDisplaySeconds == 0 && messageScrollTimes == 0) {
|
||||
P.setTextAlignment(PA_CENTER);
|
||||
advanceDisplayMode();
|
||||
}
|
||||
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
unsigned long currentMillis = millis();
|
||||
unsigned long runtimeSeconds = (currentMillis - bootMillis) / 1000;
|
||||
|
||||
@@ -3486,161 +3486,160 @@ void loop() {
|
||||
}
|
||||
|
||||
|
||||
// --- Custom Message Display Mode (displayMode == 6) ---
|
||||
if (displayMode == 6) {
|
||||
|
||||
// 1. Initial Check: If message is empty, skip mode 6.
|
||||
if (strlen(customMessage) == 0) {
|
||||
advanceDisplayMode();
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
// --- Custom Message Display Mode (displayMode == 6) ---
|
||||
if (displayMode == 6) {
|
||||
|
||||
// --- CHARACTER REPLACEMENT AND PADDING (Common to both short and long) ---
|
||||
const size_t MAX_NON_SCROLLING_CHARS = 8;
|
||||
String msg = String(customMessage);
|
||||
|
||||
// Replace standard digits 0–9 with your custom font character codes
|
||||
for (int i = 0; i < msg.length(); i++) {
|
||||
if (isDigit(msg[i])) {
|
||||
int num = msg[i] - '0';
|
||||
msg[i] = 145 + ((num + 9) % 10);
|
||||
// 1. Initial Check: If message is empty, skip mode 6.
|
||||
if (strlen(customMessage) == 0) {
|
||||
advanceDisplayMode();
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// --- CHECK FOR TIMEOUT (Applies to temporary short & long messages) ---
|
||||
bool timedOut = false;
|
||||
// Check if a time limit (messageDisplaySeconds > 0) has been exceeded
|
||||
if (messageDisplaySeconds > 0 && (millis() - messageStartTime) >= (messageDisplaySeconds * 1000UL)) {
|
||||
Serial.printf("[MESSAGE] HA message timed out after %d seconds.\n", messageDisplaySeconds);
|
||||
timedOut = true;
|
||||
}
|
||||
// --- CHARACTER REPLACEMENT AND PADDING (Common to both short and long) ---
|
||||
const size_t MAX_NON_SCROLLING_CHARS = 8;
|
||||
String msg = String(customMessage);
|
||||
|
||||
// --- CHECK FOR SCROLL/CYCLE LIMIT BEFORE DISPLAYING ---
|
||||
// Scrolls complete applies to long messages.
|
||||
bool scrollsComplete = (messageScrollTimes > 0) && (currentScrollCount >= messageScrollTimes);
|
||||
// Replace standard digits 0–9 with your custom font character codes
|
||||
for (int i = 0; i < msg.length(); i++) {
|
||||
if (isDigit(msg[i])) {
|
||||
int num = msg[i] - '0';
|
||||
msg[i] = 145 + ((num + 9) % 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Cycles complete applies to short messages.
|
||||
extern int currentDisplayCycleCount; // Use the dedicated short message counter
|
||||
bool cyclesComplete = (messageScrollTimes > 0) && (currentDisplayCycleCount >= messageScrollTimes);
|
||||
// --- CHECK FOR TIMEOUT (Applies to temporary short & long messages) ---
|
||||
bool timedOut = false;
|
||||
// Check if a time limit (messageDisplaySeconds > 0) has been exceeded
|
||||
if (messageDisplaySeconds > 0 && (millis() - messageStartTime) >= (messageDisplaySeconds * 1000UL)) {
|
||||
Serial.printf("[MESSAGE] HA message timed out after %d seconds.\n", messageDisplaySeconds);
|
||||
timedOut = true;
|
||||
}
|
||||
|
||||
// --- CHECK FOR SCROLL/CYCLE LIMIT BEFORE DISPLAYING ---
|
||||
// Scrolls complete applies to long messages.
|
||||
bool scrollsComplete = (messageScrollTimes > 0) && (currentScrollCount >= messageScrollTimes);
|
||||
|
||||
// Cycles complete applies to short messages.
|
||||
extern int currentDisplayCycleCount; // Use the dedicated short message counter
|
||||
bool cyclesComplete = (messageScrollTimes > 0) && (currentDisplayCycleCount >= messageScrollTimes);
|
||||
|
||||
|
||||
// --- ADVANCE MODE CHECK (Check if HA parameters are complete) ---
|
||||
// If either timer or cycle/scroll count is finished, we clean up the temporary message.
|
||||
if (scrollsComplete || cyclesComplete) {
|
||||
Serial.println(F("[MESSAGE] HA-controlled message finished."));
|
||||
// --- ADVANCE MODE CHECK (Check if HA parameters are complete) ---
|
||||
// If either timer or cycle/scroll count is finished, we clean up the temporary message.
|
||||
if (scrollsComplete || cyclesComplete) {
|
||||
Serial.println(F("[MESSAGE] HA-controlled message finished."));
|
||||
|
||||
// Reset common counters
|
||||
currentScrollCount = 0;
|
||||
messageStartTime = 0;
|
||||
currentDisplayCycleCount = 0; // Reset the cycle counter
|
||||
// Reset common counters
|
||||
currentScrollCount = 0;
|
||||
messageStartTime = 0;
|
||||
currentDisplayCycleCount = 0; // Reset the cycle counter
|
||||
|
||||
// CRITICAL LOGIC: RESTORE PERSISTENT MESSAGE (Exit Mode 6 Logic)
|
||||
if (strlen(lastPersistentMessage) > 0) {
|
||||
// A persistent message exists, restore it
|
||||
strncpy(customMessage, lastPersistentMessage, sizeof(customMessage));
|
||||
messageScrollSpeed = GENERAL_SCROLL_SPEED;
|
||||
messageDisplaySeconds = 0;
|
||||
messageScrollTimes = 0;
|
||||
Serial.printf("[MESSAGE] Restored persistent message: '%s'. Staying in mode 6.\n", customMessage);
|
||||
} else {
|
||||
// No persistent message to restore. Clear the temporary HA message and Exit mode 6.
|
||||
customMessage[0] = '\0';
|
||||
Serial.println(F("[MESSAGE] No persistent message to restore. Advancing display mode."));
|
||||
// CRITICAL LOGIC: RESTORE PERSISTENT MESSAGE (Exit Mode 6 Logic)
|
||||
if (strlen(lastPersistentMessage) > 0) {
|
||||
// A persistent message exists, restore it
|
||||
strncpy(customMessage, lastPersistentMessage, sizeof(customMessage));
|
||||
messageScrollSpeed = GENERAL_SCROLL_SPEED;
|
||||
messageDisplaySeconds = 0;
|
||||
messageScrollTimes = 0;
|
||||
Serial.printf("[MESSAGE] Restored persistent message: '%s'. Staying in mode 6.\n", customMessage);
|
||||
} else {
|
||||
// No persistent message to restore. Clear the temporary HA message and Exit mode 6.
|
||||
customMessage[0] = '\0';
|
||||
Serial.println(F("[MESSAGE] No persistent message to restore. Advancing display mode."));
|
||||
advanceDisplayMode();
|
||||
}
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// BRANCH A: NON-SCROLLING (Short Message: strlen <= 8)
|
||||
// ----------------------------------------------------------------------
|
||||
if (msg.length() <= MAX_NON_SCROLLING_CHARS) {
|
||||
|
||||
// Determine the duration: use HA seconds if set, otherwise use weatherDuration.
|
||||
unsigned long durationMs = (messageDisplaySeconds > 0)
|
||||
? (messageDisplaySeconds * 1000UL)
|
||||
: weatherDuration;
|
||||
|
||||
// If HA seconds is set, we use the timedOut check at the top.
|
||||
// If only scrollTimes is set, we still display for weatherDuration before incrementing the cycle count.
|
||||
|
||||
Serial.printf("[MESSAGE] Displaying timed short message: '%s' for %lu ms. Advancing mode.\n", customMessage, durationMs);
|
||||
|
||||
P.setTextAlignment(PA_CENTER);
|
||||
P.setCharSpacing(1);
|
||||
P.print(msg.c_str());
|
||||
|
||||
// Block execution for the specified duration (non-HA uses weatherDuration)
|
||||
unsigned long displayUntil = millis() + durationMs;
|
||||
while (millis() < displayUntil) {
|
||||
yield();
|
||||
}
|
||||
|
||||
// --- CYCLE TRACKING FOR SCROLLTIMES ---
|
||||
// Increment the counter if the HA message is configured to clear by scroll count.
|
||||
if (messageScrollTimes > 0) {
|
||||
currentDisplayCycleCount++;
|
||||
Serial.printf("[MESSAGE] Short message cycle complete. Count: %d/%d\n", currentDisplayCycleCount, messageScrollTimes);
|
||||
}
|
||||
|
||||
// After display, the message content must persist, but the display must cycle.
|
||||
Serial.println(F("[MESSAGE] Short message duration complete. Advancing display mode."));
|
||||
advanceDisplayMode();
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// BRANCH B: SCROLLING (Long Message: strlen > 8) - (Existing Logic)
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// --- Determine if we need left padding based on previous mode ---
|
||||
bool addPadding = false;
|
||||
bool humidityVisible = showHumidity && weatherAvailable && strlen(openWeatherApiKey) == 32 && strlen(openWeatherCity) > 0 && strlen(openWeatherCountry) > 0;
|
||||
|
||||
// If coming from CLOCK mode
|
||||
if (prevDisplayMode == 0 && (showDayOfWeek || colonBlinkEnabled)) {
|
||||
addPadding = true;
|
||||
} else if (prevDisplayMode == 1 && humidityVisible) {
|
||||
addPadding = true;
|
||||
}
|
||||
// Apply padding (4 spaces) if needed
|
||||
if (addPadding) {
|
||||
msg = " " + msg;
|
||||
}
|
||||
|
||||
// --- Display scrolling message ---
|
||||
P.setTextAlignment(PA_LEFT);
|
||||
P.setCharSpacing(1);
|
||||
textEffect_t actualScrollDirection = getEffectiveScrollDirection(PA_SCROLL_LEFT, flipDisplay);
|
||||
extern int messageScrollSpeed;
|
||||
|
||||
// START SCROLL CYCLE
|
||||
P.displayScroll(msg.c_str(), PA_LEFT, actualScrollDirection, messageScrollSpeed);
|
||||
|
||||
// BLOCKING WAIT: Completes 1 full scroll
|
||||
while (!P.displayAnimate()) yield();
|
||||
|
||||
// SCROLL COUNT INCREMENT
|
||||
if (messageScrollTimes > 0) {
|
||||
currentScrollCount++;
|
||||
Serial.printf("[MESSAGE] Scroll complete. Count: %d/%d\n", currentScrollCount, messageScrollTimes);
|
||||
}
|
||||
|
||||
// If no HA parameters are set, this is a persistent/infinite scroll, so advance mode after 1 scroll cycle.
|
||||
// If HA parameters ARE set, the mode relies on the check at the top to break out.
|
||||
if (messageDisplaySeconds == 0 && messageScrollTimes == 0) {
|
||||
P.setTextAlignment(PA_CENTER);
|
||||
advanceDisplayMode();
|
||||
}
|
||||
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// BRANCH A: NON-SCROLLING (Short Message: strlen <= 8)
|
||||
// ----------------------------------------------------------------------
|
||||
if (msg.length() <= MAX_NON_SCROLLING_CHARS) {
|
||||
|
||||
// Determine the duration: use HA seconds if set, otherwise use weatherDuration.
|
||||
unsigned long durationMs = (messageDisplaySeconds > 0)
|
||||
? (messageDisplaySeconds * 1000UL)
|
||||
: weatherDuration;
|
||||
|
||||
// If HA seconds is set, we use the timedOut check at the top.
|
||||
// If only scrollTimes is set, we still display for weatherDuration before incrementing the cycle count.
|
||||
|
||||
Serial.printf("[MESSAGE] Displaying timed short message: '%s' for %lu ms. Advancing mode.\n", customMessage, durationMs);
|
||||
|
||||
P.setTextAlignment(PA_CENTER);
|
||||
P.setCharSpacing(1);
|
||||
P.print(msg.c_str());
|
||||
|
||||
// Block execution for the specified duration (non-HA uses weatherDuration)
|
||||
unsigned long displayUntil = millis() + durationMs;
|
||||
while (millis() < displayUntil) {
|
||||
yield();
|
||||
}
|
||||
|
||||
// --- CYCLE TRACKING FOR SCROLLTIMES ---
|
||||
// Increment the counter if the HA message is configured to clear by scroll count.
|
||||
if (messageScrollTimes > 0) {
|
||||
currentDisplayCycleCount++;
|
||||
Serial.printf("[MESSAGE] Short message cycle complete. Count: %d/%d\n", currentDisplayCycleCount, messageScrollTimes);
|
||||
}
|
||||
|
||||
// After display, the message content must persist, but the display must cycle.
|
||||
Serial.println(F("[MESSAGE] Short message duration complete. Advancing display mode."));
|
||||
advanceDisplayMode();
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// BRANCH B: SCROLLING (Long Message: strlen > 8) - (Existing Logic)
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// --- Determine if we need left padding based on previous mode ---
|
||||
bool addPadding = false;
|
||||
bool humidityVisible = showHumidity && weatherAvailable && strlen(openWeatherApiKey) == 32 && strlen(openWeatherCity) > 0 && strlen(openWeatherCountry) > 0;
|
||||
|
||||
// If coming from CLOCK mode
|
||||
if (prevDisplayMode == 0 && (showDayOfWeek || colonBlinkEnabled)) {
|
||||
addPadding = true;
|
||||
} else if (prevDisplayMode == 1 && humidityVisible) {
|
||||
addPadding = true;
|
||||
}
|
||||
// Apply padding (4 spaces) if needed
|
||||
if (addPadding) {
|
||||
msg = " " + msg;
|
||||
}
|
||||
|
||||
// --- Display scrolling message ---
|
||||
P.setTextAlignment(PA_LEFT);
|
||||
P.setCharSpacing(1);
|
||||
textEffect_t actualScrollDirection = getEffectiveScrollDirection(PA_SCROLL_LEFT, flipDisplay);
|
||||
extern int messageScrollSpeed;
|
||||
|
||||
// START SCROLL CYCLE
|
||||
P.displayScroll(msg.c_str(), PA_LEFT, actualScrollDirection, messageScrollSpeed);
|
||||
|
||||
// BLOCKING WAIT: Completes 1 full scroll
|
||||
while (!P.displayAnimate()) yield();
|
||||
|
||||
// SCROLL COUNT INCREMENT
|
||||
if (messageScrollTimes > 0) {
|
||||
currentScrollCount++;
|
||||
Serial.printf("[MESSAGE] Scroll complete. Count: %d/%d\n", currentScrollCount, messageScrollTimes);
|
||||
}
|
||||
|
||||
// If no HA parameters are set, this is a persistent/infinite scroll, so advance mode after 1 scroll cycle.
|
||||
// If HA parameters ARE set, the mode relies on the check at the top to break out.
|
||||
if (messageDisplaySeconds == 0 && messageScrollTimes == 0) {
|
||||
P.setTextAlignment(PA_CENTER);
|
||||
advanceDisplayMode();
|
||||
}
|
||||
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
unsigned long currentMillis = millis();
|
||||
unsigned long runtimeSeconds = (currentMillis - bootMillis) / 1000;
|
||||
unsigned long currentTotal = totalUptimeSeconds + runtimeSeconds;
|
||||
|
||||
Reference in New Issue
Block a user