feat: updates to 0.8.0 - initial write functions

This commit is contained in:
2026-04-07 02:09:29 -04:00
parent c2ab94f20c
commit bcc044655a
6 changed files with 1083 additions and 21 deletions
+51 -11
View File
@@ -240,6 +240,7 @@
let charts = {};
let lastData = null;
let unitInfo = null;
let geoRange = 10.0; // in/s full-scale for geo channels; updated on connect
let eventList = []; // populated from /device/events after connect
let currentEventIndex = 0;
@@ -277,6 +278,7 @@
throw new Error(err.detail || resp.statusText);
}
unitInfo = await resp.json();
geoRange = unitInfo.compliance_config?.max_range_geo ?? 10.0;
} catch (e) {
setStatus(`Error: ${e.message}`, 'error');
btn.disabled = false;
@@ -441,19 +443,48 @@
Object.values(charts).forEach(c => c.destroy());
charts = {};
// Mic peak PSI from 0C waveform record — used to scale raw mic counts
const micPeakPsi = data.peak_values?.micl_psi ?? null;
const DBL_REF_PSI = 2.9e-9; // 20 µPa in psi
for (const [ch, color] of Object.entries(CHANNEL_COLORS)) {
const samples = channels[ch];
if (!samples || samples.length === 0) continue;
// Convert raw ADC counts to physical units
const isGeo = ch !== 'Mic';
let plotSamples, peakLabel, yUnit, tooltipFmt, tickFmt;
if (isGeo) {
// Geo channels: counts × (range / 32767) → in/s
const scale = geoRange / 32767;
plotSamples = samples.map(c => c * scale);
const peakIns = Math.max(...plotSamples.map(Math.abs));
peakLabel = `${peakIns.toFixed(5)} in/s`;
yUnit = 'in/s';
tooltipFmt = v => `${ch}: ${v.toFixed(5)} in/s`;
tickFmt = v => v.toFixed(4);
} else {
// Mic: derive psi/count scale from the 0C peak value, display as psi; show dBL in header
const peakCounts = Math.max(...samples.map(Math.abs));
const micScale = (micPeakPsi !== null && peakCounts > 0)
? Math.abs(micPeakPsi) / peakCounts
: 1.0;
plotSamples = samples.map(c => c * micScale);
const peakPsi = Math.max(...plotSamples.map(Math.abs));
const peakDbl = peakPsi > 0 ? 20 * Math.log10(peakPsi / DBL_REF_PSI) : -Infinity;
peakLabel = `${peakDbl.toFixed(1)} dBL (${peakPsi.toExponential(3)} psi)`;
yUnit = 'psi';
tooltipFmt = v => `${ch}: ${v.toExponential(3)} psi`;
tickFmt = v => v.toExponential(1);
}
const wrap = document.createElement('div');
wrap.className = 'chart-wrap';
const lbl = document.createElement('div');
lbl.className = `chart-label ch-${ch.toLowerCase()}`;
// Compute peak for label
const peak = Math.max(...samples.map(Math.abs));
lbl.textContent = `${ch} — peak ${peak.toLocaleString()} counts`;
lbl.textContent = `${ch} — peak ${peakLabel}`;
wrap.appendChild(lbl);
const canvasWrap = document.createElement('div');
@@ -466,11 +497,11 @@
// Downsample for rendering if very long (keep chart responsive)
const MAX_POINTS = 4000;
let renderTimes = times;
let renderData = samples;
if (samples.length > MAX_POINTS) {
const step = Math.ceil(samples.length / MAX_POINTS);
let renderData = plotSamples;
if (plotSamples.length > MAX_POINTS) {
const step = Math.ceil(plotSamples.length / MAX_POINTS);
renderTimes = times.filter((_, i) => i % step === 0);
renderData = samples.filter((_, i) => i % step === 0);
renderData = plotSamples.filter((_, i) => i % step === 0);
}
const chart = new Chart(canvas, {
@@ -496,10 +527,9 @@
intersect: false,
callbacks: {
title: items => `t = ${items[0].label} ms`,
label: item => `${ch}: ${item.raw.toLocaleString()} counts`,
label: item => tooltipFmt(item.raw),
},
},
// Trigger line annotation (drawn manually via afterDraw)
},
scales: {
x: {
@@ -513,8 +543,18 @@
grid: { color: '#21262d' },
},
y: {
ticks: { color: '#484f58', maxTicksLimit: 5 },
ticks: {
color: '#484f58',
maxTicksLimit: 5,
callback: v => tickFmt(v),
},
grid: { color: '#21262d' },
title: {
display: true,
text: yUnit,
color: '#484f58',
font: { size: 10 },
},
},
},
},