Repository navigation
Releases
v1.6.2 — Refill the backup reserve where it pays most
This release plans a backup reserve refill around the price peaks in front of it, and makes the consistency checks more accurate and easier to follow (#69, thanks to @emilsundstrom83-spec for the detailed question).
When the SOC is below the backup reserve, the battery may spend nothing until the reserve is refilled. The refill went to the cheapest slot before the deadline, chosen on price alone. If that slot came after a price peak, the peak was lost: no arbitrage and no idle before the refill, only auto. This was easy to run into with a reserve raised at runtime, for example on a storm warning.
- Refill where it pays most: the planner now also tries finishing the refill earlier, in front of each slot worth more than the energy it could buy before it. It plans the whole day around each of these refills and keeps the cheapest plan. If nothing is gained, the refill stays in the cheapest slot as before (#71, #72).
- Honest savings: only the cheapest refill counts as mandatory. If the refill moves earlier, its extra cost comes off the estimated savings.
reserve_refill_cost_eurshows what the chosen refill really costs. - More accurate auto-slot checks: the checks "PV surplus doesn't reach the battery" and "battery doesn't cover the house" now sample PV and house load every minute, instead of once per refresh or slot boundary. On a variable sky the old readings could overstate the surplus or deficit and push towards a false message (#73).
- A week of check history in the diagnostics: each consistency check keeps its daily verdict for the last 7 days under
runtime.health.history. Strikes, and a good day resetting a series, are logged at info level (#70). - Docs: the BYD + Fronius Gen24 example explains the inverter's revert timeout (
InOutWRte_RvrtTms) and why the example scripts assume0(#68).
Upgrading
Nothing to configure. With a backup reserve, a refill can now show up earlier in the plan than before, together with a charge for the following peak. The minute sampling for the auto-slot checks only runs when a PV power or consumption entity is configured.
Full changelog: v1.6.1...v1.6.2
v1.6.1 — Keep a running charge when a re-plan repeats or fails its script call
This release fixes a charge slot that could be cancelled seconds after it started (#65, thanks to @emilsundstrom83-spec for the detailed report).
The charge and export scripts ran again on every re-plan, even with identical values. A re-plan often lands right at a slot boundary, for example when the price sensor updates at that moment, so the script could run twice within seconds. If the integration behind it limits how often a register can be written, the second call failed. The pilot then fell back to auto and ended the charge the first call had started.
- No repeated calls: within a slot, a charge or export script runs again only when
power_worreserve_socchanged. Every new slot still calls it, even with the same values. - A failed update no longer cancels the slot: if an update fails while the mode is already running in this slot, the mode keeps running and the next re-plan or slot boundary tries again. Until then, the battery continues with the previous values.
- The fail-safe stays: if the first call of a slot fails, the pilot still falls back to auto mode. A script that keeps failing still raises its message under Repairs.
Two calls can still come close together when the power really changes, so a script should tolerate a rate limit or skip writes that wouldn't change anything. See Control scripts.
Upgrading
Nothing to configure. If a script relied on being called again by a re-plan within a slot, it now runs only at the start of the slot and when its values change. The diagnostics download shows the new outcome failed_kept_running for an update that failed.
Full changelog: v1.6.0...v1.6.1
v1.6.0 — Report when the battery doesn't do what the plan counts on
The pilot now notices when the battery doesn't do what the plan counts on. Until now, a failed assumption caused no error: a charge script that barely charges, an idle slot that leaks or PV surplus that never reaches the battery simply let the plan and the battery drift apart. The first symptom was the bill.
Eleven read-only checks now compare the two and raise a message under Settings → Repairs:
- The pilot isn't steering: a control script keeps failing, there has been no valid plan for 12 hours, or another controller has held the battery for 24 hours.
- A sensor or setting is off: the SOC stands still while energy moves, the PV forecast for today is really a "remaining today" sensor, or the configured capacity is more than 25 % off.
- An action doesn't work: charge, idle and export slots that don't do their part, and auto slots that don't cover the house or don't take PV surplus (#58).
The checks only report; they never change a plan or a script call. Most need three days with enough energy at stake before they fire, and a good day clears the message again. Only slots the pilot really drives count, and surplus and deficit are measured, so a wrong PV forecast can't raise a message. All details are in Consistency checks. The current state of the checks is in the diagnostics download under runtime.health.
The limits are first values. If a message is wrong for your installation, please open an issue with the diagnostics attached. If it describes something you do on purpose, use Ignore on the message.
The docs also gain What an auto slot assumes and an example for a command-driven AC battery (Zendure SolarFlow 2400 AC+, thanks to @flatpackfan).
Upgrading
If you update from v1.4.0, you also get the card changes of v1.5.0: the bars and flow views and a visual polish.
Nothing to configure. New messages may appear under Repairs in the days after the update. The check for PV surplus needs the optional live PV power entity; without it, it stays off.
Full changelog: v1.5.0...v1.6.0
v1.5.0 — Two new card views and a visual polish
Two things for the dashboard card: the existing charts get a visual polish, and two new views draw the plan differently.
This release was published after v1.6.0, to complete the version history. v1.6.0 contains everything here, so there's no reason to go back to this version.
New views
view: bars: The price as one bar per slot in the colour of the planned action, which replaces the ribbon. The energy and SOC panels are as intracks.view: flow: The price as a band of one orange that darkens with the price, with the cheapest and dearest slot labeled above it and the action ribbon directly under it. PV is drawn upwards and consumption downwards around zero. The SOC runs across 0–100 %, withmin_socandmax_socas dashed lines.- EV charging: With EV charging on the plan, both views add a lane under the price with the car's kWh per slot, on a scale of its own.
barsdraws evcc's price limit as a line;flowputs a dot on every slot under it.
Polish in all views
- Areas: Fills fade from the curve to the baseline, and orange and amber no longer turn into a brown block on dark themes.
- Grid: The tinted plot boxes are gone, and the grid is a hairline in the theme's divider colour.
- Now marker: The red "now" line is replaced by a playhead, a pointer above the action ribbon with a hairline through the panels.
- Hover: Hovering puts a dot on every curve, and the tooltip opens each series row with its colour.
- Price labels: The cheapest slot is now labeled next to the most expensive one.
Upgrading
Nothing to configure. To try a new view, set view: bars or view: flow on the card.
Full changelog: v1.4.0...v1.5.0
v1.4.0 — Hourly PV curve from Energy-dashboard forecasts
Until now, the daily PV forecast was spread over the daylight hours as an even, symmetric curve. That misplaces much of the yield of east- or west-facing arrays, and of days whose clouds clear or build up during the day. For an east roof, the planner expected an afternoon yield that never came.
Forecast integrations that feed the Energy dashboard (Forecast.Solar, Open-Meteo Solar Forecast, Solcast, Helios and others) already know the hourly shape of the day. The PV step now has an optional Hourly forecast field: pick one config entry per roof face, and their hourly curves are added up and used slot by slot. The card's PV curve follows automatically.
- Fallback, never a missing roof. If one selected entry delivers no curve, the whole cycle plans with the daily sensors and the log says so once. Slots beyond the end of the shortest curve also use the daily sensors, so keep them configured.
- Startup. Forecast integrations often load after this one. While Home Assistant is starting, a missing curve is not reported; the plan is redone once startup has finished.
- Forecast.Solar stamps each value with the end of its hour, other integrations with the start. Both are read correctly.
- Local hour of day. A price source that stamps its slots in UTC no longer shifts the PV curve and the consumption profile by the UTC offset.
- The diagnostics download shows under
inputs.pv_hourlywhich entries were used, which failed, and how many slots came from the curve.
The docs now also point out two common pitfalls with the daily sensors. Enter the forecast for the whole day, never "remaining today". Helios Forecast numbers its days from today: energy_day_1 is today, energy_day_2 is tomorrow.
Upgrading
Nothing changes on its own: existing installations keep planning exactly as before. To use the hourly curve, open Settings → Devices & services → Smart Battery Pilot → Configure → PV forecast and pick your forecast entries under Hourly forecast, then Apply. A new setup pre-selects the entries your Energy dashboard already uses.
Full changelog: v1.3.1...v1.4.0
v1.3.1 — README screenshots render in HACS
The README screenshots were broken in the HACS frontend: it does not support <picture> and does not resolve relative image paths. The screenshots now use plain <img> tags with absolute URLs, so they show up in HACS as well as on GitHub.
No functional changes to the integration or the card.
Upgrading
Nothing to do. Update through HACS as usual; the README in HACS refreshes with the new release.
Full changelog: v1.3.0...v1.3.1
v1.3.0 — Your currency, and export at the best peak
This release brings two changes: prices are counted in your Home Assistant currency, and export mode gives stored energy to the most valuable peak.
Prices in your currency (#50, #52)
Until now, prices were passed through unconverted, but everything around them assumed euros: sensor units, config-flow labels and limits, the default spread and feed-in tariff, the plausibility bound, and the card's price axis. A price curve in SEK/kWh was planned correctly but labelled EUR, got defaults about ten times too small, and a price spike above 10 SEK/kWh made the pilot refuse to plan.
The currency now comes from Home Assistant's own setting. Price and savings sensors carry that unit, the config and options flows label and bound the price fields in it, and a new entry starts with a spread and feed-in tariff sized for it. The plausibility bound and evcc's limit tolerance scale with it as well. If your price entity declares a different currency than Home Assistant, planning carries on and the mismatch is shown in the price step of the flow, as a repair issue under Settings → Repairs, and in the log. The card follows the plan's currency.
Export mode: the best peak gets the energy (#49, #51)
In export mode the optimizer used to assign self-consumption for every slot before it looked at export at all. A cheap night slot could therefore spend stored energy that an evening price peak would have sold for far more, and on some days the plan exported nothing. In synthetic winter scenarios this left 1.7–2.2 EUR per day on the table compared with an exact optimum of the same model.
Covering demand and exporting now compete for stored energy in one list, ordered by value. Covering demand is worth the import price, exporting is worth the sell price minus your spread. The spread discount means a slot's demand stays covered unless selling the energy elsewhere clearly pays more.
Self-consumption mode plans exactly as before.
Upgrading
Update through HACS and restart Home Assistant.
- Export mode: plans now look different. The battery may be held (
idle) for a few hours ahead of a price peak, then sell for several slots in a row at full discharge power, down to the backup reserve or min SOC. After the peak, the house is supplied from the grid when that is cheaper than the energy was worth at the peak. Your export script must keep serving the house while it discharges into the grid; this matters more now that export runs can last several hours. If your inverter cannot do both, switch to self-consumption mode. To make export more selective, raise the spread threshold. - Home Assistant currency EUR: no visible change from the currency work.
- Home Assistant currency other than EUR: the price and savings sensors change their unit from EUR to your currency. Home Assistant may show a one-time repair about a changed statistics unit for these sensors; the old unit was wrong, so accept the new one. Stored values for price offset, feed-in tariff and spread are not changed (only new entries get scaled defaults), so review them once in the options. A later change of Home Assistant's currency takes effect after reloading the integration.
Entity IDs, unique IDs and attribute names stay the same, so history, statistics and templates carry on.
Full changelog: v1.2.5...v1.3.0
v1.2.5
Fix: the card is now registered as a Lovelace resource (storage mode) instead of only via extra_js_url. This avoids a race with the scoped custom element registry polyfill that made the card intermittently missing (#47, home-assistant/frontend#53890).
YAML dashboards (resource_mode: yaml): the resource list is read-only, add /smart_battery_pilot/smart-battery-pilot-card.js as a module resource manually (see README).
v1.2.4 — The documentation gets its own pages
The documentation now has its own pages on the project website: https://cygnusb.github.io/ha-smart-battery-pilot/docs/
They are built from the same Markdown files you find in docs/ on GitHub, and every change to them is published automatically. On the website you get search, navigation, a table of contents for each page and a dark mode, in the same look as the project page. Links to missing pages or anchors are now caught in CI before they reach the site.
The "Documentation" link on the integration's page in Home Assistant, the README and the project page now lead to these pages.
This release does not change how the integration plans or controls your battery.
Upgrading
Nothing to do: update through HACS and restart Home Assistant. The Documentation link in Settings → Devices & services now opens the new pages.
Full changelog: v1.2.3...v1.2.4
v1.2.3 — The card says how the charger stands
The card always shows whether evcc is being read. Until now, a card with evcc as its source looked exactly like one without whenever nothing was planned for the car, for example with the car full or unplugged. The status line now says how the charger stands:
EV: 100 % · no charging planned: a car is plugged in, at that SOC, and evcc has nothing to charge.EV: not plugged inEV: evcc not reachable
When evcc plans a session, the status line shows that session, as before.
The plan sensor carries the data as ev_status and ev_loadpoints: connected, charging, mode, SOC and limit for each loadpoint, without vehicle or loadpoint names. Both stay out of the recorder.
Upgrading
Nothing to configure. Reload the card (browser cache) after the update.
Full changelog: v1.2.2...v1.2.3