Skip to content

Add solar_hold_pct battery parameter with charging gate#70

Closed
larsxschneider wants to merge 2 commits intoevcc-io:mainfrom
larsxschneider:ls/hold
Closed

Add solar_hold_pct battery parameter with charging gate#70
larsxschneider wants to merge 2 commits intoevcc-io:mainfrom
larsxschneider:ls/hold

Conversation

@larsxschneider
Copy link
Copy Markdown

Summary

Add a solar_hold_pct parameter that limits battery charging during solar hours but still ensures a fully charged battery by sunset.

Motivation

Battery health: In summer, my battery is fully charged early in the morning and sits at 100% until the evening at high temperature. Keeping the battery at e.g. 70% during the day and only charging to 100% before sunset should improve longevity.

Grid feed-in limits (future work): The German Solarspitzengesetz (Solar Peak Act) will restrict grid feed-in during peak solar hours. By holding the battery low in the morning, peak midday solar can charge the battery instead of being curtailed. This aspect is not implemented in this PR but would be the logical next step if the maintainers agree with the general approach.

How it works

A per-timestep SoC cap curve is computed from the solar forecast:

  • During solar hours the cap is flat at solar_hold_pct * s_capacity (e.g. 50%)
  • A backward ramp raises the cap before each solar window ends, timed so the battery reaches s_max using the remaining solar surplus
  • Outside solar hours the cap is s_max (no restriction)

Enforcement uses a binary charging gate (Big-M formulation): when SoC is at or above the cap, charging is blocked; when SoC is below the cap, charging is allowed up to the cap. Discharge is never restricted, so the battery is not forced to dump energy.

Usage

solar_hold_pct (0..1) can be set per-battery in the API request or globally via the OPTIMIZER_SOLAR_HOLD_PCT environment variable. The env var default is only applied to home batteries (s_capacity set and d_max > 0), which should exclude EVs.

Commits

  1. Add documentation for MILP model, variables, and data structures -- documents the existing code (dataclasses, variable naming, penalty weights) which might be useful for other new contributors.
  2. Add solar_hold_pct battery parameter with charging gate -- the feature itself, including three test cases with real-world data.

larsxschneider and others added 2 commits April 24, 2026 23:57
Document all dataclasses (BatteryConfig, GridConfig, TimeSeriesData,
OptimizationStrategy) with field descriptions, units, and usage notes.
Add comprehensive Optimizer class docstring with variable naming
conventions, penalty variable reference, and penalty weight naming.
Document constructor parameters.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a solar_hold_pct parameter (0..1) that limits battery charging during
solar hours to preserve headroom for later solar production. A backward
ramp raises the cap before each solar window ends so the battery reaches
s_max by sunset.

Enforcement uses a binary charging gate instead of a penalty to avoid
incentivizing unnecessary discharge: when SoC >= cap, charging is blocked
but discharge remains unrestricted. When SoC < cap, charging is allowed
up to the cap value.

The parameter can be set per-battery in the API request or globally via
the OPTIMIZER_SOLAR_HOLD_PCT environment variable (applied only to home
batteries with s_capacity and d_max > 0).

Includes three test cases: basic solar hold, high initial SoC (s_initial
> s_max), and two-battery setup with car + home battery.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@andig
Copy link
Copy Markdown
Member

andig commented Apr 25, 2026

Imho this approach fundamentally violates how the optimizer should operate. Instead of giving an "keep the time while max soc applies as short as possible" it is a hardcoded "if value x then y". Unless I completely misunderstand this is nothing we want to implement.

@andig andig closed this Apr 25, 2026
@andig
Copy link
Copy Markdown
Member

andig commented Apr 25, 2026

The param descriptions are really great- but would deserve their own PR.

@larsxschneider
Copy link
Copy Markdown
Author

I'll raise a separate PR for the docs.

I tried it with a soft limit first, but this approach did run into a few edge cases. The proposed solution generated better results.

@andig
Copy link
Copy Markdown
Member

andig commented Apr 25, 2026

I still take stance that the approach is flawed. The whole purpose of the optimizer ist to not have fixed, pre-defined limits. If those are needed we can put them into evcc.

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.

2 participants