Replace current precendence with min/max logic (#11311)
This commit is contained in:
parent
32dc8384b2
commit
cf597421d3
5 changed files with 110 additions and 13 deletions
|
|
@ -9,7 +9,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
//go:generate mockgen -package api -destination mock.go github.com/evcc-io/evcc/api Charger,ChargeState,PhaseSwitcher,Identifier,Meter,MeterEnergy,Vehicle,ChargeRater,Battery,Tariff,BatteryController
|
||||
//go:generate mockgen -package api -destination mock.go github.com/evcc-io/evcc/api Charger,ChargeState,CurrentLimiter,PhaseSwitcher,Identifier,Meter,MeterEnergy,Vehicle,ChargeRater,Battery,Tariff,BatteryController
|
||||
|
||||
// ChargeMode is the charge operation mode. Valid values are off, now, minpv and pv
|
||||
type ChargeMode string
|
||||
|
|
|
|||
41
api/mock.go
41
api/mock.go
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/evcc-io/evcc/api (interfaces: Charger,ChargeState,PhaseSwitcher,Identifier,Meter,MeterEnergy,Vehicle,ChargeRater,Battery,Tariff,BatteryController)
|
||||
// Source: github.com/evcc-io/evcc/api (interfaces: Charger,ChargeState,CurrentLimiter,PhaseSwitcher,Identifier,Meter,MeterEnergy,Vehicle,ChargeRater,Battery,Tariff,BatteryController)
|
||||
|
||||
// Package api is a generated GoMock package.
|
||||
package api
|
||||
|
|
@ -129,6 +129,45 @@ func (mr *MockChargeStateMockRecorder) Status() *gomock.Call {
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockChargeState)(nil).Status))
|
||||
}
|
||||
|
||||
// MockCurrentLimiter is a mock of CurrentLimiter interface.
|
||||
type MockCurrentLimiter struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockCurrentLimiterMockRecorder
|
||||
}
|
||||
|
||||
// MockCurrentLimiterMockRecorder is the mock recorder for MockCurrentLimiter.
|
||||
type MockCurrentLimiterMockRecorder struct {
|
||||
mock *MockCurrentLimiter
|
||||
}
|
||||
|
||||
// NewMockCurrentLimiter creates a new mock instance.
|
||||
func NewMockCurrentLimiter(ctrl *gomock.Controller) *MockCurrentLimiter {
|
||||
mock := &MockCurrentLimiter{ctrl: ctrl}
|
||||
mock.recorder = &MockCurrentLimiterMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockCurrentLimiter) EXPECT() *MockCurrentLimiterMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetMinMaxCurrent mocks base method.
|
||||
func (m *MockCurrentLimiter) GetMinMaxCurrent() (float64, float64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMinMaxCurrent")
|
||||
ret0, _ := ret[0].(float64)
|
||||
ret1, _ := ret[1].(float64)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// GetMinMaxCurrent indicates an expected call of GetMinMaxCurrent.
|
||||
func (mr *MockCurrentLimiterMockRecorder) GetMinMaxCurrent() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMinMaxCurrent", reflect.TypeOf((*MockCurrentLimiter)(nil).GetMinMaxCurrent))
|
||||
}
|
||||
|
||||
// MockPhaseSwitcher is a mock of PhaseSwitcher interface.
|
||||
type MockPhaseSwitcher struct {
|
||||
ctrl *gomock.Controller
|
||||
|
|
|
|||
|
|
@ -60,38 +60,46 @@ func (lp *Loadpoint) SocBasedPlanning() bool {
|
|||
|
||||
// effectiveMinCurrent returns the effective min current
|
||||
func (lp *Loadpoint) effectiveMinCurrent() float64 {
|
||||
minCurrent := lp.GetMinCurrent()
|
||||
|
||||
if v := lp.GetVehicle(); v != nil {
|
||||
if res, ok := v.OnIdentified().GetMinCurrent(); ok {
|
||||
return res
|
||||
minCurrent = max(minCurrent, res)
|
||||
}
|
||||
}
|
||||
|
||||
if c, ok := lp.charger.(api.CurrentLimiter); ok {
|
||||
if res, _, err := c.GetMinMaxCurrent(); err == nil {
|
||||
lp.publish(keys.EffectiveMinCurrent, res)
|
||||
return res
|
||||
if res > 0 && res < minCurrent {
|
||||
minCurrent = res
|
||||
} else {
|
||||
minCurrent = max(minCurrent, res)
|
||||
}
|
||||
lp.publish(keys.EffectiveMinCurrent, minCurrent)
|
||||
}
|
||||
}
|
||||
|
||||
return lp.GetMinCurrent()
|
||||
return minCurrent
|
||||
}
|
||||
|
||||
// effectiveMaxCurrent returns the effective max current
|
||||
func (lp *Loadpoint) effectiveMaxCurrent() float64 {
|
||||
maxCurrent := lp.GetMaxCurrent()
|
||||
|
||||
if v := lp.GetVehicle(); v != nil {
|
||||
if res, ok := v.OnIdentified().GetMaxCurrent(); ok {
|
||||
return res
|
||||
maxCurrent = min(maxCurrent, res)
|
||||
}
|
||||
}
|
||||
|
||||
if c, ok := lp.charger.(api.CurrentLimiter); ok {
|
||||
if _, res, err := c.GetMinMaxCurrent(); err == nil {
|
||||
lp.publish(keys.EffectiveMaxCurrent, res)
|
||||
return res
|
||||
maxCurrent = min(maxCurrent, res)
|
||||
lp.publish(keys.EffectiveMaxCurrent, maxCurrent)
|
||||
}
|
||||
}
|
||||
|
||||
return lp.GetMaxCurrent()
|
||||
return maxCurrent
|
||||
}
|
||||
|
||||
// effectiveLimitSoc returns the effective session limit soc
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ package core
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
@ -11,3 +13,54 @@ func TestEffectiveLimitSoc(t *testing.T) {
|
|||
lp := NewLoadpoint(util.NewLogger("foo"), nil)
|
||||
assert.Equal(t, 100, lp.effectiveLimitSoc())
|
||||
}
|
||||
|
||||
func TestEffectiveMinMaxCurrent(t *testing.T) {
|
||||
tc := []struct {
|
||||
chargerMin, chargerMax float64
|
||||
vehicleMin, vehicleMax float64
|
||||
effectiveMin, effectiveMax float64
|
||||
}{
|
||||
{0, 0, 0, 0, 6, 16},
|
||||
{1, 10, 0, 0, 1, 10}, // charger lower
|
||||
{10, 20, 0, 0, 10, 16}, // charger higher - max ignored
|
||||
{0, 0, 1, 10, 6, 10}, // vehicle lower - min ignored
|
||||
{0, 0, 10, 20, 10, 16}, // vehicle higher - max ignored
|
||||
{1, 10, 2, 12, 1, 10}, // charger + vehicle lower
|
||||
{10, 20, 12, 22, 10, 16}, // charger + vehicle higher
|
||||
}
|
||||
|
||||
for _, tc := range tc {
|
||||
t.Logf("%+v", tc)
|
||||
ctrl := gomock.NewController(t)
|
||||
|
||||
lp := NewLoadpoint(util.NewLogger("foo"), nil)
|
||||
lp.charger = api.NewMockCharger(ctrl)
|
||||
|
||||
if tc.chargerMin+tc.chargerMax > 0 {
|
||||
currentLimiter := api.NewMockCurrentLimiter(ctrl)
|
||||
currentLimiter.EXPECT().GetMinMaxCurrent().Return(tc.chargerMin, tc.chargerMax, nil).AnyTimes()
|
||||
|
||||
lp.charger = struct {
|
||||
api.Charger
|
||||
api.CurrentLimiter
|
||||
}{
|
||||
Charger: lp.charger,
|
||||
CurrentLimiter: currentLimiter,
|
||||
}
|
||||
}
|
||||
|
||||
if tc.vehicleMin+tc.vehicleMax > 0 {
|
||||
vehicle := api.NewMockVehicle(ctrl)
|
||||
ac := api.ActionConfig{
|
||||
MinCurrent: tc.vehicleMin,
|
||||
MaxCurrent: tc.vehicleMax,
|
||||
}
|
||||
vehicle.EXPECT().OnIdentified().Return(ac).AnyTimes()
|
||||
|
||||
lp.vehicle = vehicle
|
||||
}
|
||||
|
||||
assert.Equal(t, tc.effectiveMin, lp.effectiveMinCurrent())
|
||||
assert.Equal(t, tc.effectiveMax, lp.effectiveMaxCurrent())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,9 +88,6 @@ func TestNew(t *testing.T) {
|
|||
if lp.phases != 0 {
|
||||
t.Errorf("Phases %v", lp.phases)
|
||||
}
|
||||
if lp.MinCurrent != minA {
|
||||
t.Errorf("MinCurrent %v", lp.MinCurrent)
|
||||
}
|
||||
if lp.MaxCurrent != maxA {
|
||||
t.Errorf("MaxCurrent %v", lp.MaxCurrent)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue