|
|
|
@@ -79,6 +79,8 @@ const healthResets = qs('healthResets'); |
|
|
|
const healthAge = qs('healthAge'); |
|
|
|
const healthGpu = qs('healthGpu'); |
|
|
|
const healthFps = qs('healthFps'); |
|
|
|
const healthRefinePlan = qs('healthRefinePlan'); |
|
|
|
const healthRefineWindows = qs('healthRefineWindows'); |
|
|
|
|
|
|
|
const drawerEl = qs('eventDrawer'); |
|
|
|
const drawerCloseBtn = qs('drawerClose'); |
|
|
|
@@ -739,6 +741,14 @@ async function loadGPU() { |
|
|
|
} catch {} |
|
|
|
} |
|
|
|
|
|
|
|
async function loadRefinement() { |
|
|
|
try { |
|
|
|
const res = await fetch('/api/refinement'); |
|
|
|
if (!res.ok) return; |
|
|
|
refinementInfo = await res.json(); |
|
|
|
} catch {} |
|
|
|
} |
|
|
|
|
|
|
|
function queueConfigUpdate(partial) { |
|
|
|
if (isSyncingConfig) return; |
|
|
|
pendingConfigUpdate = { ...(pendingConfigUpdate || {}), ...partial }; |
|
|
|
@@ -827,6 +837,21 @@ function updateHeroMetrics() { |
|
|
|
healthAge.textContent = stats.last_sample_ago_ms >= 0 ? `${stats.last_sample_ago_ms} ms` : 'n/a'; |
|
|
|
healthGpu.textContent = gpuInfo.error ? `${gpuInfo.active ? 'ON' : 'OFF'} · ${gpuInfo.error}` : (gpuInfo.active ? 'ON' : (gpuInfo.available ? 'Ready' : 'N/A')); |
|
|
|
healthFps.textContent = `${renderFps.toFixed(0)} fps`; |
|
|
|
if (healthRefinePlan) { |
|
|
|
const plan = refinementInfo.plan || {}; |
|
|
|
healthRefinePlan.textContent = `${plan.selected?.length || 0}/${plan.budget || 0} · drop ${plan.dropped_by_snr || 0}/${plan.dropped_by_budget || 0}`; |
|
|
|
} |
|
|
|
if (healthRefineWindows) { |
|
|
|
const windows = refinementInfo.windows || []; |
|
|
|
if (!Array.isArray(windows) || windows.length === 0) { |
|
|
|
healthRefineWindows.textContent = 'n/a'; |
|
|
|
} else { |
|
|
|
const spans = windows.map(w => w.span_hz || 0).filter(v => v > 0); |
|
|
|
const minSpan = spans.length ? Math.min(...spans) : 0; |
|
|
|
const maxSpan = spans.length ? Math.max(...spans) : 0; |
|
|
|
healthRefineWindows.textContent = spans.length ? `${fmtHz(minSpan)}–${fmtHz(maxSpan)}` : 'n/a'; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function renderBandNavigator() { |
|
|
|
@@ -2174,6 +2199,7 @@ window.addEventListener('keydown', (ev) => { |
|
|
|
loadConfig(); |
|
|
|
loadStats(); |
|
|
|
loadGPU(); |
|
|
|
loadRefinement(); |
|
|
|
fetchEvents(true); |
|
|
|
fetchRecordings(); |
|
|
|
loadDecoders(); |
|
|
|
@@ -2181,6 +2207,7 @@ connect(); |
|
|
|
requestAnimationFrame(renderLoop); |
|
|
|
setInterval(loadStats, 1000); |
|
|
|
setInterval(loadGPU, 1000); |
|
|
|
setInterval(loadRefinement, 1500); |
|
|
|
setInterval(() => fetchEvents(false), 2000); |
|
|
|
setInterval(fetchRecordings, 5000); |
|
|
|
setInterval(loadSignals, 1500); |
|
|
|
|