Repository navigation
Joint cost-aware EV and home-battery scheduling under a site import limit #5490
Description
Feature request
Joint cost-aware scheduling of a fixed-rate EV and home battery under a site import limit
This is a request for one native Predbat plan which jointly decides when the EV
charges and when the home battery charges, holds or discharges, using household
and heating demand, PV forecasts, actual import/export prices and physical limits.
It is not a request for a second Home Assistant optimiser or a fast protective loop.
I am developing an opt-in implementation in my personal fork. This issue describes
the intended behaviour and acceptance criteria, not a claim that the feature is
complete or deployed. Diagnostic draft PR #5486 remains separate and does not
close this request.
Problem
The current Predbat-led car planner selects low-import-price windows before the
household battery optimisation. It does not jointly search EV placement, battery
preparation and whole-site import feasibility. A fixed-rate charger cannot follow
whatever PV surplus happens to remain: when enabled, its real full demand must be
accounted for, with the balance supplied by an executable combination of battery
and grid.
Avoiding expensive hours alone can miss a better overall outcome. Charging a car
with PV plus some battery now can be cheaper when later sunlight will replenish
the battery anyway. Conversely, buying cheap electricity overnight for the car
and/or home battery may preserve valuable stored energy for household demand later.
There should be no unconditional rule to fill the home battery before the EV, use
the battery at all costs, or avoid grid charging altogether.
Representative configurable example
The following is a synthetic acceptance profile, not a deployment configuration:
| Quantity | Example |
|---|---|
| Whole-site grid import ceiling | 6,000 W |
| Fixed EV charging demand | 6,770 W, on/off only |
| Home battery capacity | approximately 32 kWh |
| Home battery charge/discharge limits | 3,000 / 8,000 W |
| Minimum domestic SoC | 10% |
| EV pause/restart domestic SoC | 15% / 25% |
| EV target / departure | 100% / 07:30, subject to physical feasibility |
| Import bands | 8.1 / 11.2 / 19.1 currency cents per kWh |
| Export compensation | zero in this example, configurable elsewhere |
Grid import, battery power, inverter conversion and AC load/passthrough limits
are distinct constraints. A 6 kW import ceiling is not a 6 kW household-load
ceiling: PV and battery can supply additional load within the verified topology.
An inverter's nominal rating alone is not proof of available power at every SoC.
Use cases and expected behaviour
1. Charge on solar now, recover the home battery later
Given 5 kW usable PV, 1 kW household demand and a 6.77 kW fixed EV, a candidate
may use approximately 2.77 kW of battery support, subject to losses and limits.
If later PV can replenish the home battery after the EV finishes, compare this
with delaying the EV or buying overnight. Do not reject the daytime candidate
merely because PV alone cannot cover the EV, and do not pretend the charger
has reduced itself to the available surplus.
2. Prepare the home battery during cheap hours
When PV is insufficient, the planner may buy cheap energy for the home battery
before an EV slot. Include charging power, charging/discharging losses, SoC,
household consumption and the time available. Grid-charge preparation and EV
charging must be co-scheduled, not assumed to fit simultaneously under the cap.
Do not assume an ECO inverter supplies only the amount above the import limit;
simulate its actual battery-first/hold/charge behaviour.
3. Use the next more expensive eligible hours automatically
If the lowest-price windows cannot meet the target, include the next cheapest
eligible windows before departure, rather than reporting a shortfall merely
because cheap time ran out. Compare the full system cost, including solar and
storage opportunity cost, not only the import-price label on an EV slot.
Only a genuine absence of a physically feasible plan should remain unmet. A
bounded search must distinguish "no plan found" from a proof of impossibility.
4. Heating and household demand remain the priority
When heating or other household demand rises, re-plan the flexible EV/battery
schedule. Do not silently shed household demand, move heating without permission,
increase electrical limits or invent a reduced EV charging rate. Include actual
EV restart hysteresis and minimum switching intervals to avoid a plan the executor
will repeatedly pause.
5. Anticipate arrival without inventing a connection
An expected return time and a recent EV SoC may establish a future energy need,
even while the car is away. No EV energy may be assigned before its availability
window. Expected availability is not permission to energise an absent/unplugged
charger: actual execution needs a separate trustworthy connection/session gate.
Re-plan on delayed arrival, cancellation, stale/unknown SoC or disconnection.
6. Do not use tomorrow's sun to satisfy an earlier deadline
PV arriving after a 07:30 departure cannot count towards that departure's EV
energy. It can affect the value of energy left in the house battery afterwards.
Price changes on weekdays must be respected from the supplied tariff series.
7. Respect power and energy at every step
With no PV, a battery already at reserve, a 1.2 kW house and a fixed 6.77 kW EV,
the demand is 7.97 kW. A 6 kW import ceiling cannot be satisfied by clipping the
graph or debiting an empty battery. Move the EV or prepare energy earlier.
Preserve raw energy balance, efficiencies, charge/discharge limits and SoC bounds.
Curtailing grid-funded battery charging must not unnecessarily curtail usable PV.
8. Compare equivalent end conditions and handle forecast changes
Account for terminal stored energy or an explicit terminal target, so an emptier
battery does not masquerade as a saving. Include uncertainty/re-planning when PV
underperforms or household load increases. A safe forecast is not a guarantee
against every instantaneous unforecast load spike.
Integration and acceptance criteria
- Opt-in; disabled behaviour remains unchanged.
- Native Predbat owns the plan; existing inverter mappings and one existing EV
executor remain authoritative. No competing controller or external service. - Real fixed-rate EV energy, battery losses, source accounting and terminal energy
are covered by synthetic regression tests for the use cases above. - Candidate selection treats physical feasibility and the departure requirement
separately from monetary cost; no arbitrary large monetary penalty presented
as a hard constraint. - Any candidate applied to native control must match executable inverter modes,
window resolution/count and rates. Unsupported configurations must be explicit,
not silently run an idealised dispatch model against different hardware. - Python, native-kernel, cache and final HA publication paths must agree, or an
unsupported accelerated path must be explicitly disabled for the feature. - Planning is not electrical protection. Hardware protection and a verified fast
control path are still needed; a five-minute optimisation loop cannot enforce
an instantaneous whole-site ceiling by itself.
Relation to existing work
- Add configurable whole-site import diagnostics (no enforcement) #5486: truthful site-import diagnostics; retained as the first foundation,
not relabelled as joint optimisation or enforcement. - import_limit setting requirement #2449: site import modelling. This request adds the coupled EV/battery
scheduling objective and concrete fixed-rate departure/availability cases. - Consider solar export value when scheduling EV charging #5384: solar opportunity cost when choosing EV slots. The same economics
also matter with zero export compensation and limited storage. - Charge the car on forecast solar surplus #5195: solar-led charging/availability/deadlines. Its current solar path
assumes a charger that modulates to surplus; this request must also support
fixed on/off EV charging with battery/grid support, without that assumption. - [Feature Request] Prevent simultaneous EV charging and battery grid charging (Capacity Tariff optimization) #3293: concurrent EV and battery charging. A blanket ban is not required
when PV and the verified topology make concurrency feasible. - Limit grid import (capacity tariff) #1199: rolling capacity tariffs are related but remain a separate billing
feature, not interchangeable with this per-step import constraint.
The new issue is intentionally an integration-level behaviour contract linking
those pieces, not a duplicate request for another import-limit setting. No issue
above should be closed merely by publishing diagnostics or this proposal.
Activity
springfall2008 commentedon Oct 11, 2026
🤖 Automated first-pass triage — a maintainer will review this before any action is taken.
Classification: enhancement (feature request, so no priority label).
Verified against current main (v9.3.7-6-gd6985b6d) — the gap the issue describes is real:
plan_car_charging()(apps/predbat/plan.py:5969), called fromfetch_sensor_data_car_planning()(apps/predbat/fetch.py:1424, slot creation at fetch.py:1454) before the battery optimisation runs. It sorts the handed-over low-rate windows cheapest-first (car_charging_plan_smartonly reorders them) and fills tocar_charging_limitby the ready time; PV, battery SoC and any import cap never enter that search, and when the handed windows can't reach the target the plan just ends up short — there is no expansion into other windows. The battery solver then runs with the placed car slots as fixed load, so the plan's cost is car-aware, but EV placement itself is never co-searched. That is exactly the joint-scheduling gap the issue names.import_limitappears only as per-inverter discovery ratings (sunsynk.py:1605, fox.py:2614 — device-reported caps) and never as a planner setting. The shipped precedent it would mirror is the export-sideexport_limitclamp inside the per-minute prediction loop (prediction.py:664).run_prediction()dispatches to the native kernel when available (prediction.py:538), and the kernel source lives inprediction_kernel.cpp. A new constraint must be mirrored in both engines or the accelerated path disabled while the feature is on, which is what the issue asks for and which draft PR Add configurable whole-site import diagnostics (no enforcement) #5486's change list (prediction.py, prediction_kernel.py, tests) already anticipates.Not a duplicate — none of the linked pieces asks for the joint objective; each covers a subset:
import_limitmirroringexport_limitas a first cut, a reactive external-target throttle (projected 15-minute average) as follow-up, Predbat publishing state while user automations keep billing policy — and it flags the measurement gap, that a load not on the total-import reading can't be clamped.car_charging_solardoesn't exist anywhere in main, so use case 5's "solar path" describes a proposal, not shipped behaviour.import_limitscalar +predbat.best_import_limitsensor, no enforcement, no candidate ordering change) — i.e. the first stage of the Limit grid import (capacity tariff) #1199 note's staging.Shape for maintainer review: this is one umbrella request whose pieces could land in the recorded order above (cap → diagnostics → ranking cost → joint search), and the maintainer may equally decide the joint EV+battery search shouldn't live inside the 5-minute-loop planner at all — the issue's own acceptance criteria treat that loop as not-electrical-protection and leave hardware protection explicitly out of scope. Both the scope decision and where the joint search lives (car planner vs main solver) are maintainer calls on a change this wide.
Nothing further is needed for triage — as a feature request it doesn't require a debug yaml or log.
arturonaredo commentedon Oct 11, 2026
Personal-fork progress, not an installation recommendation or a claim that this issue is solved:
Published commit:
11f3d385, signature verified by GitHub.execution_enabledandenforcedremain false.calculate_plan→ solver → native replay tests; full quick suite with the native kernel required; both committed golden debug replays; pre-commit and documentation build. Four slow suites remain excluded. No change to either native prediction engine's dispatch semantics.This is a bounded approximation, not proof of a global optimum or infeasibility when no plan is found. Executable window mapping (including adjacent unequal targets), reliable real connection/session permission, and hardware validation are still unresolved. No live deployment, forced charging, hardware-limit change, or new upstream implementation PR has been made. Maintainer scope/design approval is still separate from automated triage.