Add loadpoint prioritisation (#6107)
This commit is contained in:
parent
c65f7270a9
commit
ccb1338d90
7 changed files with 638 additions and 2 deletions
|
|
@ -103,6 +103,7 @@ type Loadpoint struct {
|
|||
Mode api.ChargeMode `mapstructure:"mode"` // Charge mode, guarded by mutex
|
||||
|
||||
Title_ string `mapstructure:"title"` // UI title
|
||||
Priority_ int `mapstructure:"priority"` // Priority
|
||||
ConfiguredPhases int `mapstructure:"phases"` // Charger configured phase mode 0/1/3
|
||||
ChargerRef string `mapstructure:"charger"` // Charger reference
|
||||
VehicleRef string `mapstructure:"vehicle"` // Vehicle reference
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import (
|
|||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
||||
//go:generate mockgen -package loadpoint -destination mock.go -mock_names API=MockAPI github.com/evcc-io/evcc/core/loadpoint API
|
||||
|
||||
// Controller gives access to loadpoint
|
||||
type Controller interface {
|
||||
LoadpointControl(API)
|
||||
|
|
@ -15,6 +17,7 @@ type Controller interface {
|
|||
type API interface {
|
||||
// Title returns the defined loadpoint title
|
||||
Title() string
|
||||
Priority() int
|
||||
|
||||
//
|
||||
// status
|
||||
|
|
@ -76,6 +79,8 @@ type API interface {
|
|||
HasChargeMeter() bool
|
||||
// GetChargePower returns the current charging power
|
||||
GetChargePower() float64
|
||||
// GetChargePowerFlexibility returns the flexible amount of current charging power
|
||||
GetChargePowerFlexibility() float64
|
||||
// GetMinCurrent returns the min charging current
|
||||
GetMinCurrent() float64
|
||||
// SetMinCurrent sets the min charging current
|
||||
|
|
|
|||
520
core/loadpoint/mock.go
Normal file
520
core/loadpoint/mock.go
Normal file
|
|
@ -0,0 +1,520 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/evcc-io/evcc/core/loadpoint (interfaces: API)
|
||||
|
||||
// Package loadpoint is a generated GoMock package.
|
||||
package loadpoint
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
|
||||
api "github.com/evcc-io/evcc/api"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockAPI is a mock of API interface.
|
||||
type MockAPI struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockAPIMockRecorder
|
||||
}
|
||||
|
||||
// MockAPIMockRecorder is the mock recorder for MockAPI.
|
||||
type MockAPIMockRecorder struct {
|
||||
mock *MockAPI
|
||||
}
|
||||
|
||||
// NewMockAPI creates a new mock instance.
|
||||
func NewMockAPI(ctrl *gomock.Controller) *MockAPI {
|
||||
mock := &MockAPI{ctrl: ctrl}
|
||||
mock.recorder = &MockAPIMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockAPI) EXPECT() *MockAPIMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetChargePower mocks base method.
|
||||
func (m *MockAPI) GetChargePower() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetChargePower")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetChargePower indicates an expected call of GetChargePower.
|
||||
func (mr *MockAPIMockRecorder) GetChargePower() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChargePower", reflect.TypeOf((*MockAPI)(nil).GetChargePower))
|
||||
}
|
||||
|
||||
// GetChargePowerFlexibility mocks base method.
|
||||
func (m *MockAPI) GetChargePowerFlexibility() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetChargePowerFlexibility")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetChargePowerFlexibility indicates an expected call of GetChargePowerFlexibility.
|
||||
func (mr *MockAPIMockRecorder) GetChargePowerFlexibility() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChargePowerFlexibility", reflect.TypeOf((*MockAPI)(nil).GetChargePowerFlexibility))
|
||||
}
|
||||
|
||||
// GetDisableThreshold mocks base method.
|
||||
func (m *MockAPI) GetDisableThreshold() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetDisableThreshold")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetDisableThreshold indicates an expected call of GetDisableThreshold.
|
||||
func (mr *MockAPIMockRecorder) GetDisableThreshold() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDisableThreshold", reflect.TypeOf((*MockAPI)(nil).GetDisableThreshold))
|
||||
}
|
||||
|
||||
// GetEnableThreshold mocks base method.
|
||||
func (m *MockAPI) GetEnableThreshold() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetEnableThreshold")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetEnableThreshold indicates an expected call of GetEnableThreshold.
|
||||
func (mr *MockAPIMockRecorder) GetEnableThreshold() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEnableThreshold", reflect.TypeOf((*MockAPI)(nil).GetEnableThreshold))
|
||||
}
|
||||
|
||||
// GetMaxCurrent mocks base method.
|
||||
func (m *MockAPI) GetMaxCurrent() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMaxCurrent")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetMaxCurrent indicates an expected call of GetMaxCurrent.
|
||||
func (mr *MockAPIMockRecorder) GetMaxCurrent() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMaxCurrent", reflect.TypeOf((*MockAPI)(nil).GetMaxCurrent))
|
||||
}
|
||||
|
||||
// GetMaxPower mocks base method.
|
||||
func (m *MockAPI) GetMaxPower() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMaxPower")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetMaxPower indicates an expected call of GetMaxPower.
|
||||
func (mr *MockAPIMockRecorder) GetMaxPower() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMaxPower", reflect.TypeOf((*MockAPI)(nil).GetMaxPower))
|
||||
}
|
||||
|
||||
// GetMinCurrent mocks base method.
|
||||
func (m *MockAPI) GetMinCurrent() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMinCurrent")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetMinCurrent indicates an expected call of GetMinCurrent.
|
||||
func (mr *MockAPIMockRecorder) GetMinCurrent() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMinCurrent", reflect.TypeOf((*MockAPI)(nil).GetMinCurrent))
|
||||
}
|
||||
|
||||
// GetMinPower mocks base method.
|
||||
func (m *MockAPI) GetMinPower() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMinPower")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetMinPower indicates an expected call of GetMinPower.
|
||||
func (mr *MockAPIMockRecorder) GetMinPower() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMinPower", reflect.TypeOf((*MockAPI)(nil).GetMinPower))
|
||||
}
|
||||
|
||||
// GetMinSoc mocks base method.
|
||||
func (m *MockAPI) GetMinSoc() int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMinSoc")
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetMinSoc indicates an expected call of GetMinSoc.
|
||||
func (mr *MockAPIMockRecorder) GetMinSoc() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMinSoc", reflect.TypeOf((*MockAPI)(nil).GetMinSoc))
|
||||
}
|
||||
|
||||
// GetMode mocks base method.
|
||||
func (m *MockAPI) GetMode() api.ChargeMode {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetMode")
|
||||
ret0, _ := ret[0].(api.ChargeMode)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetMode indicates an expected call of GetMode.
|
||||
func (mr *MockAPIMockRecorder) GetMode() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMode", reflect.TypeOf((*MockAPI)(nil).GetMode))
|
||||
}
|
||||
|
||||
// GetPhases mocks base method.
|
||||
func (m *MockAPI) GetPhases() int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPhases")
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetPhases indicates an expected call of GetPhases.
|
||||
func (mr *MockAPIMockRecorder) GetPhases() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPhases", reflect.TypeOf((*MockAPI)(nil).GetPhases))
|
||||
}
|
||||
|
||||
// GetPlan mocks base method.
|
||||
func (m *MockAPI) GetPlan(arg0 time.Time, arg1 float64) (time.Duration, api.Rates, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPlan", arg0, arg1)
|
||||
ret0, _ := ret[0].(time.Duration)
|
||||
ret1, _ := ret[1].(api.Rates)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// GetPlan indicates an expected call of GetPlan.
|
||||
func (mr *MockAPIMockRecorder) GetPlan(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPlan", reflect.TypeOf((*MockAPI)(nil).GetPlan), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetPlannerUnit mocks base method.
|
||||
func (m *MockAPI) GetPlannerUnit() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPlannerUnit")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetPlannerUnit indicates an expected call of GetPlannerUnit.
|
||||
func (mr *MockAPIMockRecorder) GetPlannerUnit() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPlannerUnit", reflect.TypeOf((*MockAPI)(nil).GetPlannerUnit))
|
||||
}
|
||||
|
||||
// GetRemainingDuration mocks base method.
|
||||
func (m *MockAPI) GetRemainingDuration() time.Duration {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetRemainingDuration")
|
||||
ret0, _ := ret[0].(time.Duration)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetRemainingDuration indicates an expected call of GetRemainingDuration.
|
||||
func (mr *MockAPIMockRecorder) GetRemainingDuration() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRemainingDuration", reflect.TypeOf((*MockAPI)(nil).GetRemainingDuration))
|
||||
}
|
||||
|
||||
// GetRemainingEnergy mocks base method.
|
||||
func (m *MockAPI) GetRemainingEnergy() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetRemainingEnergy")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetRemainingEnergy indicates an expected call of GetRemainingEnergy.
|
||||
func (mr *MockAPIMockRecorder) GetRemainingEnergy() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRemainingEnergy", reflect.TypeOf((*MockAPI)(nil).GetRemainingEnergy))
|
||||
}
|
||||
|
||||
// GetStatus mocks base method.
|
||||
func (m *MockAPI) GetStatus() api.ChargeStatus {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetStatus")
|
||||
ret0, _ := ret[0].(api.ChargeStatus)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetStatus indicates an expected call of GetStatus.
|
||||
func (mr *MockAPIMockRecorder) GetStatus() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatus", reflect.TypeOf((*MockAPI)(nil).GetStatus))
|
||||
}
|
||||
|
||||
// GetTargetEnergy mocks base method.
|
||||
func (m *MockAPI) GetTargetEnergy() float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetTargetEnergy")
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetTargetEnergy indicates an expected call of GetTargetEnergy.
|
||||
func (mr *MockAPIMockRecorder) GetTargetEnergy() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTargetEnergy", reflect.TypeOf((*MockAPI)(nil).GetTargetEnergy))
|
||||
}
|
||||
|
||||
// GetTargetSoc mocks base method.
|
||||
func (m *MockAPI) GetTargetSoc() int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetTargetSoc")
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetTargetSoc indicates an expected call of GetTargetSoc.
|
||||
func (mr *MockAPIMockRecorder) GetTargetSoc() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTargetSoc", reflect.TypeOf((*MockAPI)(nil).GetTargetSoc))
|
||||
}
|
||||
|
||||
// GetTargetTime mocks base method.
|
||||
func (m *MockAPI) GetTargetTime() time.Time {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetTargetTime")
|
||||
ret0, _ := ret[0].(time.Time)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetTargetTime indicates an expected call of GetTargetTime.
|
||||
func (mr *MockAPIMockRecorder) GetTargetTime() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTargetTime", reflect.TypeOf((*MockAPI)(nil).GetTargetTime))
|
||||
}
|
||||
|
||||
// GetVehicle mocks base method.
|
||||
func (m *MockAPI) GetVehicle() api.Vehicle {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetVehicle")
|
||||
ret0, _ := ret[0].(api.Vehicle)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetVehicle indicates an expected call of GetVehicle.
|
||||
func (mr *MockAPIMockRecorder) GetVehicle() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVehicle", reflect.TypeOf((*MockAPI)(nil).GetVehicle))
|
||||
}
|
||||
|
||||
// HasChargeMeter mocks base method.
|
||||
func (m *MockAPI) HasChargeMeter() bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HasChargeMeter")
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HasChargeMeter indicates an expected call of HasChargeMeter.
|
||||
func (mr *MockAPIMockRecorder) HasChargeMeter() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasChargeMeter", reflect.TypeOf((*MockAPI)(nil).HasChargeMeter))
|
||||
}
|
||||
|
||||
// Priority mocks base method.
|
||||
func (m *MockAPI) Priority() int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Priority")
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Priority indicates an expected call of Priority.
|
||||
func (mr *MockAPIMockRecorder) Priority() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Priority", reflect.TypeOf((*MockAPI)(nil).Priority))
|
||||
}
|
||||
|
||||
// RemoteControl mocks base method.
|
||||
func (m *MockAPI) RemoteControl(arg0 string, arg1 RemoteDemand) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "RemoteControl", arg0, arg1)
|
||||
}
|
||||
|
||||
// RemoteControl indicates an expected call of RemoteControl.
|
||||
func (mr *MockAPIMockRecorder) RemoteControl(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteControl", reflect.TypeOf((*MockAPI)(nil).RemoteControl), arg0, arg1)
|
||||
}
|
||||
|
||||
// SetDisableThreshold mocks base method.
|
||||
func (m *MockAPI) SetDisableThreshold(arg0 float64) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetDisableThreshold", arg0)
|
||||
}
|
||||
|
||||
// SetDisableThreshold indicates an expected call of SetDisableThreshold.
|
||||
func (mr *MockAPIMockRecorder) SetDisableThreshold(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDisableThreshold", reflect.TypeOf((*MockAPI)(nil).SetDisableThreshold), arg0)
|
||||
}
|
||||
|
||||
// SetEnableThreshold mocks base method.
|
||||
func (m *MockAPI) SetEnableThreshold(arg0 float64) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetEnableThreshold", arg0)
|
||||
}
|
||||
|
||||
// SetEnableThreshold indicates an expected call of SetEnableThreshold.
|
||||
func (mr *MockAPIMockRecorder) SetEnableThreshold(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetEnableThreshold", reflect.TypeOf((*MockAPI)(nil).SetEnableThreshold), arg0)
|
||||
}
|
||||
|
||||
// SetMaxCurrent mocks base method.
|
||||
func (m *MockAPI) SetMaxCurrent(arg0 float64) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetMaxCurrent", arg0)
|
||||
}
|
||||
|
||||
// SetMaxCurrent indicates an expected call of SetMaxCurrent.
|
||||
func (mr *MockAPIMockRecorder) SetMaxCurrent(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxCurrent", reflect.TypeOf((*MockAPI)(nil).SetMaxCurrent), arg0)
|
||||
}
|
||||
|
||||
// SetMinCurrent mocks base method.
|
||||
func (m *MockAPI) SetMinCurrent(arg0 float64) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetMinCurrent", arg0)
|
||||
}
|
||||
|
||||
// SetMinCurrent indicates an expected call of SetMinCurrent.
|
||||
func (mr *MockAPIMockRecorder) SetMinCurrent(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMinCurrent", reflect.TypeOf((*MockAPI)(nil).SetMinCurrent), arg0)
|
||||
}
|
||||
|
||||
// SetMinSoc mocks base method.
|
||||
func (m *MockAPI) SetMinSoc(arg0 int) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetMinSoc", arg0)
|
||||
}
|
||||
|
||||
// SetMinSoc indicates an expected call of SetMinSoc.
|
||||
func (mr *MockAPIMockRecorder) SetMinSoc(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMinSoc", reflect.TypeOf((*MockAPI)(nil).SetMinSoc), arg0)
|
||||
}
|
||||
|
||||
// SetMode mocks base method.
|
||||
func (m *MockAPI) SetMode(arg0 api.ChargeMode) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetMode", arg0)
|
||||
}
|
||||
|
||||
// SetMode indicates an expected call of SetMode.
|
||||
func (mr *MockAPIMockRecorder) SetMode(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMode", reflect.TypeOf((*MockAPI)(nil).SetMode), arg0)
|
||||
}
|
||||
|
||||
// SetPhases mocks base method.
|
||||
func (m *MockAPI) SetPhases(arg0 int) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SetPhases", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SetPhases indicates an expected call of SetPhases.
|
||||
func (mr *MockAPIMockRecorder) SetPhases(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPhases", reflect.TypeOf((*MockAPI)(nil).SetPhases), arg0)
|
||||
}
|
||||
|
||||
// SetTargetEnergy mocks base method.
|
||||
func (m *MockAPI) SetTargetEnergy(arg0 float64) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetTargetEnergy", arg0)
|
||||
}
|
||||
|
||||
// SetTargetEnergy indicates an expected call of SetTargetEnergy.
|
||||
func (mr *MockAPIMockRecorder) SetTargetEnergy(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTargetEnergy", reflect.TypeOf((*MockAPI)(nil).SetTargetEnergy), arg0)
|
||||
}
|
||||
|
||||
// SetTargetSoc mocks base method.
|
||||
func (m *MockAPI) SetTargetSoc(arg0 int) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetTargetSoc", arg0)
|
||||
}
|
||||
|
||||
// SetTargetSoc indicates an expected call of SetTargetSoc.
|
||||
func (mr *MockAPIMockRecorder) SetTargetSoc(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTargetSoc", reflect.TypeOf((*MockAPI)(nil).SetTargetSoc), arg0)
|
||||
}
|
||||
|
||||
// SetTargetTime mocks base method.
|
||||
func (m *MockAPI) SetTargetTime(arg0 time.Time) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SetTargetTime", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SetTargetTime indicates an expected call of SetTargetTime.
|
||||
func (mr *MockAPIMockRecorder) SetTargetTime(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTargetTime", reflect.TypeOf((*MockAPI)(nil).SetTargetTime), arg0)
|
||||
}
|
||||
|
||||
// SetVehicle mocks base method.
|
||||
func (m *MockAPI) SetVehicle(arg0 api.Vehicle) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetVehicle", arg0)
|
||||
}
|
||||
|
||||
// SetVehicle indicates an expected call of SetVehicle.
|
||||
func (mr *MockAPIMockRecorder) SetVehicle(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetVehicle", reflect.TypeOf((*MockAPI)(nil).SetVehicle), arg0)
|
||||
}
|
||||
|
||||
// StartVehicleDetection mocks base method.
|
||||
func (m *MockAPI) StartVehicleDetection() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "StartVehicleDetection")
|
||||
}
|
||||
|
||||
// StartVehicleDetection indicates an expected call of StartVehicleDetection.
|
||||
func (mr *MockAPIMockRecorder) StartVehicleDetection() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartVehicleDetection", reflect.TypeOf((*MockAPI)(nil).StartVehicleDetection))
|
||||
}
|
||||
|
||||
// Title mocks base method.
|
||||
func (m *MockAPI) Title() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Title")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Title indicates an expected call of Title.
|
||||
func (mr *MockAPIMockRecorder) Title() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Title", reflect.TypeOf((*MockAPI)(nil).Title))
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package core
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
|
|
@ -17,6 +18,11 @@ func (lp *Loadpoint) Title() string {
|
|||
return lp.Title_
|
||||
}
|
||||
|
||||
// Priority returns the loadpoint priority
|
||||
func (lp *Loadpoint) Priority() int {
|
||||
return lp.Priority_
|
||||
}
|
||||
|
||||
// GetStatus returns the charging status
|
||||
func (lp *Loadpoint) GetStatus() api.ChargeStatus {
|
||||
lp.Lock()
|
||||
|
|
@ -285,6 +291,22 @@ func (lp *Loadpoint) GetChargePower() float64 {
|
|||
return lp.chargePower
|
||||
}
|
||||
|
||||
// GetChargePowerFlexibility returns the flexible amount of current charging power
|
||||
func (lp *Loadpoint) GetChargePowerFlexibility() float64 {
|
||||
// no locking
|
||||
mode := lp.GetMode()
|
||||
if mode == api.ModeNow || !lp.charging() || lp.minSocNotReached() {
|
||||
return 0
|
||||
}
|
||||
|
||||
if mode == api.ModePV {
|
||||
return lp.GetChargePower()
|
||||
}
|
||||
|
||||
// MinPV mode
|
||||
return math.Max(0, lp.GetChargePower()-lp.GetMinPower())
|
||||
}
|
||||
|
||||
// GetMinCurrent returns the min loadpoint current
|
||||
func (lp *Loadpoint) GetMinCurrent() float64 {
|
||||
lp.Lock()
|
||||
|
|
|
|||
34
core/prioritizer/prioritizer.go
Normal file
34
core/prioritizer/prioritizer.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package prioritizer
|
||||
|
||||
import (
|
||||
"github.com/evcc-io/evcc/core/loadpoint"
|
||||
)
|
||||
|
||||
type Prioritizer struct {
|
||||
demand map[loadpoint.API]float64
|
||||
}
|
||||
|
||||
func New() *Prioritizer {
|
||||
return &Prioritizer{
|
||||
demand: make(map[loadpoint.API]float64),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prioritizer) UpdateChargePowerFlexibility(lp loadpoint.API) {
|
||||
if power := lp.GetChargePowerFlexibility(); power >= 0 {
|
||||
p.demand[lp] = power
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prioritizer) GetChargePowerFlexibility(lp loadpoint.API) float64 {
|
||||
prio := lp.Priority()
|
||||
|
||||
var reduceBy float64
|
||||
for lp, power := range p.demand {
|
||||
if lp.Priority() < prio {
|
||||
reduceBy += power
|
||||
}
|
||||
}
|
||||
|
||||
return reduceBy
|
||||
}
|
||||
36
core/prioritizer/prioritizer_test.go
Normal file
36
core/prioritizer/prioritizer_test.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package prioritizer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/evcc-io/evcc/core/loadpoint"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPrioritzer(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
|
||||
p := New()
|
||||
|
||||
lo := loadpoint.NewMockAPI(ctrl)
|
||||
lo.EXPECT().Priority().Return(0).AnyTimes()
|
||||
|
||||
hi := loadpoint.NewMockAPI(ctrl)
|
||||
hi.EXPECT().Priority().Return(1).AnyTimes()
|
||||
|
||||
// no additional power available
|
||||
lo.EXPECT().GetChargePowerFlexibility().Return(300.0)
|
||||
p.UpdateChargePowerFlexibility(lo)
|
||||
assert.Equal(t, 0.0, p.GetChargePowerFlexibility(lo))
|
||||
|
||||
// additional power available
|
||||
hi.EXPECT().GetChargePowerFlexibility().Return(1e3)
|
||||
p.UpdateChargePowerFlexibility(hi)
|
||||
assert.Equal(t, 300.0, p.GetChargePowerFlexibility(hi))
|
||||
|
||||
// additional power removed
|
||||
lo.EXPECT().GetChargePowerFlexibility().Return(0.0)
|
||||
p.UpdateChargePowerFlexibility(lo)
|
||||
assert.Equal(t, 0.0, p.GetChargePowerFlexibility(hi))
|
||||
}
|
||||
22
core/site.go
22
core/site.go
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/evcc-io/evcc/core/db"
|
||||
"github.com/evcc-io/evcc/core/loadpoint"
|
||||
"github.com/evcc-io/evcc/core/planner"
|
||||
"github.com/evcc-io/evcc/core/prioritizer"
|
||||
"github.com/evcc-io/evcc/push"
|
||||
serverdb "github.com/evcc-io/evcc/server/db"
|
||||
"github.com/evcc-io/evcc/tariff"
|
||||
|
|
@ -25,6 +26,7 @@ const standbyPower = 10 // consider less than 10W as charger in standby
|
|||
|
||||
// Updater abstracts the Loadpoint implementation for testing
|
||||
type Updater interface {
|
||||
loadpoint.API
|
||||
Update(availablePower float64, batteryBuffered bool)
|
||||
}
|
||||
|
||||
|
|
@ -68,6 +70,7 @@ type Site struct {
|
|||
tariffs tariff.Tariffs // Tariff
|
||||
loadpoints []*Loadpoint // Loadpoints
|
||||
coordinator *coordinator.Coordinator // Vehicles
|
||||
prioritizer *prioritizer.Prioritizer // Power budgets
|
||||
savings *Savings // Savings
|
||||
|
||||
// cached state
|
||||
|
|
@ -108,6 +111,7 @@ func NewSiteFromConfig(
|
|||
site.loadpoints = loadpoints
|
||||
site.tariffs = tariffs
|
||||
site.coordinator = coordinator.New(log, vehicles)
|
||||
site.prioritizer = prioritizer.New()
|
||||
site.savings = NewSavings(tariffs)
|
||||
|
||||
// upload telemetry on shutdown
|
||||
|
|
@ -485,7 +489,7 @@ func (site *Site) updateMeters() error {
|
|||
|
||||
// sitePower returns the net power exported by the site minus a residual margin.
|
||||
// negative values mean grid: export, battery: charging
|
||||
func (site *Site) sitePower(totalChargePower float64) (float64, error) {
|
||||
func (site *Site) sitePower(totalChargePower, flexiblePower float64) (float64, error) {
|
||||
if err := site.updateMeters(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -537,6 +541,12 @@ func (site *Site) sitePower(totalChargePower float64) (float64, error) {
|
|||
site.publish("auxPower", auxPower)
|
||||
sitePower -= auxPower
|
||||
|
||||
// handle priority
|
||||
if flexiblePower > 0 {
|
||||
site.log.DEBUG.Printf("giving loadpoint priority for additional: %.0fW", flexiblePower)
|
||||
sitePower -= flexiblePower
|
||||
}
|
||||
|
||||
site.log.DEBUG.Printf("site power: %.0fW", sitePower)
|
||||
|
||||
return sitePower, nil
|
||||
|
|
@ -609,9 +619,17 @@ func (site *Site) update(lp Updater) {
|
|||
for _, lp := range site.loadpoints {
|
||||
lp.UpdateChargePower()
|
||||
totalChargePower += lp.GetChargePower()
|
||||
|
||||
site.prioritizer.UpdateChargePowerFlexibility(lp)
|
||||
}
|
||||
|
||||
if sitePower, err := site.sitePower(totalChargePower); err == nil {
|
||||
// prioritize if possible
|
||||
var flexiblePower float64
|
||||
if lp.GetMode() == api.ModePV {
|
||||
flexiblePower = site.prioritizer.GetChargePowerFlexibility(lp)
|
||||
}
|
||||
|
||||
if sitePower, err := site.sitePower(totalChargePower, flexiblePower); err == nil {
|
||||
lp.Update(sitePower, site.batteryBuffered)
|
||||
|
||||
// ignore negative pvPower values as that means it is not an energy source but consumption
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue