Repository: evcc-io/evcc
Pull request #4111 (2022-08-14 14:08:59)

Disable detection by status for vehicles with defined id on id-capable chargers 
Refs https://github.com/evcc-io/evcc/discussions/3683#discussioncomment-3392957


Patch:
diff --git a/core/coordinator/adapter.go b/core/coordinator/adapter.go
index 74765cde..feda3229 100644
--- a/core/coordinator/adapter.go
+++ b/core/coordinator/adapter.go
@@ -31,6 +31,7 @@ func (a *adapter) Release(v api.Vehicle) {
 	a.c.release(v)
 }
 
-func (a *adapter) IdentifyVehicleByStatus() api.Vehicle {
-	return a.c.identifyVehicleByStatus(a.lp)
+func (a *adapter) IdentifyVehicleByStatus(includeIdCapable bool) api.Vehicle {
+	available := a.c.availableDetectibleVehicles(a.lp, includeIdCapable)
+	return a.c.identifyVehicleByStatus(available)
 }
diff --git a/core/coordinator/api.go b/core/coordinator/api.go
index 717ace62..49ddc0ce 100644
--- a/core/coordinator/api.go
+++ b/core/coordinator/api.go
@@ -7,5 +7,5 @@ type API interface {
 	GetVehicles() []api.Vehicle
 	Acquire(api.Vehicle)
 	Release(api.Vehicle)
-	IdentifyVehicleByStatus() api.Vehicle
+	IdentifyVehicleByStatus(includeIdCapable bool) api.Vehicle
 }
diff --git a/core/coordinator/coordinator.go b/core/coordinator/coordinator.go
index 32cdbd4c..ba572bc2 100644
--- a/core/coordinator/coordinator.go
+++ b/core/coordinator/coordinator.go
@@ -39,13 +39,18 @@ func (c *Coordinator) release(vehicle api.Vehicle) {
 
 // availableDetectibleVehicles is the list of vehicles that are currently not
 // associated to another loadpoint and have a status api that allows for detection
-func (c *Coordinator) availableDetectibleVehicles(owner loadpoint.API) []api.Vehicle {
+func (c *Coordinator) availableDetectibleVehicles(owner loadpoint.API, includeIdCapable bool) []api.Vehicle {
 	var res []api.Vehicle
 
 	for _, vv := range c.vehicles {
+		// status api available
 		if _, ok := vv.(api.ChargeState); ok {
+			// available or associated to current loadpoint
 			if o, ok := c.tracked[vv]; o == owner || !ok {
-				res = append(res, vv)
+				// no identifiers configured or identifiers ignored
+				if includeIdCapable || len(vv.Identifiers()) == 0 {
+					res = append(res, vv)
+				}
 			}
 		}
 	}
@@ -54,9 +59,7 @@ func (c *Coordinator) availableDetectibleVehicles(owner loadpoint.API) []api.Veh
 }
 
 // identifyVehicleByStatus finds active vehicle by charge state
-func (c *Coordinator) identifyVehicleByStatus(owner loadpoint.API) api.Vehicle {
-	available := c.availableDetectibleVehicles(owner)
-
+func (c *Coordinator) identifyVehicleByStatus(available []api.Vehicle) api.Vehicle {
 	var res api.Vehicle
 	for _, vehicle := range available {
 		if vs, ok := vehicle.(api.ChargeState); ok {
diff --git a/core/coordinator/dummy.go b/core/coordinator/dummy.go
index 6b75c05b..51d353c4 100644
--- a/core/coordinator/dummy.go
+++ b/core/coordinator/dummy.go
@@ -19,6 +19,6 @@ func (a *dummy) Acquire(v api.Vehicle) {}
 
 func (a *dummy) Release(v api.Vehicle) {}
 
-func (a *dummy) IdentifyVehicleByStatus() api.Vehicle {
+func (a *dummy) IdentifyVehicleByStatus(includeIdCapable bool) api.Vehicle {
 	return nil
 }
diff --git a/core/loadpoint.go b/core/loadpoint.go
index bae90aac..71f5ea01 100644
--- a/core/loadpoint.go
+++ b/core/loadpoint.go
@@ -908,7 +908,9 @@ func (lp *LoadPoint) identifyVehicleByStatus() {
 		return
 	}
 
-	if vehicle := lp.coordinator.IdentifyVehicleByStatus(); vehicle != nil {
+	_, ok := lp.charger.(api.Identifier)
+
+	if vehicle := lp.coordinator.IdentifyVehicleByStatus(!ok); vehicle != nil {
 		lp.setActiveVehicle(vehicle)
 		return
 	}


Test patch:
diff --git a/core/coordinator/coordinator_test.go b/core/coordinator/coordinator_test.go
index 4dfc80f3..9afe1584 100644
--- a/core/coordinator/coordinator_test.go
+++ b/core/coordinator/coordinator_test.go
@@ -38,6 +38,11 @@ func TestVehicleDetectByStatus(t *testing.T) {
 	log := util.NewLogger("foo")
 	vehicles := []api.Vehicle{v1, v2}
 
+	v1.MockVehicle.EXPECT().Title().Return("v1").AnyTimes()
+	v2.MockVehicle.EXPECT().Title().Return("v2").AnyTimes()
+	v1.MockVehicle.EXPECT().Identifiers().Return(nil).AnyTimes()
+	v2.MockVehicle.EXPECT().Identifiers().Return([]string{"it's me"}).AnyTimes()
+
 	var lp loadpoint.API
 	c := New(log, vehicles)
 
@@ -46,10 +51,9 @@ func TestVehicleDetectByStatus(t *testing.T) {
 
 		v1.MockChargeState.EXPECT().Status().Return(tc.v1, nil)
 		v2.MockChargeState.EXPECT().Status().Return(tc.v2, nil)
-		v1.MockVehicle.EXPECT().Title().Return("v1").AnyTimes()
-		v2.MockVehicle.EXPECT().Title().Return("v2").AnyTimes()
 
-		res := c.identifyVehicleByStatus(lp)
+		available := c.availableDetectibleVehicles(lp, true) // include id-able vehicles
+		res := c.identifyVehicleByStatus(available)
 		if tc.res != res {
 			t.Errorf("expected %v, got %v", tc.res, res)
 		}