Skip to content

Commit

Permalink
Ensure charger target status is always updated even while car disconn… (
Browse files Browse the repository at this point in the history
  • Loading branch information
andig committed May 6, 2020
1 parent f5f3257 commit 4dd1c46
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 24 deletions.
6 changes: 3 additions & 3 deletions core/chargerhandler.go
Expand Up @@ -118,11 +118,11 @@ func (lp *ChargerHandler) rampUpDown(target int64) error {
// Setting current and disabling are two steps. If already disabled, this is a nop.
func (lp *ChargerHandler) rampOff() error {
if lp.enabled {
if lp.targetCurrent == lp.MinCurrent {
return lp.chargerEnable(false)
if lp.targetCurrent != lp.MinCurrent {
return lp.setTargetCurrent(lp.MinCurrent)
}

return lp.setTargetCurrent(lp.MinCurrent)
return lp.chargerEnable(false)
}

return nil
Expand Down
51 changes: 32 additions & 19 deletions core/loadpoint.go
Expand Up @@ -345,8 +345,7 @@ func (lp *LoadPoint) updateChargeStatus() api.ChargeStatus {
return status
}

// updateModePV sets "minpv" or "pv" load modes
func (lp *LoadPoint) updateModePV(mode api.ChargeMode) error {
func (lp *LoadPoint) maxCurrent(mode api.ChargeMode) int64 {
// grid meter will always be available, if as wrapped pv meter
targetPower := lp.chargePower - lp.gridPower - lp.batteryPower - lp.ResidualPower
if lp.batteryMeter == nil {
Expand All @@ -366,6 +365,19 @@ func (lp *LoadPoint) updateModePV(mode api.ChargeMode) error {
}
}

return targetCurrent
}

// updateModePV handles "minpv" or "pv" modes by setting charger enabled/disabled state
// and maximum current according to available PV power
func (lp *LoadPoint) updateModePV(mode api.ChargeMode) error {
targetCurrent := lp.maxCurrent(mode)
if !lp.connected() {
// ensure minimum current when not connected
// https://github.com/andig/evcc/issues/105
targetCurrent = min(lp.MinCurrent, targetCurrent)
}

log.DEBUG.Printf("%s target charge current: %dA", lp.Name, targetCurrent)

if targetCurrent == 0 {
Expand Down Expand Up @@ -435,24 +447,25 @@ func (lp *LoadPoint) update() {

// check if car connected and ready for charging
var err error
if !lp.connected() {
// ensure restart at min current
err = lp.setTargetCurrent(lp.MinCurrent)
} else {
// execute loading strategy
switch mode := lp.GetMode(); mode {
case api.ModeOff:
err = lp.rampOff()
case api.ModeNow:
err = lp.rampOn(lp.MaxCurrent)
case api.ModeMinPV, api.ModePV:
if meterErr == nil {
// pv modes require meter measurements
err = lp.updateModePV(mode)
} else {
log.WARN.Printf("%s aborting due to meter error", lp.Name)
}

// execute loading strategy
switch mode := lp.GetMode(); mode {
case api.ModeOff:
err = lp.rampOff()
case api.ModeNow:
// ensure that new connections happen at min current
current := lp.MinCurrent
if lp.connected() {
current = lp.MaxCurrent
}
err = lp.rampOn(current)
case api.ModeMinPV, api.ModePV:
// pv modes require meter measurements
if meterErr != nil {
log.WARN.Printf("%s aborting due to meter error", lp.Name)
break
}
err = lp.updateModePV(mode)
}

if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions core/loadpoint_test.go
Expand Up @@ -133,7 +133,8 @@ func TestMeterConfigurations(t *testing.T) {

ctrl := gomock.NewController(t)
lp, wb := newEnvironment(t, ctrl, pm, gm, cm)
wb.EXPECT().Status().Return(api.StatusA, nil)
wb.EXPECT().Status().Return(api.StatusA, nil) // disconnected
wb.EXPECT().Enable(false) // "off" mode

lp.update()
}
Expand Down Expand Up @@ -184,7 +185,7 @@ func TestInitialUpdate(t *testing.T) {
}

// disable if not connected
if tc.status != api.StatusA && tc.mode == api.ModeOff {
if tc.mode == api.ModeOff {
wb.EXPECT().Enable(false)
}

Expand Down

0 comments on commit 4dd1c46

Please sign in to comment.