|
@@ -1457,13 +1457,20 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
function renderCoreCard(core) {
|
|
function renderCoreCard(core) {
|
|
|
- const batteryPct = pctRange(core.battery_mv, 3000, 4200);
|
|
|
|
|
|
|
+ const batteryMin = Number.isFinite(core.battery_min_mv) ? core.battery_min_mv : 3000;
|
|
|
|
|
+ const batteryMax = Number.isFinite(core.battery_max_mv) ? core.battery_max_mv : 4200;
|
|
|
|
|
+ const batteryPct = Number.isFinite(core.battery_display_pct)
|
|
|
|
|
+ ? clamp(core.battery_display_pct, 0, 100)
|
|
|
|
|
+ : pctRange(core.battery_mv, batteryMin, batteryMax);
|
|
|
const queuePct = pctRange(core.queue_len, 0, 12);
|
|
const queuePct = pctRange(core.queue_len, 0, 12);
|
|
|
const errorsPct = core.errors > 0 ? 100 : 0;
|
|
const errorsPct = core.errors > 0 ? 100 : 0;
|
|
|
|
|
+ const batteryDetail = batteryMin < batteryMax
|
|
|
|
|
+ ? (core.battery_mv || 0) + " mV (" + batteryMin + "-" + batteryMax + " mV)"
|
|
|
|
|
+ : (core.battery_mv || 0) + " mV";
|
|
|
return `<section class="hud-card">
|
|
return `<section class="hud-card">
|
|
|
<h3>Core</h3>
|
|
<h3>Core</h3>
|
|
|
<div class="core-grid">
|
|
<div class="core-grid">
|
|
|
- ${renderMeter("Battery", Math.round(batteryPct) + "%", batteryPct, (core.battery_mv || 0) + " mV", false)}
|
|
|
|
|
|
|
+ ${renderMeter("Battery", Math.round(batteryPct) + "%", batteryPct, batteryDetail, false)}
|
|
|
${renderMeter("Queue", String(core.queue_len ?? 0), queuePct, "outbound packets", true)}
|
|
${renderMeter("Queue", String(core.queue_len ?? 0), queuePct, "outbound packets", true)}
|
|
|
${renderMeter("Errors", String(core.errors ?? 0), errorsPct, "sticky error flags", true)}
|
|
${renderMeter("Errors", String(core.errors ?? 0), errorsPct, "sticky error flags", true)}
|
|
|
</div>
|
|
</div>
|
|
@@ -1798,6 +1805,10 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
|
|
return baseColor || "#2f8f4e";
|
|
return baseColor || "#2f8f4e";
|
|
|
}
|
|
}
|
|
|
function sparkValueRange(key, values) {
|
|
function sparkValueRange(key, values) {
|
|
|
|
|
+ if (key === "packets" || key === "gps_satellites") {
|
|
|
|
|
+ const maxValue = Math.max(1, ...values);
|
|
|
|
|
+ return { min:0, max:maxValue };
|
|
|
|
|
+ }
|
|
|
if (key === "signal") {
|
|
if (key === "signal") {
|
|
|
return { min:(-125 * 4), max:(-30 * 4) };
|
|
return { min:(-125 * 4), max:(-30 * 4) };
|
|
|
}
|
|
}
|
|
@@ -1881,21 +1892,25 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
|
|
ctx.lineTo(plotRight, y);
|
|
ctx.lineTo(plotRight, y);
|
|
|
ctx.stroke();
|
|
ctx.stroke();
|
|
|
});
|
|
});
|
|
|
|
|
+ const slotWidth = (plotRight - plotLeft) / Math.max(points.length, 1);
|
|
|
const coords = points.map((point, index) => ({
|
|
const coords = points.map((point, index) => ({
|
|
|
- x: (index / Math.max(1, points.length - 1)) * (plotRight - plotLeft) + plotLeft,
|
|
|
|
|
|
|
+ x: (key === "packets" || key === "gps_satellites")
|
|
|
|
|
+ ? (plotLeft + (slotWidth * index) + (slotWidth / 2))
|
|
|
|
|
+ : ((index / Math.max(1, points.length - 1)) * (plotRight - plotLeft) + plotLeft),
|
|
|
y: scaleY(point[1])
|
|
y: scaleY(point[1])
|
|
|
}));
|
|
}));
|
|
|
const strokeColor = sparkStrokeColor(key, points);
|
|
const strokeColor = sparkStrokeColor(key, points);
|
|
|
if (key === "packets" || key === "gps_satellites") {
|
|
if (key === "packets" || key === "gps_satellites") {
|
|
|
- const slotWidth = (plotRight - plotLeft) / Math.max(points.length, 1);
|
|
|
|
|
const barWidth = Math.max(3, Math.min(18, slotWidth * 0.68));
|
|
const barWidth = Math.max(3, Math.min(18, slotWidth * 0.68));
|
|
|
const hoverColor = sparkHoverColor(key, strokeColor);
|
|
const hoverColor = sparkHoverColor(key, strokeColor);
|
|
|
coords.forEach((point, index) => {
|
|
coords.forEach((point, index) => {
|
|
|
- const left = clamp(point.x - (barWidth / 2), plotLeft, plotRight - barWidth);
|
|
|
|
|
|
|
+ const left = plotLeft + (slotWidth * index) + ((slotWidth - barWidth) / 2);
|
|
|
const top = point.y;
|
|
const top = point.y;
|
|
|
- const barHeight = Math.max(1, plotBottom - top);
|
|
|
|
|
|
|
+ const barHeight = Math.max(0, plotBottom - top);
|
|
|
ctx.fillStyle = Number.isInteger(hoverIndex) && hoverIndex === index ? hoverColor : strokeColor;
|
|
ctx.fillStyle = Number.isInteger(hoverIndex) && hoverIndex === index ? hoverColor : strokeColor;
|
|
|
- ctx.fillRect(left, top, barWidth, barHeight);
|
|
|
|
|
|
|
+ if (barHeight > 0) {
|
|
|
|
|
+ ctx.fillRect(left, top, barWidth, barHeight);
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|