fix: enforce minimum charge power in charge-demand slots#91
Conversation
The semi-continuous charge constraint (c is 0 or >= c_min) was only applied in slots without a charge demand. In demand slots (p_demand[t] > 0) only the demand constraints ran, so the solver could return any power in (0, c_min) - e.g. ~950 W for a charger whose real minimum is far higher (evcc-io/evcc#31894). Apply the semi-continuous bound in every time step, independent of demand.
|
@ekkea could you kindly check? |
Parallel planned sessions under load management must each be granted a whole effectiveMinPower chunk (charger runs >= min or off). At most floor(circuitBudget/effectiveMinPower) sessions fit a slot; the rest shift. Same semi-continuous rule as evcc-io/optimizer#91.
|
Will do. |
|
This will work in most cases, however, there is a corner case why the lines 458 - 477 exist: If charging gets close to The actual bugs seems to sit in line 463 ( |
|
Let me know if you want me to fix and test this, I can take some time tomorrow night. |
|
Ran both points against the solver. Split result: the 1.
|
That would be great- see Claude's comment above. I guess a test case for the corner cases would also be great. |
|
running out of time here. I will raise another PR as I cannot commit to this one. It will not be ready, still needing a tweak. |
|
see PR #95 - not ready for merging! |
Problem
The MILP already models minimum charge power as a semi-continuous variable: charge energy
cis either0or>= c_minvia the binaryz_c. But that constraint was only applied in time steps without a charge demand:So in exactly the slots where a loadpoint is actively charging (
p_demand[t] > 0),cwas free to take any value in(0, c_min). That produces physically impossible schedules — e.g. ~950 W for a wallbox whose real minimum is ~1.4 kW+ (evcc-io/evcc#31894).Fix
Apply the semi-continuous bound in every time step for
c_min > 0batteries, independent of the demand branch. Demand constraints and the min-charge bound now coexist: the solver still tries to meetp_demand, but can only do so with0or>= c_min.Test
tests/test_semicontinuous.pyrequests a500 Whdemand in a slot whilec_min = 1400 W, with charging strictly costly (no solar, priced grid,p_a=0) so the solver is forced to the cheapest feasible power.500 W(sub-minimum) → test fails>= c_minor0→ test passesFull suite: 15 passed.
🤖 Generated with Claude Code