Circuit: fix validateCurrent and validatePower (#20183)
This commit is contained in:
parent
167124bfa3
commit
455bc3348c
5 changed files with 39 additions and 28 deletions
|
|
@ -239,8 +239,8 @@ type Circuit interface {
|
|||
SetMaxPower(float64)
|
||||
SetMaxCurrent(float64)
|
||||
Update([]CircuitLoad) error
|
||||
ValidateCurrent(old, new float64) float64
|
||||
ValidatePower(old, new float64) float64
|
||||
ValidateCurrent(old, new float64, charging bool) float64
|
||||
ValidatePower(old, new float64, charging bool) float64
|
||||
}
|
||||
|
||||
// Redactor is an interface to redact sensitive data
|
||||
|
|
|
|||
16
api/mock.go
16
api/mock.go
|
|
@ -953,31 +953,31 @@ func (mr *MockCircuitMockRecorder) Update(arg0 any) *gomock.Call {
|
|||
}
|
||||
|
||||
// ValidateCurrent mocks base method.
|
||||
func (m *MockCircuit) ValidateCurrent(old, new float64) float64 {
|
||||
func (m *MockCircuit) ValidateCurrent(old, new float64, charging bool) float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidateCurrent", old, new)
|
||||
ret := m.ctrl.Call(m, "ValidateCurrent", old, new, charging)
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ValidateCurrent indicates an expected call of ValidateCurrent.
|
||||
func (mr *MockCircuitMockRecorder) ValidateCurrent(old, new any) *gomock.Call {
|
||||
func (mr *MockCircuitMockRecorder) ValidateCurrent(old, new, charging any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateCurrent", reflect.TypeOf((*MockCircuit)(nil).ValidateCurrent), old, new)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateCurrent", reflect.TypeOf((*MockCircuit)(nil).ValidateCurrent), old, new, charging)
|
||||
}
|
||||
|
||||
// ValidatePower mocks base method.
|
||||
func (m *MockCircuit) ValidatePower(old, new float64) float64 {
|
||||
func (m *MockCircuit) ValidatePower(old, new float64, charging bool) float64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatePower", old, new)
|
||||
ret := m.ctrl.Call(m, "ValidatePower", old, new, charging)
|
||||
ret0, _ := ret[0].(float64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ValidatePower indicates an expected call of ValidatePower.
|
||||
func (mr *MockCircuitMockRecorder) ValidatePower(old, new any) *gomock.Call {
|
||||
func (mr *MockCircuitMockRecorder) ValidatePower(old, new, charging any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatePower", reflect.TypeOf((*MockCircuit)(nil).ValidatePower), old, new)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatePower", reflect.TypeOf((*MockCircuit)(nil).ValidatePower), old, new, charging)
|
||||
}
|
||||
|
||||
// Wrap mocks base method.
|
||||
|
|
|
|||
|
|
@ -320,17 +320,22 @@ func (c *Circuit) GetMaxPhaseCurrent() float64 {
|
|||
}
|
||||
|
||||
// ValidatePower validates power request
|
||||
func (c *Circuit) ValidatePower(old, new float64) float64 {
|
||||
func (c *Circuit) ValidatePower(old, new float64, charging bool) float64 {
|
||||
if maxPower := c.GetMaxPower(); maxPower != 0 {
|
||||
delta := max(0, new-old)
|
||||
potential := maxPower - c.power
|
||||
|
||||
if delta > potential {
|
||||
capped := max(0, old+potential)
|
||||
c.log.DEBUG.Printf("validate power: %.5gW + (%.5gW -> %.5gW) > %.5gW capped at %.5gW", c.power, old, new, maxPower, capped)
|
||||
new = capped
|
||||
if charging {
|
||||
if delta > potential {
|
||||
capped := max(0, min(new, min(old+potential, maxPower*1.1))) //allow 10% more than maxPower since some devices may not utilize offered power completely
|
||||
c.log.DEBUG.Printf("validate power: %.5gW + (%.5gW -> %.5gW) > %.5gW capped at %.5gW", c.power, old, new, maxPower, capped)
|
||||
new = capped
|
||||
} else {
|
||||
c.log.TRACE.Printf("validate power: %.5gW + (%.5gW -> %.5gW) <= %.5gW ok", c.power, old, new, maxPower)
|
||||
new = min(new, maxPower*1.1)
|
||||
}
|
||||
} else {
|
||||
c.log.TRACE.Printf("validate power: %.5gW + (%.5gW -> %.5gW) <= %.5gW ok", c.power, old, new, maxPower)
|
||||
new = max(0, min(new, potential))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,21 +343,27 @@ func (c *Circuit) ValidatePower(old, new float64) float64 {
|
|||
return new
|
||||
}
|
||||
|
||||
return c.parent.ValidatePower(old, new)
|
||||
return c.parent.ValidatePower(old, new, charging)
|
||||
}
|
||||
|
||||
// ValidateCurrent validates current request
|
||||
func (c *Circuit) ValidateCurrent(old, new float64) float64 {
|
||||
// ValidateCurrent validates current request
|
||||
func (c *Circuit) ValidateCurrent(old, new float64, charging bool) float64 {
|
||||
if maxCurrent := c.GetMaxCurrent(); maxCurrent != 0 {
|
||||
delta := max(0, new-old)
|
||||
potential := maxCurrent - c.current
|
||||
|
||||
if delta > potential {
|
||||
capped := max(0, old+potential)
|
||||
c.log.DEBUG.Printf("validate current: %.3gA + (%.3gA -> %.3gA) > %.3gA capped at %.3gA", c.current, old, new, maxCurrent, capped)
|
||||
new = capped
|
||||
if charging {
|
||||
if delta > potential {
|
||||
capped := max(0, min(new, min(old+potential, maxCurrent*1.1))) //allow up to 10% more than maxCurrent since some devices may not utilize offered current completely
|
||||
c.log.DEBUG.Printf("validate current: %.3gA + (%.3gA -> %.3gA) > %.3gA capped at %.3gA", c.current, old, new, maxCurrent, capped)
|
||||
new = capped
|
||||
} else {
|
||||
c.log.TRACE.Printf("validate current: %.3gA + (%.3gA -> %.3gA) <= %.3gA ok", c.current, old, new, maxCurrent)
|
||||
new = min(new, maxCurrent*1.1)
|
||||
}
|
||||
} else {
|
||||
c.log.TRACE.Printf("validate current: %.3gA + (%.3gA -> %.3gA) <= %.3gA ok", c.current, old, new, maxCurrent)
|
||||
new = max(0, min(new, potential))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -360,5 +371,5 @@ func (c *Circuit) ValidateCurrent(old, new float64) float64 {
|
|||
return new
|
||||
}
|
||||
|
||||
return c.parent.ValidateCurrent(old, new)
|
||||
return c.parent.ValidateCurrent(old, new, charging)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ func TestCircuitPower(t *testing.T) {
|
|||
cm2.EXPECT().CurrentPower().Return(tc.c2, nil)
|
||||
require.NoError(t, pc.Update(nil))
|
||||
|
||||
assert.Equal(t, tc.res, c1.ValidatePower(tc.old, tc.new), tc)
|
||||
assert.Equal(t, tc.res, c1.ValidatePower(tc.old, tc.new, true), tc)
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ func TestCircuitCurrents(t *testing.T) {
|
|||
cm2.MockPhaseCurrents.EXPECT().Currents().Return(tc.c2, tc.c2, tc.c2, nil)
|
||||
require.NoError(t, pc.Update(nil))
|
||||
|
||||
assert.Equal(t, tc.res, c1.ValidateCurrent(tc.old, tc.new), tc)
|
||||
assert.Equal(t, tc.res, c1.ValidateCurrent(tc.old, tc.new, true), tc)
|
||||
|
||||
ctrl.Finish()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -836,10 +836,10 @@ func (lp *Loadpoint) setLimit(chargeCurrent float64) error {
|
|||
|
||||
// apply circuit limits
|
||||
if lp.circuit != nil {
|
||||
currentLimit := lp.circuit.ValidateCurrent(lp.chargeCurrent, chargeCurrent)
|
||||
currentLimit := lp.circuit.ValidateCurrent(lp.chargeCurrent, chargeCurrent, lp.charging())
|
||||
|
||||
activePhases := lp.ActivePhases()
|
||||
powerLimit := lp.circuit.ValidatePower(lp.chargePower, currentToPower(chargeCurrent, activePhases))
|
||||
powerLimit := lp.circuit.ValidatePower(lp.chargePower, currentToPower(chargeCurrent, activePhases), lp.charging())
|
||||
currentLimitViaPower := powerToCurrent(powerLimit, activePhases)
|
||||
|
||||
chargeCurrent = lp.roundedCurrent(min(currentLimit, currentLimitViaPower))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue