fix: add debug panel for raw ADC counts and decode diagnostics

This commit is contained in:
2026-04-14 21:02:40 -04:00
parent 8d0537389d
commit 727bfed5c4
+65 -2
View File
@@ -175,6 +175,27 @@
} }
#connect-btn:hover { background: #2ea043; } #connect-btn:hover { background: #2ea043; }
#connect-btn:disabled { background: #21262d; color: #484f58; } #connect-btn:disabled { background: #21262d; color: #484f58; }
#debug-panel {
display: none;
background: #0d1117;
border-bottom: 1px solid #21262d;
padding: 6px 20px;
font-family: monospace;
font-size: 11px;
color: #6e7681;
line-height: 1.7;
}
#debug-panel.visible { display: block; }
#debug-panel .dp-row { display: flex; gap: 24px; flex-wrap: wrap; }
#debug-panel .dp-ch { color: #8b949e; }
#debug-panel .dp-ch span { color: #c9d1d9; }
#debug-panel .dp-warn { color: #e3b341; }
#debug-toggle {
background: none; border: none; color: #484f58; font-size: 11px;
cursor: pointer; padding: 0; float: right; text-decoration: underline;
}
#debug-toggle:hover { color: #8b949e; }
</style> </style>
</head> </head>
<body> <body>
@@ -193,8 +214,10 @@
</div> </div>
<button id="connect-btn" onclick="connectUnit()">Connect</button> <button id="connect-btn" onclick="connectUnit()">Connect</button>
<button id="load-btn" onclick="loadWaveform()" disabled>Load Waveform</button> <button id="load-btn" onclick="loadWaveform()" disabled>Load Waveform</button>
<label style="display:flex;align-items:center;gap:4px;color:#8b949e;font-size:12px;cursor:pointer"> <label style="display:flex;align-items:center;gap:4px;color:#8b949e;font-size:12px;cursor:pointer"
<input type="checkbox" id="force-reload" style="accent-color:#1f6feb" /> title="Re-download from device, bypassing server cache. Check this then click Load Waveform (or checking it will auto-reload if a waveform is already shown).">
<input type="checkbox" id="force-reload" style="accent-color:#1f6feb"
onchange="if(this.checked && lastData !== null) loadWaveform()" />
Force&nbsp;reload Force&nbsp;reload
</label> </label>
<button id="prev-btn" onclick="stepEvent(-1)" disabled>◀ Prev</button> <button id="prev-btn" onclick="stepEvent(-1)" disabled>◀ Prev</button>
@@ -223,6 +246,10 @@
</div> </div>
<div id="status-bar">Ready — enter device host and click Connect.</div> <div id="status-bar">Ready — enter device host and click Connect.</div>
<div id="debug-panel">
<button id="debug-toggle" onclick="document.getElementById('debug-panel').classList.remove('visible')">hide</button>
<div id="debug-content"></div>
</div>
<div id="empty-state"> <div id="empty-state">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
@@ -478,6 +505,7 @@
? 'Waveform decode returned no samples — check server logs' ? 'Waveform decode returned no samples — check server logs'
: `Record type "${recType}" — waveform decode not yet supported for this mode`; : `Record type "${recType}" — waveform decode not yet supported for this mode`;
document.getElementById('charts').style.display = 'none'; document.getElementById('charts').style.display = 'none';
document.getElementById('debug-panel').classList.remove('visible');
Object.values(charts).forEach(c => c.destroy()); Object.values(charts).forEach(c => c.destroy());
charts = {}; charts = {};
return; return;
@@ -687,6 +715,41 @@
if (chart) charts[ch] = chart; if (chart) charts[ch] = chart;
} }
// ── Debug panel: raw ADC counts + decode diagnostics ────────────────────
// Shows the first 8 decoded ADC counts per channel and whether peak values
// came from the 0C record (authoritative) or from Math.max fallback.
// Useful for diagnosing channel misalignment without touching server logs.
const dbg = document.getElementById('debug-panel');
const dbgContent = document.getElementById('debug-content');
const geoChans = ['Tran', 'Vert', 'Long'];
const rawChans = channels;
const scale = geoRange / 32767;
let dbgHtml = '<div class="dp-row">';
// per-channel first-8 raw counts
for (const ch of [...geoChans, 'Mic']) {
const raw = (rawChans[ch] || []).slice(0, 8);
if (raw.length === 0) continue;
const maxAbs = Math.max(...raw.map(Math.abs));
const p0c = peakValues0C?.[ch] ?? null;
const src = (ch !== 'Mic' && p0c !== null) ? `0C=${p0c.toFixed(4)}` : `Math.max=${(maxAbs*scale).toFixed(4)}`;
dbgHtml += `<div class="dp-ch">${ch} raw[0:8]: <span>${raw.join(', ')}</span> peak src: <span>${src}</span></div>`;
}
dbgHtml += '</div>';
// warn if peak0C was null for any geo channel
const nullPeaks = geoChans.filter(ch => (peakValues0C?.[ch] ?? null) === null);
if (nullPeaks.length > 0) {
dbgHtml += `<div class="dp-warn">⚠ peak0C null for: ${nullPeaks.join(', ')} — using Math.max fallback (check Force reload + Load Waveform)</div>`;
}
// summary line
dbgHtml += `<div>decoded=${data.samples_decoded} total=${data.total_samples} pretrig=${data.pretrig_samples} sr=${data.sample_rate} geoRange=${geoRange}</div>`;
dbgContent.innerHTML = dbgHtml;
dbg.classList.add('visible');
} }
// Auto-detect API base from wherever this page was served from // Auto-detect API base from wherever this page was served from