cockpit: battery/power card; van-battery publishes thresholds in state
New "Battery / Power" card shows mains vs battery, charge % with a severity- colored bar (only bites while on battery), the last alert level, and the configured warn/shutdown thresholds. van-battery now includes warn_levels + shutdown_level in /run/van-battery/state.json so the card stays self-describing instead of hardcoding the numbers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
52e948654e
commit
473a75c729
@@ -97,6 +97,45 @@ function renderThermal(th) {
|
||||
el.innerHTML = html;
|
||||
}
|
||||
|
||||
/* ---------- Battery / power source (van-battery daemon state) ---------- */
|
||||
|
||||
async function readBattery() {
|
||||
try {
|
||||
return JSON.parse(await run(["cat", "/run/van-battery/state.json"]));
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function renderBattery(b) {
|
||||
const el = document.getElementById("battery");
|
||||
if (!b || b.capacity == null) {
|
||||
el.innerHTML = `<p class="muted">van-battery daemon not running (no state file).</p>`;
|
||||
return;
|
||||
}
|
||||
const cap = b.capacity;
|
||||
const shut = b.shutdown_level != null ? b.shutdown_level : 10;
|
||||
const warns = b.warn_levels || [];
|
||||
const lowest = warns.length ? Math.min.apply(null, warns) : 25;
|
||||
|
||||
// Charge severity only bites while on battery; on mains it's just charging/full.
|
||||
let lvl = "ok";
|
||||
if (b.on_battery) lvl = cap <= shut ? "crit" : cap <= lowest ? "warn" : "ok";
|
||||
const pillClass = { ok: "ok", warn: "warn", crit: "bad" }[lvl];
|
||||
|
||||
const src = b.on_battery
|
||||
? `<span class="pill warn">on battery</span>`
|
||||
: `<span class="pill ok">on mains</span>`;
|
||||
|
||||
let html = `<p>Power: ${src} Charge: <span class="pill ${pillClass}">${esc(cap)}%</span></p>`;
|
||||
html += `<div class="bar"><div class="bar-fill ${lvl}" style="width:${Math.max(0, Math.min(100, cap))}%"></div></div>`;
|
||||
if (b.on_battery && b.alerted_below != null)
|
||||
html += `<p class="muted">Low-battery alert sent at ${esc(b.alerted_below)}%.</p>`;
|
||||
html += `<p class="muted">On battery: alerts at ${esc(warns.join("/"))}%, auto-shutdown at ${esc(shut)}%.` +
|
||||
` Alerts: <code>journalctl -u van-battery</code></p>`;
|
||||
el.innerHTML = html;
|
||||
}
|
||||
|
||||
/* ---------- WAN failover (van-failover daemon state) ---------- */
|
||||
|
||||
async function readFailover() {
|
||||
@@ -225,9 +264,10 @@ async function restartAP() {
|
||||
|
||||
async function refresh() {
|
||||
try {
|
||||
const [ap, th, fo, wan] = await Promise.all([readAP(), readThermal(), readFailover(), readWAN()]);
|
||||
const [ap, th, bat, fo, wan] = await Promise.all([readAP(), readThermal(), readBattery(), readFailover(), readWAN()]);
|
||||
renderAP(ap);
|
||||
renderThermal(th);
|
||||
renderBattery(bat);
|
||||
renderFailover(fo);
|
||||
renderWAN(wan);
|
||||
document.getElementById("updated").textContent = "updated " + new Date().toLocaleTimeString();
|
||||
|
||||
Reference in New Issue
Block a user