From a20c09eadda3c65af97f43d4695d765d53b0b6d3 Mon Sep 17 00:00:00 2001 From: Ingo <71161062+iseeberg79@users.noreply.github.com> Date: Fri, 27 Feb 2026 08:09:35 +0100 Subject: [PATCH] Loadpoint: treat planned charging as inflexible power (#27747) --- core/loadpoint_api.go | 2 +- core/loadpoint_effective_test.go | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/core/loadpoint_api.go b/core/loadpoint_api.go index 5b33979e7..6f44de9de 100644 --- a/core/loadpoint_api.go +++ b/core/loadpoint_api.go @@ -654,7 +654,7 @@ func (lp *Loadpoint) GetChargePower() float64 { func (lp *Loadpoint) GetChargePowerFlexibility(rates api.Rates) float64 { mode := lp.GetMode() if mode == api.ModeNow || !lp.charging() || lp.minSocNotReached() || - lp.smartLimitActive(lp.GetSmartCostLimit(), rates, true) { + lp.planActive || lp.smartLimitActive(lp.GetSmartCostLimit(), rates, true) { return 0 } diff --git a/core/loadpoint_effective_test.go b/core/loadpoint_effective_test.go index e852a9971..2b6dc2dd4 100644 --- a/core/loadpoint_effective_test.go +++ b/core/loadpoint_effective_test.go @@ -161,3 +161,40 @@ func TestPlanLocking(t *testing.T) { assert.Equal(t, 0, id) }) } + +func TestGetChargePowerFlexibility(t *testing.T) { + Voltage = 230 + + for _, tc := range []struct { + mode api.ChargeMode + status api.ChargeStatus + planActive bool + want float64 + }{ + // not charging → always 0 + {api.ModePV, api.StatusB, false, 0}, + // PV mode, charging, no plan → full power is flexible + {api.ModePV, api.StatusC, false, 2700}, + // PV mode, charging, plan active → not flexible + {api.ModePV, api.StatusC, true, 0}, + // MinPV mode, charging, no plan → surplus above min is flexible (230V * 6A * 1phase = 1380W) + {api.ModeMinPV, api.StatusC, false, 2700 - 1380}, + // MinPV mode, charging, plan active → not flexible + {api.ModeMinPV, api.StatusC, true, 0}, + // Now mode → never flexible, regardless of plan + {api.ModeNow, api.StatusC, false, 0}, + } { + t.Run("", func(t *testing.T) { + lp := NewLoadpoint(util.NewLogger("foo"), nil) + lp.mode = tc.mode + lp.status = tc.status + lp.chargePower = 2700 + lp.planActive = tc.planActive + // EffectiveMinPower() = 230V * 6A * 1phase = 1380W + lp.minCurrent = 6 + lp.phases = 1 + + assert.Equal(t, tc.want, lp.GetChargePowerFlexibility(nil)) + }) + } +}