Skip to content

Add opportunistic solar (sun-following) car charging model#4125

Open
tieskuh wants to merge 1 commit into
springfall2008:mainfrom
tieskuh:feature/car-charging-solar-diversion
Open

Add opportunistic solar (sun-following) car charging model#4125
tieskuh wants to merge 1 commit into
springfall2008:mainfrom
tieskuh:feature/car-charging-solar-diversion

Conversation

@tieskuh

@tieskuh tieskuh commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in, per-car model for opportunistic solar charging — where an external charger or app (EVCC, Ohme Solar Boost, a PV diverter, …) charges the car from solar surplus. Predbat reflects the diverted energy in its forecast so the home-battery prediction stays accurate on sunny days, without planning or controlling any car charging itself. Default off, so no behaviour change unless enabled.

Addresses #632, helps the forecast side of #3820, and relates to discussion #3785 (Predbat + EVCC).

The problem

When you charge the car opportunistically from solar via an external app, there is no clean way to tell Predbat about it:

  • car_charging_now / car_charging_planned both schedule grid/low-rate slots toward a target — there is no "solar surplus only" variant.
  • iBoost models exactly the right behaviour (solar diversion), but is scaled to an immersion heater: iboost_max_power is capped at 3.5 kW and iboost_max_energy at 30 kWh/day, while car charging runs to 7–11 kW.

So as soon as the car charges from solar, Predbat's home-battery forecast is too optimistic (it does not see the daytime surplus going to the car), and it may plan night-time grid slots the external app never executes.

What it does

A new per-car flag car_charging_solar. When enabled:

  • No grid/low-rate slots are planned for that car (unless a departure plan is active — see below).
  • In the forecast, the car takes the PV surplus left after the house load is served, off the top before the home battery/export, so the home battery SoC and export are lower on sunny days and the modelled car SoC rises toward its limit.
  • The diversion is bounded by: the available surplus, a min/max power band, an optional discrete charge-power step (real chargers only switch in whole 1 A current steps), the remaining capacity up to a solar SoC limit (independent of the grid plan target), and a home-battery priority SoC threshold (mirrors EVCC prioritySoc).

It generalises the existing iBoost solar diverter to the car loadpoint, without the iBoost power cap. Modelling only — Predbat never sends commands to the car; the external app stays in control.

Alongside a departure plan

If a departure plan is also set (car_charging_planned active), the normal planner still runs to guarantee the departure target, and the solar diversion is modelled on top. The solar SoC limit and the plan target are independent, so e.g. solar can charge to 60% opportunistically while a plan guarantees 80% by departure (or the reverse). Solar is applied before the planned grid charging each step, so free solar is used first and the grid only covers the remainder.

New configuration (per car unless noted)

Setting Purpose
car_charging_solar Turn the model on and suppress grid scheduling for that car
car_charging_plugged Optional plugged-in sensor over the forecast horizon (falls back to car_charging_now)
car_charging_solar_max_power Max diversion power (kW); defaults to car_charging_rate, uncapped for 3-phase
car_charging_solar_min_power Min power before the charger starts diverting
car_charging_solar_power_step Optional discrete charge-power step (kW); models 1 A current steps
car_charging_solar_limit Solar SoC limit (%), independent of the grid plan target; defaults to car_charging_limit
input_number.predbat_car_charging_solar_min_soc Home-battery priority threshold (%)

Everything defaults to off / existing behaviour, so an unset config is bit-for-bit identical to before.

Plan view

Solar diverted to the car shows green in the car column (vs yellow for planned grid charging), in both the HTML plan and the JSON/client-rendered plan.

Testing

10 new model scenarios in test_model.py (flag-off baseline, diversion, night = no diversion, min-SoC / min-power gating, capacity cap, house-load subtraction, discrete power step, solar-limit-vs-plan-target split, solar-before-grid ordering). All pass; with the flag off the suite is unchanged.

Docs

New "Opportunistic solar (sun-following) charging" section in docs/car-charging.md, plus the new args in docs/apps-yaml.md.

Feedback welcome

This is my first larger feature for Predbat, so I would really value your view on the approach before this is considered for merge — in particular:

  • Does the modelling-only scope (Predbat reflects the diversion in the forecast but never commands the car) fit how you would want this handled?
  • Is the apps.yaml-only config surface right, or would you prefer per-car HA entities/switches for some of these (e.g. car_charging_solar)?
  • Anything you would want changed before merging?

Very happy to adjust — thanks for taking a look.

Models PV diverted to the car by an external charger or app (EVCC, Ohme Solar
Boost, a PV diverter, ...) so the forecast accounts for it, without Predbat
planning or controlling any car charging. Default off, so no behaviour change
unless enabled.

- prediction.py: per-car solar diversion generalising the iBoost off-the-top
  solar model - takes the PV surplus (PV minus house load) before the home
  battery/export, gated by a home-battery priority SoC threshold, bounded by a
  min/max power band, optional discrete charge-power steps (1A current steps),
  and a solar SoC limit independent of the grid plan target. Solar is applied
  before any planned grid charging so free solar is used first. No 3.5kW cap.
- fetch.py / config.py: new per-car apps.yaml args (car_charging_solar,
  car_charging_plugged, car_charging_solar_max_power/_min_power/_power_step/
  _limit) plus a global car_charging_solar_min_soc input_number; grid scheduling
  is suppressed for a solar car with no active departure plan.
- output.py / plan.py / predbat.py: report the modelled diversion (green in the
  car column of both the HTML and JSON/client-rendered plan).
- tests: 10 model scenarios; with the flag off the suite is unchanged.
- docs: new car-charging.md section and apps-yaml.md args.

Modelling only - Predbat never commands the car; the external app stays in
control. Addresses springfall2008#632, helps the forecast side of springfall2008#3820, relates to springfall2008#3785.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant