From c03ced5539561a9468fdf9f5eaf3970702a46418 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Sep 2025 19:23:01 +0000 Subject: [PATCH 1/9] Initial plan From 07f408e53d480c7cd772d8700fb13c6435835b5b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Sep 2025 19:34:46 +0000 Subject: [PATCH 2/9] Implement comprehensive error logging system with user-accessible error log Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- wled00/const.h | 17 ++++ wled00/data/index.js | 187 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 169 insertions(+), 35 deletions(-) diff --git a/wled00/const.h b/wled00/const.h index 8891dfcaee..01ddee4f16 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -439,6 +439,23 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit"); #define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented) #define ERR_UNDERVOLT 32 // An attached voltmeter has measured a voltage below the threshold (not implemented) +// Additional error types for better user feedback +#define ERR_NORAM_BUS 33 // Not enough RAM for bus allocation +#define ERR_NORAM_SEG 34 // Not enough RAM for segment allocation +#define ERR_NORAM_TRANS 35 // Not enough RAM for transition effects +#define ERR_PIN_CONFLICT 36 // Pin assignment conflict detected +#define ERR_PIN_INVALID 37 // Invalid pin number for this platform +#define ERR_CONFIG_LOAD 38 // Configuration loading failed +#define ERR_CONFIG_SAVE 39 // Configuration saving failed + +// Warning types (starting at 100 as requested) +#define WARN_LOW_MEMORY 100 // Low memory warning +#define WARN_HIGH_TEMP 101 // Temperature approaching limits +#define WARN_LOW_VOLTAGE 102 // Voltage below optimal range +#define WARN_HIGH_CURRENT 103 // Current approaching limits +#define WARN_WIFI_WEAK 104 // Weak WiFi signal +#define WARN_FS_SPACE 105 // Filesystem space running low + // Timer mode types #define NL_MODE_SET 0 //After nightlight time elapsed, set to target brightness #define NL_MODE_FADE 1 //Fade to target brightness gradually diff --git a/wled00/data/index.js b/wled00/data/index.js index 2514f03fb1..db5e8ac4e1 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -26,6 +26,8 @@ var pmt = 1, pmtLS = 0, pmtLast = 0; var lastinfo = {}; var isM = false, mw = 0, mh=0; var ws, wsRpt=0; +var errorLog = []; // Store last 5 errors/warnings +var hasUnreadErrors = false; var cfg = { theme:{base:"dark", bg:{url:"", rnd: false, rndGrayscale: false, rndBlur: false}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, @@ -384,6 +386,131 @@ function inforow(key, val, unit = "") return `${key}${val}${unit}`; } +function getErrorMessage(errorCode) { + switch (errorCode) { + case 1: return "Operation denied by current settings"; + case 2: return "Cannot process request while client is active"; + case 3: return "JSON buffer is locked, try again in a moment"; + case 4: return "Feature not implemented on this version"; + case 7: return "Insufficient RAM to allocate pixel buffer"; + case 8: return "Not enough RAM available for effect processing"; + case 9: return "JSON parsing failed - data may be too large"; + case 10: return "Could not initialize filesystem - check partition"; + case 11: return "Not enough space to save preset to filesystem"; + case 12: return "Requested preset does not exist"; + case 13: return "IR configuration file 'ir.json' not found"; + case 14: return "Remote configuration file 'remote.json' not found"; + case 19: return "An unspecified filesystem error occurred"; + case 30: return "Temperature sensor reading above safe threshold"; + case 31: return "Current sensor reading above safe threshold"; + case 32: return "Voltage sensor reading below safe threshold"; + case 33: return "Insufficient RAM to allocate LED bus"; + case 34: return "Insufficient RAM to allocate segment data"; + case 35: return "Insufficient RAM for transition effects"; + case 36: return "Pin assignment conflict detected"; + case 37: return "Invalid pin number for this platform"; + case 38: return "Failed to load configuration from filesystem"; + case 39: return "Failed to save configuration to filesystem"; + case 100: return "Memory usage is approaching limits"; + case 101: return "Temperature is approaching safe limits"; + case 102: return "Voltage is below optimal operating range"; + case 103: return "Current draw is approaching safe limits"; + case 104: return "WiFi signal strength is poor"; + case 105: return "Filesystem space is running low"; + default: return `Unknown error code ${errorCode}`; + } +} + +function addToErrorLog(errorCode, timestamp = null) { + if (!timestamp) timestamp = Date.now(); + + const errorEntry = { + code: errorCode, + message: getErrorMessage(errorCode), + timestamp: timestamp, + isWarning: errorCode >= 100 + }; + + // Add to beginning of array + errorLog.unshift(errorEntry); + + // Keep only last 5 entries + if (errorLog.length > 5) { + errorLog = errorLog.slice(0, 5); + } + + hasUnreadErrors = true; + updateInfoButtonIcon(); +} + +function updateInfoButtonIcon() { + const infoBtn = gId('buttonI'); + const icon = infoBtn.querySelector('i'); + if (hasUnreadErrors) { + // Change to red exclamation mark icon + icon.innerHTML = ''; // Exclamation mark + icon.style.color = 'var(--c-r)'; + } else { + // Reset to normal info icon + icon.innerHTML = ''; // Info icon + icon.style.color = ''; + } +} + +function clearErrorLog() { + errorLog = []; + hasUnreadErrors = false; + updateInfoButtonIcon(); + const errorArea = gId('errorLogArea'); + if (errorArea) { + errorArea.style.display = 'none'; + gId('errorLogContent').innerHTML = ''; + } +} + +function generateErrorLogHtml() { + if (errorLog.length === 0) return ''; + + let html = ''; + for (let i = 0; i < errorLog.length; i++) { + const entry = errorLog[i]; + const timeStr = new Date(entry.timestamp).toLocaleTimeString(); + const icon = entry.isWarning ? '⚠' : '🚫'; // Warning triangle or error circle + const color = entry.isWarning ? 'var(--c-y)' : 'var(--c-r)'; + + html += `
+
+ ${icon} ${entry.isWarning ? 'Warning' : 'Error'} ${entry.code} - ${timeStr} +
+
+ ${entry.message} +
+
`; + } + + html += `
+ +
`; + + return html; +} + +function toggleErrorLog() { + const content = gId('errorLogContent'); + const button = content.previousElementSibling; + + if (content.style.display === 'none') { + content.style.display = 'block'; + content.innerHTML = generateErrorLogHtml(); + button.innerHTML = ' Hide Error Log'; + } else { + content.style.display = 'none'; + button.innerHTML = ` Show Error Log (${errorLog.length})`; + } +} + function getLowestUnusedP() { var l = 1; @@ -746,6 +873,19 @@ ${inforow("Flash size",i.flash," MB")} ${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")} ${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")} `; + + // Add error log section if there are any errors + if (errorLog.length > 0) { + cn += `
+ + +
`; + } + gId('kv').innerHTML = cn; // update all sliders in Info d.querySelectorAll('#kv .sliderdisplay').forEach((sd,i) => { @@ -1518,40 +1658,12 @@ function readState(s,command=false) gId('checkO3').checked = !(!i.o3); if (s.error && s.error != 0) { - var errstr = ""; - switch (s.error) { - case 1: - errstr = "Denied!"; - break; - case 3: - errstr = "Buffer locked!"; - break; - case 7: - errstr = "No RAM for buffer!"; - break; - case 8: - errstr = "Effect RAM depleted!"; - break; - case 9: - errstr = "JSON parsing error!"; - break; - case 10: - errstr = "Could not mount filesystem!"; - break; - case 11: - errstr = "Not enough space to save preset!"; - break; - case 12: - errstr = "Preset not found."; - break; - case 13: - errstr = "Missing ir.json."; - break; - case 19: - errstr = "A filesystem error has occured."; - break; - } - showToast('Error ' + s.error + ": " + errstr, true); + // Add to error log for detailed tracking + addToErrorLog(s.error); + + // Keep showing toast for immediate feedback (simplified message) + const shortMessage = s.error >= 100 ? 'Warning' : 'Error'; + showToast(`${shortMessage} ${s.error}`, true); } selectedPal = i.pal; @@ -1846,7 +1958,12 @@ function toggleInfo() if (isNodes) toggleNodes(); if (isLv && isM) toggleLiveview(); isInfo = !isInfo; - if (isInfo) requestJson(); + if (isInfo) { + requestJson(); + // Mark errors as read when info panel is opened + hasUnreadErrors = false; + updateInfoButtonIcon(); + } gId('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)"; gId('buttonI').className = (isInfo) ? "active":""; } From cc827c82350e3f4170e2f66b4ac4b2d2a1de64b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Sep 2025 10:26:41 +0000 Subject: [PATCH 3/9] Fix error logging system based on feedback - restore detailed toasts, fix positioning and icon Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- wled00/data/index.htm | 6 ++ wled00/data/index.js | 131 ++++++++++++++++++++++++++++++------------ 2 files changed, 100 insertions(+), 37 deletions(-) diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 22f1987e93..c075932f17 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -332,6 +332,12 @@ +
Made with ❤︎ by Aircoookie and the WLED community diff --git a/wled00/data/index.js b/wled00/data/index.js index db5e8ac4e1..b5db7081f2 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -448,7 +448,7 @@ function updateInfoButtonIcon() { const icon = infoBtn.querySelector('i'); if (hasUnreadErrors) { // Change to red exclamation mark icon - icon.innerHTML = ''; // Exclamation mark + icon.innerHTML = ''; // Use add/warning icon icon.style.color = 'var(--c-r)'; } else { // Reset to normal info icon @@ -464,7 +464,6 @@ function clearErrorLog() { const errorArea = gId('errorLogArea'); if (errorArea) { errorArea.style.display = 'none'; - gId('errorLogContent').innerHTML = ''; } } @@ -488,29 +487,9 @@ function generateErrorLogHtml() { `; } - html += `
- -
`; - return html; } -function toggleErrorLog() { - const content = gId('errorLogContent'); - const button = content.previousElementSibling; - - if (content.style.display === 'none') { - content.style.display = 'block'; - content.innerHTML = generateErrorLogHtml(); - button.innerHTML = ' Hide Error Log'; - } else { - content.style.display = 'none'; - button.innerHTML = ` Show Error Log (${errorLog.length})`; - } -} - function getLowestUnusedP() { var l = 1; @@ -873,20 +852,17 @@ ${inforow("Flash size",i.flash," MB")} ${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")} ${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")} `; - - // Add error log section if there are any errors - if (errorLog.length > 0) { - cn += `
- - -
`; - } gId('kv').innerHTML = cn; + + // Update error log area visibility and content + const errorArea = gId('errorLogArea'); + if (errorLog.length > 0) { + errorArea.style.display = 'block'; + gId('errorLogContent').innerHTML = generateErrorLogHtml(); + } else { + errorArea.style.display = 'none'; + } // update all sliders in Info d.querySelectorAll('#kv .sliderdisplay').forEach((sd,i) => { let s = sd.previousElementSibling; @@ -1661,9 +1637,90 @@ function readState(s,command=false) // Add to error log for detailed tracking addToErrorLog(s.error); - // Keep showing toast for immediate feedback (simplified message) - const shortMessage = s.error >= 100 ? 'Warning' : 'Error'; - showToast(`${shortMessage} ${s.error}`, true); + // Show detailed toast message as before + var errstr = ""; + switch (s.error) { + case 1: + errstr = "Denied!"; + break; + case 3: + errstr = "Buffer locked!"; + break; + case 7: + errstr = "No RAM for buffer!"; + break; + case 8: + errstr = "Effect RAM depleted!"; + break; + case 9: + errstr = "JSON parsing error!"; + break; + case 10: + errstr = "Could not mount filesystem!"; + break; + case 11: + errstr = "Not enough space to save preset!"; + break; + case 12: + errstr = "Preset not found."; + break; + case 13: + errstr = "Missing ir.json."; + break; + case 19: + errstr = "A filesystem error has occured."; + break; + case 30: + errstr = "Overtemperature!"; + break; + case 31: + errstr = "Overcurrent!"; + break; + case 32: + errstr = "Undervoltage!"; + break; + case 33: + errstr = "No RAM for bus!"; + break; + case 34: + errstr = "No RAM for segment!"; + break; + case 35: + errstr = "No RAM for transitions!"; + break; + case 36: + errstr = "Pin conflict!"; + break; + case 37: + errstr = "Invalid pin!"; + break; + case 38: + errstr = "Config load failed!"; + break; + case 39: + errstr = "Config save failed!"; + break; + case 100: + errstr = "Low memory!"; + break; + case 101: + errstr = "High temperature!"; + break; + case 102: + errstr = "Low voltage!"; + break; + case 103: + errstr = "High current!"; + break; + case 104: + errstr = "Weak WiFi!"; + break; + case 105: + errstr = "Low disk space!"; + break; + } + const prefix = s.error >= 100 ? 'Warning' : 'Error'; + showToast(`${prefix} ${s.error}: ${errstr}`, true); } selectedPal = i.pal; From 61b11e185c06e5aa03da43e79799ccf7842f0930 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Sep 2025 06:32:01 +0000 Subject: [PATCH 4/9] Implement server-side error logging system with client-side timestamp calculation Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- wled00/data/index.htm | 12 ++-- wled00/data/index.js | 155 ++++++++++++++++-------------------------- wled00/fcn_declare.h | 4 ++ wled00/json.cpp | 28 +++++++- wled00/util.cpp | 19 ++++++ wled00/wled.h | 14 ++++ 6 files changed, 127 insertions(+), 105 deletions(-) diff --git a/wled00/data/index.htm b/wled00/data/index.htm index c075932f17..3b92d971e5 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -325,6 +325,12 @@
+
Loading...

@@ -332,12 +338,6 @@
-
Made with ❤︎ by Aircoookie and the WLED community diff --git a/wled00/data/index.js b/wled00/data/index.js index b5db7081f2..b9955ea3e4 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -457,14 +457,58 @@ function updateInfoButtonIcon() { } } -function clearErrorLog() { +function handleServerErrorLog(serverErrors, serverTime) { + // Clear client-side log and replace with server data errorLog = []; hasUnreadErrors = false; - updateInfoButtonIcon(); - const errorArea = gId('errorLogArea'); - if (errorArea) { - errorArea.style.display = 'none'; + + for (let i = 0; i < serverErrors.length; i++) { + const serverEntry = serverErrors[i]; + // Calculate absolute timestamp using server time and error timestamp + const absoluteTime = Date.now() - (serverTime - serverEntry.t); + + const errorEntry = { + code: serverEntry.c, + message: getErrorMessage(serverEntry.c), + timestamp: absoluteTime, + isWarning: serverEntry.c >= 100, + tag1: serverEntry.t1 || 0, + tag2: serverEntry.t2 || 0, + tag3: serverEntry.t3 || 0 + }; + + errorLog.push(errorEntry); + } + + if (errorLog.length > 0) { + hasUnreadErrors = true; } + + updateInfoButtonIcon(); +} + +function clearErrorLog() { + // Send clear command to server + fetch(getURL('/json/state'), { + method: 'post', + body: JSON.stringify({clearErrorLog: true}), + headers: { + 'Content-Type': 'application/json' + } + }) + .then(res => { + // Clear local state + errorLog = []; + hasUnreadErrors = false; + updateInfoButtonIcon(); + const errorArea = gId('errorLogArea'); + if (errorArea) { + errorArea.style.display = 'none'; + } + }) + .catch((error) => { + console.log('Error clearing log:', error); + }); } function generateErrorLogHtml() { @@ -474,16 +518,11 @@ function generateErrorLogHtml() { for (let i = 0; i < errorLog.length; i++) { const entry = errorLog[i]; const timeStr = new Date(entry.timestamp).toLocaleTimeString(); - const icon = entry.isWarning ? '⚠' : '🚫'; // Warning triangle or error circle + const prefix = entry.isWarning ? 'Warning' : 'Error'; const color = entry.isWarning ? 'var(--c-y)' : 'var(--c-r)'; - html += `
-
- ${icon} ${entry.isWarning ? 'Warning' : 'Error'} ${entry.code} - ${timeStr} -
-
- ${entry.message} -
+ html += `
+ ${prefix} ${entry.code} - ${timeStr}: ${entry.message}
`; } @@ -1636,91 +1675,11 @@ function readState(s,command=false) if (s.error && s.error != 0) { // Add to error log for detailed tracking addToErrorLog(s.error); - - // Show detailed toast message as before - var errstr = ""; - switch (s.error) { - case 1: - errstr = "Denied!"; - break; - case 3: - errstr = "Buffer locked!"; - break; - case 7: - errstr = "No RAM for buffer!"; - break; - case 8: - errstr = "Effect RAM depleted!"; - break; - case 9: - errstr = "JSON parsing error!"; - break; - case 10: - errstr = "Could not mount filesystem!"; - break; - case 11: - errstr = "Not enough space to save preset!"; - break; - case 12: - errstr = "Preset not found."; - break; - case 13: - errstr = "Missing ir.json."; - break; - case 19: - errstr = "A filesystem error has occured."; - break; - case 30: - errstr = "Overtemperature!"; - break; - case 31: - errstr = "Overcurrent!"; - break; - case 32: - errstr = "Undervoltage!"; - break; - case 33: - errstr = "No RAM for bus!"; - break; - case 34: - errstr = "No RAM for segment!"; - break; - case 35: - errstr = "No RAM for transitions!"; - break; - case 36: - errstr = "Pin conflict!"; - break; - case 37: - errstr = "Invalid pin!"; - break; - case 38: - errstr = "Config load failed!"; - break; - case 39: - errstr = "Config save failed!"; - break; - case 100: - errstr = "Low memory!"; - break; - case 101: - errstr = "High temperature!"; - break; - case 102: - errstr = "Low voltage!"; - break; - case 103: - errstr = "High current!"; - break; - case 104: - errstr = "Weak WiFi!"; - break; - case 105: - errstr = "Low disk space!"; - break; - } - const prefix = s.error >= 100 ? 'Warning' : 'Error'; - showToast(`${prefix} ${s.error}: ${errstr}`, true); + } + + // Handle server-side error log + if (s.errorLog && s.errorLogTime) { + handleServerErrorLog(s.errorLog, s.errorLogTime); } selectedPal = i.pal; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 1d81655d6d..4cc2f7999a 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -555,4 +555,8 @@ void sendDataWs(AsyncWebSocketClient * client = nullptr); void XML_response(Print& dest); void getSettingsJS(byte subPage, Print& dest); +//util.cpp - error logging +void addToErrorLog(byte errorCode, byte tag1 = 0, byte tag2 = 0, byte tag3 = 0); +void clearErrorLog(); + #endif diff --git a/wled00/json.cpp b/wled00/json.cpp index d2b771c590..391a6251db 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -367,6 +367,11 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) #if defined(WLED_DEBUG) && defined(WLED_DEBUG_HOST) netDebugEnabled = root[F("debug")] | netDebugEnabled; #endif + + // Handle clear error log command + if (root[F("clearErrorLog")]) { + clearErrorLog(); + } bool onBefore = bri; getVal(root["bri"], bri); @@ -639,7 +644,28 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme } if (!forPreset) { - if (errorFlag) {root[F("error")] = errorFlag; errorFlag = ERR_NONE;} //prevent error message to persist on screen + if (errorFlag) { + root[F("error")] = errorFlag; + addToErrorLog(errorFlag); // Add to error log + errorFlag = ERR_NONE; // Reset error flag + } + + // Add error log to JSON response + if (errorLogCount > 0) { + JsonArray errors = root.createNestedArray(F("errorLog")); + byte startIdx = (errorLogIndex + ERROR_LOG_SIZE - errorLogCount) % ERROR_LOG_SIZE; + + for (byte i = 0; i < errorLogCount; i++) { + byte idx = (startIdx + i) % ERROR_LOG_SIZE; + JsonObject err = errors.createNestedObject(); + err[F("t")] = errorLog[idx].timestamp; + err[F("c")] = errorLog[idx].errorCode; + err[F("t1")] = errorLog[idx].tag1; + err[F("t2")] = errorLog[idx].tag2; + err[F("t3")] = errorLog[idx].tag3; + } + root[F("errorLogTime")] = millis(); // Current time for client calculations + } root["ps"] = (currentPreset > 0) ? currentPreset : -1; root[F("pl")] = currentPlaylist; diff --git a/wled00/util.cpp b/wled00/util.cpp index 8aaaf34cab..e02892de8e 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -1124,4 +1124,23 @@ uint8_t perlin8(uint16_t x, uint16_t y) { uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z) { return (((perlin3D_raw((uint32_t)x << 8, (uint32_t)y << 8, (uint32_t)z << 8, true) * 2015) >> 10) + 33168) >> 8; //scale to 16 bit, offset, then scale to 8bit +} + +// Error logging functions +void addToErrorLog(byte errorCode, byte tag1 = 0, byte tag2 = 0, byte tag3 = 0) { + errorLog[errorLogIndex].timestamp = millis(); + errorLog[errorLogIndex].errorCode = errorCode; + errorLog[errorLogIndex].tag1 = tag1; + errorLog[errorLogIndex].tag2 = tag2; + errorLog[errorLogIndex].tag3 = tag3; + + errorLogIndex = (errorLogIndex + 1) % ERROR_LOG_SIZE; + if (errorLogCount < ERROR_LOG_SIZE) { + errorLogCount++; + } +} + +void clearErrorLog() { + errorLogIndex = 0; + errorLogCount = 0; } \ No newline at end of file diff --git a/wled00/wled.h b/wled00/wled.h index a783986a87..fb549ba389 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -889,6 +889,20 @@ WLED_GLOBAL byte currentPreset _INIT(0); WLED_GLOBAL byte errorFlag _INIT(0); +// Error logging system +struct ErrorLogEntry { + unsigned long timestamp; // millis() when error occurred + byte errorCode; // error number (8bit) + byte tag1; // future use tag 1 + byte tag2; // future use tag 2 + byte tag3; // future use tag 3 +}; + +#define ERROR_LOG_SIZE 5 +WLED_GLOBAL ErrorLogEntry errorLog[ERROR_LOG_SIZE]; +WLED_GLOBAL byte errorLogIndex _INIT(0); +WLED_GLOBAL byte errorLogCount _INIT(0); + WLED_GLOBAL String messageHead, messageSub; WLED_GLOBAL byte optionType; From 756697ae7821d391577a681639e1def195e355c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Sep 2025 11:00:20 +0000 Subject: [PATCH 5/9] Improve error log formatting - remove colored lines, center align area, 24h timestamps, larger font Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com> --- wled00/data/index.htm | 4 ++-- wled00/data/index.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 3b92d971e5..4ace10479c 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -325,8 +325,8 @@
-