Repository: evcc-io/evcc
Pull request #6651 (2023-03-05 21:21:26)

Fix merging action config overriding source values
Fix error introduced with https://github.com/evcc-io/evcc/commit/6ef578cc3eee1c00f92bd14d568938036c191d0f


Patch:
diff --git a/api/actionconfig.go b/api/actionconfig.go
index c5d37ced..0080a7b6 100644
--- a/api/actionconfig.go
+++ b/api/actionconfig.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/fatih/structs"
 	"github.com/imdario/mergo"
+	"github.com/jinzhu/copier"
 )
 
 // ActionConfig defines an action to take on event
@@ -22,10 +23,14 @@ type ActionConfig struct {
 // Merge merges all non-nil properties of the additional config into the base config.
 // The receiver's config remains immutable.
 func (a ActionConfig) Merge(m ActionConfig) ActionConfig {
-	if err := mergo.MergeWithOverwrite(&a, m); err != nil {
+	var res ActionConfig
+	if err := copier.Copy(&res, a); err != nil {
 		panic(err)
 	}
-	return a
+	if err := mergo.MergeWithOverwrite(&res, m); err != nil {
+		panic(err)
+	}
+	return res
 }
 
 // String implements Stringer and returns the ActionConfig as comma-separated key:value string


Test patch:
diff --git a/core/loadpoint_vehicle_test.go b/core/loadpoint_vehicle_test.go
index f13981f2..f3c9042f 100644
--- a/core/loadpoint_vehicle_test.go
+++ b/core/loadpoint_vehicle_test.go
@@ -170,7 +170,22 @@ func TestDefaultVehicle(t *testing.T) {
 
 	lp := NewLoadpoint(util.NewLogger("foo"))
 	lp.defaultVehicle = dflt
+
+	// ondisconnect
+	off := api.ModeOff
+	zero := 0
+	hundred := 100
+	onDisconnect := api.ActionConfig{
+		Mode:       &off,
+		MinCurrent: &lp.MinCurrent,
+		MaxCurrent: &lp.MaxCurrent,
+		MinSoc:     &zero,
+		TargetSoc:  &hundred,
+		Priority:   &zero,
+	}
+
 	lp.collectDefaults()
+	assert.Equal(t, lp.onDisconnect, onDisconnect)
 
 	// populate channels
 	x, y, z := createChannels(t)
@@ -185,47 +200,29 @@ func TestDefaultVehicle(t *testing.T) {
 
 	// non-default vehicle identified
 	lp.setActiveVehicle(vehicle)
-	if lp.vehicle != vehicle {
-		t.Errorf("expected %v, got %v", title(vehicle), title(lp.vehicle))
-	}
+	assert.Equal(t, vehicle, lp.vehicle, "expected vehicle "+title(vehicle))
 
 	// non-default vehicle disconnected
 	lp.evVehicleDisconnectHandler()
-	if lp.vehicle != dflt {
-		t.Errorf("expected %v, got %v", title(dflt), title(lp.vehicle))
-	}
+	assert.Equal(t, dflt, lp.vehicle, "expected default vehicle")
 
 	// default vehicle disconnected
 	lp.ResetOnDisconnect = true
 	lp.evVehicleDisconnectHandler()
-	if m := lp.GetMode(); m != mode {
-		t.Errorf("expected mode %v, got %v", mode, m)
-	}
-	if s := lp.GetMinSoc(); s != minsoc {
-		t.Errorf("expected minsoc %v, got %v", minsoc, s)
-	}
-	if s := lp.GetTargetSoc(); s != targetsoc {
-		t.Errorf("expected targetsoc %v, got %v", targetsoc, s)
-	}
-	if m := lp.onDisconnect.Mode; *m != api.ModeOff {
-		t.Errorf("expected ondisconnect mode %v, got %v", api.ModeOff, m)
-	}
+	assert.Equal(t, mode, lp.GetMode(), "mode")
+	assert.Equal(t, minsoc, lp.GetMinSoc(), "minsoc")
+	assert.Equal(t, targetsoc, lp.GetTargetSoc(), "targetsoc")
+	assert.Equal(t, lp.onDisconnect, onDisconnect, "ondisconnect must remain untouched")
 
 	// set non-default vehicle during disconnect - should be default on connect
 	lp.tasks.Clear()
 	lp.evVehicleConnectHandler()
-	if lp.vehicle != dflt {
-		t.Errorf("expected %v, got %v", title(dflt), title(lp.vehicle))
-	}
-	if l := lp.tasks.Size(); l != 1 {
-		t.Error("expected task in queue, got none")
-	}
+	assert.Equal(t, dflt, lp.vehicle, "expected default vehicle")
+	assert.Equal(t, 1, lp.tasks.Size(), "task queue length")
 
 	// guest connected
 	lp.setActiveVehicle(nil)
-	if lp.vehicle != nil {
-		t.Errorf("expected %v, got %v", nil, title(lp.vehicle))
-	}
+	assert.Nil(t, lp.vehicle, "expected no vehicle")
 }
 
 func TestApplyVehicleDefaults(t *testing.T) {