diff --git a/internal/control/ui.html b/internal/control/ui.html index 7ff20f8..eb211cd 100644 --- a/internal/control/ui.html +++ b/internal/control/ui.html @@ -1180,6 +1180,7 @@ input.input-error {
Buffer Duration
--
High Watermark
--
Queue Fill
--
+
Underrun Streak
--
Last Update
--
High Watermark Trend
@@ -1972,7 +1973,7 @@ function render() { updateText('info-fmmod', fmtBool(cfg.fm?.fmModulationEnabled)); updateText('info-live', engine.state ? `${String(engine.state).toUpperCase()} / ${state.server.runtimeOk ? 'runtime ok' : 'runtime pending'}` : (state.server.configOk ? 'config only' : '--')); - updateHealth(engine, audioStream); + updateHealth(engine, driver, audioStream); updateFaultHistory(engine); updateTransitionHistory(); updateResetHint(engine); @@ -2077,8 +2078,9 @@ function notifyRuntimeTransition(engine, pushHistory = true) { } -function updateHealth(engine, audioStream) { +function updateHealth(engine, driver, audioStream) { engine = engine || {}; + driver = driver || {}; updateText('health-http', state.server.configOk ? 'OK' : 'OFFLINE'); $('health-http').className = 'val ' + (state.server.configOk ? 'good' : 'err'); @@ -2175,6 +2177,35 @@ function updateHealth(engine, audioStream) { queueFillEl.className = 'val ' + queueFillClass; } + const streakEl = $('health-underrun-streak'); + if (streakEl) { + const streakRaw = driver?.underrunStreak; + const streakMaxRaw = driver?.maxUnderrunStreak; + const streakCurrent = Number.isFinite(Number(streakRaw)) ? Number(streakRaw) : null; + const streakMax = Number.isFinite(Number(streakMaxRaw)) ? Number(streakMaxRaw) : null; + let streakLabel = '--'; + if (streakCurrent != null) { + streakLabel = String(streakCurrent); + if (streakMax != null) { + streakLabel += ` (max ${streakMax})`; + } + } else if (streakMax != null) { + streakLabel = `Max ${streakMax}`; + } + let streakSeverity = ''; + if (streakCurrent != null || streakMax != null) { + const highestStreak = Math.max( + streakCurrent != null ? streakCurrent : 0, + streakMax != null ? streakMax : 0 + ); + if (highestStreak >= 6) streakSeverity = ' err'; + else if (highestStreak > 0) streakSeverity = ' warn'; + else streakSeverity = ' good'; + } + streakEl.textContent = streakLabel; + streakEl.className = 'val' + streakSeverity; + } + const last = Math.max(state.server.lastConfigAt || 0, state.server.lastRuntimeAt || 0); updateText('health-last', ageString(last));