From ed6bd8938753b72c7cfbbbd4cb5bb16a9cb63a01 Mon Sep 17 00:00:00 2001 From: rivengh <75251226+rivengh@users.noreply.github.com> Date: Sat, 3 Feb 2024 13:39:58 +0100 Subject: [PATCH] Battery control: hold battery while min soc not reached (#11941) --- core/loadpoint/api.go | 4 ++-- core/loadpoint/mock.go | 28 ++++++++++++++-------------- core/loadpoint_api.go | 11 ++++++----- core/site_battery.go | 2 +- core/site_battery_test.go | 29 ++++++++++++++--------------- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/core/loadpoint/api.go b/core/loadpoint/api.go index 19c967dfe..829b0b274 100644 --- a/core/loadpoint/api.go +++ b/core/loadpoint/api.go @@ -120,8 +120,8 @@ type API interface { // charge progress // - // GetPlanActive returns the active state of the planner - GetPlanActive() bool + // IsFastChargingActive indicates if fast charging with maximum power is active + IsFastChargingActive() bool // GetRemainingDuration is the estimated remaining charging duration GetRemainingDuration() time.Duration // GetRemainingEnergy is the remaining charge energy in Wh diff --git a/core/loadpoint/mock.go b/core/loadpoint/mock.go index 58ef9b271..4ba9a862a 100644 --- a/core/loadpoint/mock.go +++ b/core/loadpoint/mock.go @@ -265,20 +265,6 @@ func (mr *MockAPIMockRecorder) GetPlan(arg0, arg1 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPlan", reflect.TypeOf((*MockAPI)(nil).GetPlan), arg0, arg1) } -// GetPlanActive mocks base method. -func (m *MockAPI) GetPlanActive() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPlanActive") - ret0, _ := ret[0].(bool) - return ret0 -} - -// GetPlanActive indicates an expected call of GetPlanActive. -func (mr *MockAPIMockRecorder) GetPlanActive() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPlanActive", reflect.TypeOf((*MockAPI)(nil).GetPlanActive)) -} - // GetPlanEnergy mocks base method. func (m *MockAPI) GetPlanEnergy() (time.Time, float64) { m.ctrl.T.Helper() @@ -407,6 +393,20 @@ func (mr *MockAPIMockRecorder) HasChargeMeter() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasChargeMeter", reflect.TypeOf((*MockAPI)(nil).HasChargeMeter)) } +// IsFastChargingActive mocks base method. +func (m *MockAPI) IsFastChargingActive() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsFastChargingActive") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsFastChargingActive indicates an expected call of IsFastChargingActive. +func (mr *MockAPIMockRecorder) IsFastChargingActive() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsFastChargingActive", reflect.TypeOf((*MockAPI)(nil).IsFastChargingActive)) +} + // PublishEffectiveValues mocks base method. func (m *MockAPI) PublishEffectiveValues() { m.ctrl.T.Helper() diff --git a/core/loadpoint_api.go b/core/loadpoint_api.go index 4606eac5f..26fad3115 100644 --- a/core/loadpoint_api.go +++ b/core/loadpoint_api.go @@ -395,11 +395,12 @@ func (lp *Loadpoint) GetMaxPower() float64 { return Voltage * lp.effectiveMaxCurrent() * float64(lp.maxActivePhases()) } -// GetPlanActive returns the active state of the planner -func (lp *Loadpoint) GetPlanActive() bool { - lp.Lock() - defer lp.Unlock() - return lp.planActive +// IsFastChargingActive indicates if fast charging with maximum power is active +func (lp *Loadpoint) IsFastChargingActive() bool { + lp.RLock() + defer lp.RUnlock() + + return lp.mode == api.ModeNow || lp.planActive || lp.minSocNotReached() } // GetRemainingDuration is the estimated remaining charging duration diff --git a/core/site_battery.go b/core/site_battery.go index c0eb71f8d..c688f5473 100644 --- a/core/site_battery.go +++ b/core/site_battery.go @@ -32,7 +32,7 @@ func (site *Site) SetBatteryMode(batMode api.BatteryMode) { func (site *Site) determineBatteryMode(loadpoints []loadpoint.API, smartCostActive bool) api.BatteryMode { for _, lp := range loadpoints { - if lp.GetStatus() == api.StatusC && (smartCostActive || lp.GetMode() == api.ModeNow || lp.GetPlanActive()) { + if lp.GetStatus() == api.StatusC && (smartCostActive || lp.IsFastChargingActive()) { return api.BatteryHold } } diff --git a/core/site_battery_test.go b/core/site_battery_test.go index e2ecda525..630f46f83 100644 --- a/core/site_battery_test.go +++ b/core/site_battery_test.go @@ -15,19 +15,19 @@ func TestDetermineBatteryMode(t *testing.T) { ctrl := gomock.NewController(t) tcs := []struct { - chargeStatus api.ChargeStatus - planActive bool - expBatMode api.BatteryMode - mode api.ChargeMode + chargeStatus api.ChargeStatus + fastChargingActive bool + smartCostActive bool + expBatMode api.BatteryMode }{ - {api.StatusB, false, api.BatteryNormal, api.ModeOff}, // mode off -> bat normal - {api.StatusB, false, api.BatteryNormal, api.ModeNow}, // mode now, not charging -> bat normal - {api.StatusC, false, api.BatteryHold, api.ModeNow}, // mode now, charging -> bat hold - {api.StatusB, false, api.BatteryNormal, api.ModeMinPV}, // mode minPV, not charging -> bat normal - {api.StatusC, false, api.BatteryNormal, api.ModeMinPV}, // mode minPV, charging -> bat normal - {api.StatusB, false, api.BatteryNormal, api.ModePV}, // mode PV, not charging -> bat normal - {api.StatusC, false, api.BatteryNormal, api.ModePV}, // mode PV, charging, no planner -> bat normal - {api.StatusC, true, api.BatteryHold, api.ModePV}, // mode PV, charging, planner active -> bat hold + {api.StatusB, false, false, api.BatteryNormal}, // not charging | fast charge not active | smart cost not active -> bat normal + {api.StatusB, true, false, api.BatteryNormal}, // not charging | fast charge active | smart cost not active -> bat normal + {api.StatusC, false, false, api.BatteryNormal}, // charging | fast charge not active | smart cost not active -> bat normal + {api.StatusC, true, false, api.BatteryHold}, // charging | fast charge active | smart cost not active -> bat hold + {api.StatusB, false, true, api.BatteryNormal}, // not charging | fast charge not active | smart cost active -> bat normal + {api.StatusB, true, true, api.BatteryNormal}, // not charging | fast charge active | smart cost active -> bat normal + {api.StatusC, false, true, api.BatteryHold}, // charging | fast charge not active | smart cost active -> bat hold + {api.StatusC, true, true, api.BatteryHold}, // charging | fast charge active | smart cost active -> bat hold } log := util.NewLogger("foo") @@ -39,12 +39,11 @@ func TestDetermineBatteryMode(t *testing.T) { lp := loadpoint.NewMockAPI(ctrl) lp.EXPECT().GetStatus().Return(tc.chargeStatus).AnyTimes() - lp.EXPECT().GetMode().Return(tc.mode).AnyTimes() - lp.EXPECT().GetPlanActive().Return(tc.planActive).AnyTimes() + lp.EXPECT().IsFastChargingActive().Return(tc.fastChargingActive).AnyTimes() loadpoints := []loadpoint.API{lp} - mode := s.determineBatteryMode(loadpoints, false) + mode := s.determineBatteryMode(loadpoints, tc.smartCostActive) assert.Equal(t, tc.expBatMode, mode, tc) } }