A Home Assistant solar forecast (Forecast.Solar, Solcast or Open-Meteo
shapes) and the add-on's own hourly house use decide, before each cheap
run, whether the sun will fill each battery before the expensive hours.
Leftover solar then buys from the grid only the shortfall; Cheap hours only
skips the part the sun covers; Solar first never grid-charges. No, stale or
failed forecast: P3 option A exactly (12 digests pinned from 5a4cdc2).
Replay (16 recorded days, forecast errors from Elia's day-ahead BE solar):
year-earlier prices P4 19.15 vs P2 19.33 / option A 19.44 / old trade 18.14;
real 2026 prices P4 29.19 vs 32.26 / 32.01 / 31.40 EUR net.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
177 lines
10 KiB
HTML
177 lines
10 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Battery add-on</title>
|
||
<style>/*APP_CSS*/</style>
|
||
</head>
|
||
<body>
|
||
<header class="top">
|
||
<div class="logo" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="7" width="16" height="10" rx="2"/><path d="M21 11v2M8 10l-2 3h4l-2 3"/></svg></div>
|
||
<div class="grow">
|
||
<div class="app" data-t="app.name"></div>
|
||
<div class="pill" id="pill" aria-live="polite"><span class="dot warn"></span><span>…</span></div>
|
||
</div>
|
||
</header>
|
||
|
||
<nav class="tabs" role="tablist" id="tabs" data-t-label="tabs.label">
|
||
<button class="tab" role="tab" id="t-home" aria-controls="s-home" aria-selected="true" data-hash="home"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M3 11l9-7 9 7v9a1 1 0 0 1-1 1h-5v-6H9v6H4a1 1 0 0 1-1-1z"/></svg><span data-t="tabs.home"></span><span class="badge" id="attn-badge" hidden></span></button>
|
||
<button class="tab" role="tab" id="t-batt" aria-controls="s-batt" aria-selected="false" data-hash="batteries" tabindex="-1"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="7" width="16" height="10" rx="2"/><path d="M21 11v2"/><rect x="5.5" y="9.5" width="7" height="5" fill="currentColor" stroke="none"/></svg><span data-t="tabs.batteries"></span></button>
|
||
<button class="tab" role="tab" id="t-set" aria-controls="s-set" aria-selected="false" data-hash="settings" tabindex="-1"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M4 6h10M18 6h2M4 12h4M12 12h8M4 18h12M20 18h0"/><circle cx="16" cy="6" r="2"/><circle cx="10" cy="12" r="2"/><circle cx="18" cy="18" r="2"/></svg><span data-t="tabs.settings"></span></button>
|
||
<button class="tab" role="tab" id="t-wiz" aria-controls="s-wiz" aria-selected="false" data-hash="setup" tabindex="-1"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M14 7l3 3M5 19l9.5-9.5 3 3L8 22H5z"/><path d="M19 2v4M17 4h4"/></svg><span data-t="tabs.setup"></span></button>
|
||
</nav>
|
||
|
||
<main class="wrap">
|
||
|
||
<section class="screen" id="s-home" role="tabpanel" aria-labelledby="t-home">
|
||
<div id="home-banner"></div>
|
||
|
||
<div class="card" id="c-now">
|
||
<div class="row spread"><h2 data-t="now.name"></h2><span class="tiny muted" data-t="now.description"></span></div>
|
||
<div class="tiles">
|
||
<div class="tile"><div class="lab"><span class="sw-solar" aria-hidden="true">☀</span><span data-t="now.solar"></span></div><div class="val" id="v-solar">–</div><div class="sub" id="sub-solar"></div></div>
|
||
<div class="tile"><div class="lab"><span class="sw-house" aria-hidden="true">⌂</span><span data-t="now.house"></span></div><div class="val" id="v-house">–</div><div class="sub" id="sub-house"></div></div>
|
||
<div class="tile"><div class="lab"><span class="sw-grid" aria-hidden="true">⇅</span><span data-t="now.grid"></span></div><div class="val" id="v-grid">–</div><div class="sub" id="sub-grid"></div></div>
|
||
<div class="tile"><div class="lab"><span class="sw-batt" aria-hidden="true">▮</span><span data-t="now.batteries"></span></div><div class="val" id="v-batt">–</div><div class="sub" id="sub-batt"></div></div>
|
||
</div>
|
||
<div id="home-batts" style="margin-top:6px"></div>
|
||
</div>
|
||
|
||
<div class="card" id="c-plan">
|
||
<div class="row spread"><h2 data-t="plan.name"></h2><span class="chip tiny muted" id="verdict"></span></div>
|
||
<div class="small" id="plan-head"></div>
|
||
<div class="chart" id="chart">
|
||
<div class="bars" id="bars" role="group"></div>
|
||
<div id="lanes"></div>
|
||
<div class="nowline" id="nowline" aria-hidden="true"><span data-t="plan.now"></span></div>
|
||
<div class="axis" aria-hidden="true"><span>00:00</span><span>06:00</span><span>12:00</span><span>18:00</span><span>24:00</span></div>
|
||
</div>
|
||
<p class="tiny muted" id="no-prices" hidden data-t="plan.no_prices.description"></p>
|
||
<div class="legend" id="legend"></div>
|
||
<p class="tiny muted" style="margin:6px 0 0" data-t="plan.description"></p>
|
||
<h3 class="sr" data-t="plan.list"></h3>
|
||
<ul class="plain small" id="plan-list"></ul>
|
||
<p class="tiny muted" style="margin:8px 0 0" id="price-line"></p>
|
||
</div>
|
||
|
||
<div class="card" id="c-peak">
|
||
<div class="row spread"><h2 data-t="peak.name"></h2><span class="tiny muted" id="peak-month"></span></div>
|
||
<div class="row spread small" id="peak-figures"><span><span data-t="peak.this_month"></span>: <strong id="peak-now"></strong></span><span class="muted"><span data-t="peak.limit"></span> <span id="peak-limit"></span></span></div>
|
||
<div class="meter" id="peak-meter" role="img"><i style="width:0%"></i></div>
|
||
<div class="tiny muted" id="peak-line"></div>
|
||
</div>
|
||
|
||
<div class="card" id="c-attn">
|
||
<div class="row spread"><h2 data-t="attention.name"></h2><span class="tiny muted" id="attn-count"></span></div>
|
||
<div id="alerts"></div>
|
||
</div>
|
||
|
||
<div class="card" id="c-ctl">
|
||
<h2 data-t="control.name"></h2>
|
||
<div class="small" id="ctl-text"></div>
|
||
<div class="row" style="margin-top:10px">
|
||
<button class="btn" id="btn-ctl" type="button"></button>
|
||
<a class="btn primary" id="btn-setup" href="#setup" hidden data-t="setup_only.open"></a>
|
||
<a class="small" id="docs-link" hidden target="_top" rel="noopener" data-t="control.docs"></a>
|
||
</div>
|
||
<div class="tiny muted" id="hint" aria-live="polite" style="margin-top:8px"></div>
|
||
<details class="more">
|
||
<summary data-t="control.more"></summary>
|
||
<div class="row" style="padding-bottom:6px">
|
||
<button class="btn" id="btn-maint" type="button" data-t="control.maint_start"></button>
|
||
<button class="btn danger" id="btn-abort" type="button" data-t="control.maint_abort"></button>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
|
||
<details class="card more" id="c-details">
|
||
<summary data-t="details.name"></summary>
|
||
<table class="rows" id="rows"></table>
|
||
<h2 style="margin-top:12px" data-t="details.checks"></h2>
|
||
<ul class="checks" id="checks"></ul>
|
||
</details>
|
||
</section>
|
||
|
||
<section class="screen" id="s-batt" role="tabpanel" aria-labelledby="t-batt" hidden>
|
||
<div id="batt-banner"></div>
|
||
<div class="card" id="batt-off" hidden>
|
||
<h2 data-t="batteries.modes_off.name"></h2>
|
||
<p class="small muted" style="margin:0 0 10px" data-t="batteries.description"></p>
|
||
<a class="btn" href="#settings" data-t="batteries.settings"></a>
|
||
</div>
|
||
<div id="bcards"></div>
|
||
<p class="small muted" id="batt-solar" hidden></p>
|
||
<details class="grp" id="batt-how" hidden>
|
||
<summary><span class="grow"><strong data-t="batteries.how.name"></strong><span class="small muted gdesc" data-t="batteries.how.description"></span></span><span class="chev" aria-hidden="true">›</span></summary>
|
||
<div class="body small">
|
||
<p data-t="batteries.how.solar_first.description"></p>
|
||
<p data-t="batteries.how.leftover_solar.description"></p>
|
||
<p data-t="batteries.how.off.description"></p>
|
||
<p class="muted" data-t="batteries.how.rules.description"></p>
|
||
<p><a id="batt-docs" hidden target="_top" rel="noopener" data-t="control.docs"></a></p>
|
||
</div>
|
||
</details>
|
||
</section>
|
||
|
||
<section class="screen" id="s-set" role="tabpanel" aria-labelledby="t-set" hidden>
|
||
<div class="row spread" style="margin-bottom:6px">
|
||
<h2 style="margin:0" data-s="name"></h2>
|
||
<a class="small" href="config" id="set-classic" data-s="classic"></a>
|
||
</div>
|
||
<div class="row" style="margin-bottom:8px">
|
||
<div class="seg" role="radiogroup" id="set-view" data-s-label="view.name">
|
||
<button type="button" role="radio" aria-checked="true" data-v="simple" data-s="view.simple"></button>
|
||
<button type="button" role="radio" aria-checked="false" data-v="installer" tabindex="-1" data-s="view.installer"></button>
|
||
</div>
|
||
<span class="tiny muted grow" id="set-desc"></span>
|
||
</div>
|
||
<div id="set-banner" aria-live="polite"></div>
|
||
<div id="simple" class="simple" hidden></div>
|
||
<div id="set-body">
|
||
<input class="search" id="set-search" type="search" autocomplete="off" spellcheck="false" data-s-ph="search.description" data-s-label="search.name">
|
||
<div class="card" id="set-other" hidden><h2 data-s="other"></h2><ul class="plain small" id="set-other-list"></ul></div>
|
||
<div id="groups"><p class="small muted" data-s="loading"></p></div>
|
||
<p class="small muted" id="set-nomatch" hidden data-s="no_match.description"></p>
|
||
<p class="tiny muted" data-s="footer.description"></p>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="screen" id="s-wiz" role="tabpanel" aria-labelledby="t-wiz" hidden>
|
||
<div class="card" id="wz">
|
||
<div class="row spread"><h2 id="wz-title" style="margin:0" data-s="setup.name"></h2><span class="tiny muted" id="wz-count"></span></div>
|
||
<div class="steps" id="wz-steps" aria-hidden="true"></div>
|
||
<p class="small muted" id="wz-desc" style="margin:0 0 6px"></p>
|
||
<div id="wz-banner" aria-live="polite"></div>
|
||
<div id="wz-body"><p class="small muted" data-s="loading"></p></div>
|
||
<div class="row spread" id="wz-nav" style="margin-top:14px">
|
||
<button class="btn" id="wz-back" type="button" data-s="setup.back"></button>
|
||
<button class="btn primary" id="wz-next" type="button" data-s="setup.next"></button>
|
||
</div>
|
||
</div>
|
||
<p class="tiny muted" data-s="setup.description"></p>
|
||
</section>
|
||
</main>
|
||
|
||
<dialog id="dlg" aria-labelledby="dlg-t" aria-describedby="dlg-b">
|
||
<h2 id="dlg-t"></h2>
|
||
<p class="small" id="dlg-b"></p>
|
||
<div class="row" style="justify-content:flex-end">
|
||
<button class="btn" id="dlg-no" type="button" data-t="dialog.cancel"></button>
|
||
<button class="btn primary" id="dlg-yes" type="button"></button>
|
||
</div>
|
||
</dialog>
|
||
<div id="savebar" role="region" hidden><div class="in">
|
||
<span class="grow" id="sb-text" aria-live="polite"></span>
|
||
<button class="btn" id="sb-discard" type="button" data-s="savebar.discard"></button>
|
||
<button class="btn primary" id="sb-save" type="button" data-s="savebar.save"></button>
|
||
</div></div>
|
||
<div id="toast" role="status" aria-live="polite"></div>
|
||
<div id="tip" class="tip" aria-hidden="true"></div>
|
||
|
||
<script type="application/json" id="ui-text">/*UI_TEXT*/</script>
|
||
<script>/*APP_JS*/</script>
|
||
<script>/*SETTINGS_JS*/</script>
|
||
</body>
|
||
</html>
|