Repository: andig/evcc
Pull request #479 (2020-11-25 21:13:00)

Refactor charger handling
Simplify charger handling logic (aligned with hardware experts):
- remove stepwise ramp up/down of charge currents
- enable/disable charger without requiring current ramp down

As result, the charger handling becomes more immediate



Patch:
diff --git a/core/chargerhandler.go b/core/chargerhandler.go
index f731b67e..73aa0e5b 100644
--- a/core/chargerhandler.go
+++ b/core/chargerhandler.go
@@ -16,16 +16,15 @@ import (
 // Handler is the charger handler responsible for enabled state, target current and guard durations
 type Handler interface {
 	Prepare()
-	SyncEnabled()
+	Sync()
 	Enabled() bool
 	Status() (api.ChargeStatus, error)
 	TargetCurrent() int64
-	Ramp(int64, ...bool) error
+	Ramp(int64, bool) error
 }
 
 // HandlerConfig contains the public configuration for the ChargerHandler
 type HandlerConfig struct {
-	Sensitivity   int64         // Step size of current change
 	MinCurrent    int64         // PV mode: start current	Min+PV mode: min current
 	MaxCurrent    int64         // Max allowed current. Physically ensured by the charge controller
 	GuardDuration time.Duration // charger enable/disable minimum holding time
@@ -86,8 +85,8 @@ func (lp *ChargerHandler) Prepare() {
 	lp.bus.Publish(evChargeCurrent, lp.MinCurrent)
 }
 
-// SyncEnabled synchronizes charger settings to expected state
-func (lp *ChargerHandler) SyncEnabled() {
+// Sync synchronizes charger settings to expected state
+func (lp *ChargerHandler) Sync() {
 	enabled, err := lp.charger.Enabled()
 	if err == nil && enabled != lp.enabled {
 		lp.log.WARN.Printf("sync enabled state to %s", status[lp.enabled])
@@ -101,10 +100,6 @@ func (lp *ChargerHandler) SyncEnabled() {
 
 // chargerEnable switches charging on or off. Minimum cycle duration is guaranteed.
 func (lp *ChargerHandler) chargerEnable(enable bool) error {
-	if lp.targetCurrent != 0 && lp.targetCurrent != lp.MinCurrent {
-		lp.log.FATAL.Fatal("charger enable/disable called without setting min current first")
-	}
-
 	if remaining := (lp.GuardDuration - lp.clock.Since(lp.guardUpdated)).Truncate(time.Second); remaining > 0 {
 		lp.log.DEBUG.Printf("charger %s - contactor delay %v", status[enable], remaining)
 		return nil
@@ -130,92 +125,47 @@ func (lp *ChargerHandler) chargerEnable(enable bool) error {
 
 // setTargetCurrent guards setting current against changing to identical value
 // and violating MaxCurrent
-func (lp *ChargerHandler) setTargetCurrent(targetCurrentIn int64) error {
-	targetCurrent := clamp(targetCurrentIn, lp.MinCurrent, lp.MaxCurrent)
-	if targetCurrent != targetCurrentIn {
-		lp.log.WARN.Printf("hard limit charge current: %dA", targetCurrent)
-	}
+func (lp *ChargerHandler) setTargetCurrent(targetCurrent int64) error {
+	target := clamp(targetCurrent, lp.MinCurrent, lp.MaxCurrent)
 
-	if lp.targetCurrent != targetCurrent {
-		lp.log.DEBUG.Printf("set charge current: %dA", targetCurrent)
-		if err := lp.charger.MaxCurrent(targetCurrent); err != nil {
+	if lp.targetCurrent != target {
+		lp.log.DEBUG.Printf("set charge current: %dA", target)
+		if err := lp.charger.MaxCurrent(target); err != nil {
 			return fmt.Errorf("charge controller error: %v", err)
 		}
 
-		lp.targetCurrent = targetCurrent // cache
+		lp.targetCurrent = target // cache
 	}
 
 	// if not enabled, current will be reduced to 0 in handler
-	lp.bus.Publish(evChargeCurrent, targetCurrent)
-
-	return nil
-}
-
-// rampUpDown moves stepwise towards target current.
-// It does not enable or disable the charger.
-func (lp *ChargerHandler) rampUpDown(target int64) error {
-	current := lp.targetCurrent
-	if current == target {
-		return nil
-	}
-
-	var step int64
-	if current < target {
-		step = min(current+lp.Sensitivity, target)
-	} else if current > target {
-		step = max(current-lp.Sensitivity, target)
-	}
-
-	step = clamp(step, lp.MinCurrent, lp.MaxCurrent)
-
-	return lp.setTargetCurrent(step)
-}
-
-// rampOff disables charger after setting minCurrent.
-// 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.setTargetCurrent(lp.MinCurrent)
-		}
-
-		return lp.chargerEnable(false)
-	}
+	lp.bus.Publish(evChargeCurrent, target)
 
 	return nil
 }
 
-// rampOn enables charger immediately after setting minCurrent.
-// If already enabled, target will be set.
-func (lp *ChargerHandler) rampOn(target int64) error {
-	if !lp.enabled {
-		if err := lp.setTargetCurrent(lp.MinCurrent); err != nil {
-			return err
-		}
-
-		return lp.chargerEnable(true)
-	}
-
-	return lp.setTargetCurrent(target)
-}
-
 // Ramp performs ramping charger current up and down where targetCurrent=0
 // signals disabled state
-func (lp *ChargerHandler) Ramp(targetCurrent int64, force ...bool) error {
+func (lp *ChargerHandler) Ramp(targetCurrent int64, force bool) error {
 	// reset guard updated
-	if len(force) == 1 && force[0] {
+	if force {
 		lp.guardUpdated = time.Time{}
 	}
 
-	// if targetCurrent == 0 ramp down to disabled state
+	// if targetCurrent == 0 disable
 	if targetCurrent == 0 {
-		return lp.rampOff()
+		err := lp.chargerEnable(false)
+		if err == nil && lp.enabled && lp.targetCurrent > lp.MinCurrent {
+			err = lp.setTargetCurrent(lp.MinCurrent)
+		}
+
+		return err
 	}
 
-	// targetCurrent != 0 and not enabled ramp to enabled state
-	if !lp.enabled {
-		return lp.rampOn(targetCurrent)
+	// else set targetCurrent and optionally enable
+	err := lp.setTargetCurrent(targetCurrent)
+	if err == nil && !lp.enabled {
+		err = lp.chargerEnable(true)
 	}
 
-	return lp.rampUpDown(targetCurrent)
+	return err
 }
diff --git a/core/loadpoint.go b/core/loadpoint.go
index 2e2df63a..78b99a65 100644
--- a/core/loadpoint.go
+++ b/core/loadpoint.go
@@ -172,7 +172,6 @@ func NewLoadPoint(log *util.Logger) *LoadPoint {
 		HandlerConfig: HandlerConfig{
 			MinCurrent:    6,  // A
 			MaxCurrent:    16, // A
-			Sensitivity:   10, // A
 			GuardDuration: 5 * time.Minute,
 		},
 	}
@@ -226,8 +225,8 @@ func (lp *LoadPoint) configureChargerType(charger api.Charger) {
 	}
 }
 
-// notify sends push messages to clients
-func (lp *LoadPoint) notify(event string) {
+// triggerEvent sends push messages to clients
+func (lp *LoadPoint) triggerEvent(event string) {
 	lp.pushChan <- push.Event{Event: event}
 }
 
@@ -241,13 +240,13 @@ func (lp *LoadPoint) publish(key string, val interface{}) {
 // evChargeStartHandler sends external start event
 func (lp *LoadPoint) evChargeStartHandler() {
 	lp.log.INFO.Println("start charging ->")
-	lp.notify(evChargeStart)
+	lp.triggerEvent(evChargeStart)
 }
 
 // evChargeStopHandler sends external stop event
 func (lp *LoadPoint) evChargeStopHandler() {
 	lp.log.INFO.Println("stop charging <-")
-	lp.notify(evChargeStop)
+	lp.triggerEvent(evChargeStop)
 }
 
 // evVehicleConnectHandler sends external start event
@@ -267,7 +266,7 @@ func (lp *LoadPoint) evVehicleConnectHandler() {
 		lp.socEstimator.Reset()
 	}
 
-	lp.notify(evVehicleConnect)
+	lp.triggerEvent(evVehicleConnect)
 }
 
 // evVehicleDisconnectHandler sends external start event
@@ -278,7 +277,7 @@ func (lp *LoadPoint) evVehicleDisconnectHandler() {
 	lp.publish("chargedEnergy", lp.chargedEnergy)
 	lp.publish("connectedDuration", lp.clock.Since(lp.connectedTime))
 
-	lp.notify(evVehicleDisconnect)
+	lp.triggerEvent(evVehicleDisconnect)
 
 	// set default mode on disconnect
 	if lp.OnDisconnect.Mode != "" && lp.GetMode() != api.ModeOff {
@@ -289,7 +288,7 @@ func (lp *LoadPoint) evVehicleDisconnectHandler() {
 	}
 }
 
-// evChargeCurrentHandler updates the dummy charge meter's charge power. This simplifies the main flow
+// evChargeCurrentHandler publishes the charge current
 func (lp *LoadPoint) evChargeCurrentHandler(current int64) {
 	lp.publish("chargeCurrent", current)
 }
@@ -741,7 +740,7 @@ func (lp *LoadPoint) Update(sitePower float64) {
 
 	// sync settings with charger
 	if lp.status != api.StatusA {
-		lp.handler.SyncEnabled()
+		lp.handler.Sync()
 	}
 
 	// phase detection
@@ -758,7 +757,7 @@ func (lp *LoadPoint) Update(sitePower float64) {
 	case !lp.connected():
 		// always disable charger if not connected
 		// https://github.com/andig/evcc/issues/105
-		err = lp.handler.Ramp(0)
+		err = lp.handler.Ramp(0, false)
 
 	case lp.targetSocReached():
 		var targetCurrent int64 // zero disables
diff --git a/core/math.go b/core/math.go
index 912c95a1..8bbc0228 100644
--- a/core/math.go
+++ b/core/math.go
@@ -1,21 +1,5 @@
 package core
 
-// min calculates minimum of two integer values
-func min(x, y int64) int64 {
-	if x < y {
-		return x
-	}
-	return y
-}
-
-// max calculates maximum of two integer values
-func max(x, y int64) int64 {
-	if x > y {
-		return x
-	}
-	return y
-}
-
 // clamp calculates minimum of two integer values
 func clamp(x, min, max int64) int64 {
 	if x <= min {
diff --git a/evcc.dist.yaml b/evcc.dist.yaml
index d4552ec4..2a1eef55 100644
--- a/evcc.dist.yaml
+++ b/evcc.dist.yaml
@@ -84,14 +84,13 @@ loadpoints:
     mode: pv # switch back to pv mode
     targetSoC: 100 # charge to 100%
   phases: 3 # ev phases (default 3)
-  sensitivity: 1 # current raise/lower step size (default 10A)
   enable: # pv mode enable behavior
     delay: 1m # threshold must be exceeded for this long
     threshold: 0 # minimum export power (W). If zero, export must exceed minimum charge power to enable
   disable: # pv mode disable behavior
     delay: 5m # threshold must be exceeded for this long
     threshold: 200 # maximum import power (W)
-  guardduration: 10m # switch charger contactor not more often than this (default 10m)
+  guardduration: 5m # switch charger contactor not more often than this (default 10m)
   mincurrent: 6 # minimum charge current (default 6A)
   maxcurrent: 16 # maximum charge current (default 16A)
 
diff --git a/mock/mock_chargerhandler.go b/mock/mock_chargerhandler.go
index c4216f1a..ad86552b 100644
--- a/mock/mock_chargerhandler.go
+++ b/mock/mock_chargerhandler.go
@@ -60,22 +60,17 @@ func (mr *MockHandlerMockRecorder) Prepare() *gomock.Call {
 }
 
 // Ramp mocks base method
-func (m *MockHandler) Ramp(arg0 int64, arg1 ...bool) error {
+func (m *MockHandler) Ramp(arg0 int64, arg1 bool) error {
 	m.ctrl.T.Helper()
-	varargs := []interface{}{arg0}
-	for _, a := range arg1 {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "Ramp", varargs...)
+	ret := m.ctrl.Call(m, "Ramp", arg0, arg1)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // Ramp indicates an expected call of Ramp
-func (mr *MockHandlerMockRecorder) Ramp(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+func (mr *MockHandlerMockRecorder) Ramp(arg0, arg1 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{arg0}, arg1...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ramp", reflect.TypeOf((*MockHandler)(nil).Ramp), varargs...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ramp", reflect.TypeOf((*MockHandler)(nil).Ramp), arg0, arg1)
 }
 
 // Status mocks base method
@@ -93,16 +88,16 @@ func (mr *MockHandlerMockRecorder) Status() *gomock.Call {
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockHandler)(nil).Status))
 }
 
-// SyncEnabled mocks base method
-func (m *MockHandler) SyncEnabled() {
+// Sync mocks base method
+func (m *MockHandler) Sync() {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "SyncEnabled")
+	m.ctrl.Call(m, "Sync")
 }
 
-// SyncEnabled indicates an expected call of SyncEnabled
-func (mr *MockHandlerMockRecorder) SyncEnabled() *gomock.Call {
+// Sync indicates an expected call of Sync
+func (mr *MockHandlerMockRecorder) Sync() *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncEnabled", reflect.TypeOf((*MockHandler)(nil).SyncEnabled))
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sync", reflect.TypeOf((*MockHandler)(nil).Sync))
 }
 
 // TargetCurrent mocks base method


Test patch:
diff --git a/core/chargerhandler_test.go b/core/chargerhandler_test.go
index 32e9ea8c..316707ea 100644
--- a/core/chargerhandler_test.go
+++ b/core/chargerhandler_test.go
@@ -15,7 +15,6 @@ import (
 const (
 	minA          int64 = 6
 	maxA          int64 = 16
-	sensitivity         = 1
 	guardDuration       = 5 * time.Minute
 	dt                  = time.Hour
 )
@@ -29,7 +28,6 @@ func newChargerHandler(clock clock.Clock, mc api.Charger) *ChargerHandler {
 		HandlerConfig: HandlerConfig{
 			MinCurrent:    minA,
 			MaxCurrent:    maxA,
-			Sensitivity:   sensitivity,
 			GuardDuration: guardDuration,
 		},
 	}
@@ -53,9 +51,6 @@ func TestNewChargerHandler(t *testing.T) {
 	if r.MaxCurrent != maxA {
 		t.Errorf("expected %v, got %v", maxA, r.MaxCurrent)
 	}
-	if r.Sensitivity != 10 {
-		t.Errorf("expected %v, got %v", 10, r.Sensitivity)
-	}
 	if r.GuardDuration != guardDuration {
 		t.Errorf("expected %v, got %v", guardDuration, r.GuardDuration)
 	}
@@ -230,7 +225,7 @@ func TestRampOn(t *testing.T) {
 		tc.expect(mc)
 		clock.Add(tc.dt)
 
-		if err := r.rampOn(tc.targetCurrent); err != nil {
+		if err := r.Ramp(tc.targetCurrent, false); err != nil {
 			t.Error(err)
 		}
 
@@ -259,17 +254,21 @@ func TestRampOff(t *testing.T) {
 		}},
 		// on at min, disable
 		{true, minA, 0, func(mc *mock.MockCharger) {
-			// we are at min: current call omitted
 			// guard duration
 		}},
+		// on at min, set disable
 		{true, minA, dt, func(mc *mock.MockCharger) {
 			// we are at min: current call omitted
 			mc.EXPECT().Enable(false).Return(nil)
 		}},
-		// on at max, set min
+		// on at max, set disable
 		{true, maxA, 0, func(mc *mock.MockCharger) {
 			mc.EXPECT().MaxCurrent(minA).Return(nil)
-			// we are not at min: enable call omitted
+			// guard duration
+		}},
+		// on at max, set disable
+		{true, maxA, dt, func(mc *mock.MockCharger) {
+			mc.EXPECT().Enable(false).Return(nil)
 		}},
 	}
 
@@ -287,7 +286,7 @@ func TestRampOff(t *testing.T) {
 		tc.expect(mc)
 		clock.Add(tc.dt)
 
-		if err := r.rampOff(); err != nil {
+		if err := r.Ramp(0, false); err != nil {
 			t.Error(err)
 		}
 
@@ -314,11 +313,11 @@ func TestRampUpDown(t *testing.T) {
 		}},
 		// at min: set max
 		{minA, maxA, func(mc *mock.MockCharger) {
-			mc.EXPECT().MaxCurrent(minA + sensitivity).Return(nil)
+			mc.EXPECT().MaxCurrent(maxA).Return(nil)
 		}},
 		// at max: set min
 		{maxA, minA, func(mc *mock.MockCharger) {
-			mc.EXPECT().MaxCurrent(maxA - sensitivity).Return(nil)
+			mc.EXPECT().MaxCurrent(minA).Return(nil)
 		}},
 		// at max: set >max
 		{maxA, maxA + 100, func(mc *mock.MockCharger) {
@@ -339,7 +338,7 @@ func TestRampUpDown(t *testing.T) {
 
 		tc.expect(mc)
 
-		if err := h.rampUpDown(tc.targetCurrent); err != nil {
+		if err := h.Ramp(tc.targetCurrent, false); err != nil {
 			t.Error(err)
 		}
 
diff --git a/core/loadpoint_test.go b/core/loadpoint_test.go
index 600f4eb7..76630622 100644
--- a/core/loadpoint_test.go
+++ b/core/loadpoint_test.go
@@ -73,9 +73,6 @@ func TestNew(t *testing.T) {
 	if lp.MaxCurrent != lpMaxCurrent {
 		t.Errorf("MaxCurrent %v", lp.MaxCurrent)
 	}
-	if lp.Sensitivity != 10 {
-		t.Errorf("Sensitivity %v", lp.Sensitivity)
-	}
 	if lp.status != api.StatusNone {
 		t.Errorf("status %v", lp.status)
 	}
@@ -91,16 +88,16 @@ func TestUpdate(t *testing.T) {
 		expect func(h *mock.MockHandler)
 	}{
 		{api.StatusA, api.ModeOff, func(h *mock.MockHandler) {
-			h.EXPECT().Ramp(int64(0))
+			h.EXPECT().Ramp(int64(0), false)
 		}},
 		{api.StatusA, api.ModeNow, func(h *mock.MockHandler) {
-			h.EXPECT().Ramp(int64(0))
+			h.EXPECT().Ramp(int64(0), false)
 		}},
 		{api.StatusA, api.ModeMinPV, func(h *mock.MockHandler) {
-			h.EXPECT().Ramp(int64(0))
+			h.EXPECT().Ramp(int64(0), false)
 		}},
 		{api.StatusA, api.ModePV, func(h *mock.MockHandler) {
-			h.EXPECT().Ramp(int64(0)) // zero since update called with 0
+			h.EXPECT().Ramp(int64(0), false) // zero since update called with 0
 			// h.EXPECT().Enabled().Return(false) // short-circuited due to status != C
 		}},
 
@@ -170,7 +167,7 @@ func TestUpdate(t *testing.T) {
 		handler.EXPECT().TargetCurrent().Return(int64(0))
 
 		if tc.status != api.StatusA {
-			handler.EXPECT().SyncEnabled()
+			handler.EXPECT().Sync()
 
 			if tc.mode == api.ModeMinPV || tc.mode == api.ModePV {
 				handler.EXPECT().TargetCurrent().Return(int64(0))
@@ -413,7 +410,7 @@ func TestDisableAndEnableAtTargetSoC(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(6))
 	handler.EXPECT().Status().Return(api.StatusC, nil)
 	vehicle.EXPECT().ChargeState().Return(85.0, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().Ramp(int64(16), true).Return(nil)
 	lp.Update(500)
 
@@ -422,7 +419,7 @@ func TestDisableAndEnableAtTargetSoC(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(16))
 	handler.EXPECT().Status().Return(api.StatusC, nil)
 	vehicle.EXPECT().ChargeState().Return(90.0, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().Ramp(int64(0), true).Return(nil) // true due to immediately handling climate requests
 	lp.Update(500)
 
@@ -432,7 +429,7 @@ func TestDisableAndEnableAtTargetSoC(t *testing.T) {
 	handler.EXPECT().Status().Return(api.StatusB, nil)
 	handler.EXPECT().TargetCurrent().Return(int64(0)) // once more for status changes
 	vehicle.EXPECT().ChargeState().Return(95.0, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().Ramp(int64(0), true).Return(nil) // true due to immediately handling climate requests
 	lp.Update(-5000)
 
@@ -441,7 +438,7 @@ func TestDisableAndEnableAtTargetSoC(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(0))
 	handler.EXPECT().Status().Return(api.StatusB, nil)
 	vehicle.EXPECT().ChargeState().Return(85.0, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().Ramp(int64(16), true).Return(nil) // TODO don't treat this as forced change
 	lp.Update(-5000)
 
@@ -481,7 +478,7 @@ func TestSetModeAndSocAtDisconnect(t *testing.T) {
 	lp.Mode = api.ModeNow
 	handler.EXPECT().TargetCurrent().Return(int64(6))
 	handler.EXPECT().Status().Return(api.StatusC, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().Ramp(int64(16), true).Return(nil)
 	lp.Update(500)
 
@@ -489,7 +486,7 @@ func TestSetModeAndSocAtDisconnect(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(16))
 	handler.EXPECT().Status().Return(api.StatusA, nil)
 	handler.EXPECT().TargetCurrent().Return(int64(0)) // once more for status changes
-	handler.EXPECT().Ramp(int64(0)).Return(nil)
+	handler.EXPECT().Ramp(int64(0), false).Return(nil)
 	lp.Update(-3000)
 
 	if lp.Mode != api.ModeOff {
@@ -551,7 +548,7 @@ func TestChargedEnergyAtDisconnect(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(6))
 	rater.EXPECT().ChargedEnergy().Return(0.0, nil)
 	handler.EXPECT().Status().Return(api.StatusC, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().Ramp(int64(16), true).Return(nil)
 	lp.Update(-1)
 
@@ -560,7 +557,7 @@ func TestChargedEnergyAtDisconnect(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(16))
 	rater.EXPECT().ChargedEnergy().Return(5.0, nil)
 	handler.EXPECT().Status().Return(api.StatusC, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	// handler.EXPECT().TargetCurrent().Return(int64(0)) // once more for status changes
 	handler.EXPECT().Ramp(int64(16), true).Return(nil)
 	lp.Update(-1)
@@ -571,7 +568,7 @@ func TestChargedEnergyAtDisconnect(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(16))
 	rater.EXPECT().ChargedEnergy().Return(5.0, nil)
 	handler.EXPECT().Status().Return(api.StatusB, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().TargetCurrent().Return(int64(0)) // once more for status changes
 	handler.EXPECT().Ramp(int64(16), true).Return(nil)
 	lp.Update(-1)
@@ -582,7 +579,7 @@ func TestChargedEnergyAtDisconnect(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(16))
 	rater.EXPECT().ChargedEnergy().Return(5.0, nil)
 	handler.EXPECT().Status().Return(api.StatusC, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().TargetCurrent().Return(int64(0)) // once more for status changes
 	handler.EXPECT().Ramp(int64(16), true).Return(nil)
 	lp.Update(-1)
@@ -593,7 +590,7 @@ func TestChargedEnergyAtDisconnect(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(16))
 	rater.EXPECT().ChargedEnergy().Return(7.5, nil)
 	handler.EXPECT().Status().Return(api.StatusC, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	// handler.EXPECT().TargetCurrent().Return(int64(0)) // once more for status changes
 	handler.EXPECT().Ramp(int64(16), true).Return(nil)
 	lp.Update(-1)
@@ -604,7 +601,7 @@ func TestChargedEnergyAtDisconnect(t *testing.T) {
 	handler.EXPECT().TargetCurrent().Return(int64(16))
 	rater.EXPECT().ChargedEnergy().Return(10.0, nil)
 	handler.EXPECT().Status().Return(api.StatusB, nil)
-	handler.EXPECT().SyncEnabled().Return()
+	handler.EXPECT().Sync().Return()
 	handler.EXPECT().TargetCurrent().Return(int64(0)) // once more for status changes
 	handler.EXPECT().Ramp(int64(16), true).Return(nil)
 	lp.Update(-1)