diff --git a/core/coordinator/adapter.go b/core/coordinator/adapter.go index e70082816..00ed0b47f 100644 --- a/core/coordinator/adapter.go +++ b/core/coordinator/adapter.go @@ -37,5 +37,6 @@ func (a *adapter) Release(v api.Vehicle) { func (a *adapter) IdentifyVehicleByStatus() api.Vehicle { available := a.c.availableDetectibleVehicles(a.lp) - return a.c.identifyVehicleByStatus(available) + status := a.lp.GetStatus() + return a.c.identifyVehicleByStatus(available, status) } diff --git a/core/coordinator/coordinator.go b/core/coordinator/coordinator.go index bd5043cb7..531baaca2 100644 --- a/core/coordinator/coordinator.go +++ b/core/coordinator/coordinator.go @@ -128,8 +128,9 @@ func (c *Coordinator) availableDetectibleVehicles(owner loadpoint.API) []api.Veh } // identifyVehicleByStatus finds active vehicle by charge state -func (c *Coordinator) identifyVehicleByStatus(available []api.Vehicle) api.Vehicle { - var res api.Vehicle +func (c *Coordinator) identifyVehicleByStatus(available []api.Vehicle, lpStatus api.ChargeStatus) api.Vehicle { + var exactMatch api.Vehicle + var approximateMatches []api.Vehicle c.mu.RLock() defer c.mu.RUnlock() @@ -146,17 +147,32 @@ func (c *Coordinator) identifyVehicleByStatus(available []api.Vehicle) api.Vehic c.log.DEBUG.Printf("vehicle status: %s (%s)", status, vehicle.GetTitle()) - // vehicle is plugged or charging, so it should be the right one + // vehicle is plugged or charging and has the same state as the charger, so it should be the right one if status == api.StatusB || status == api.StatusC { - if res != nil { - c.log.WARN.Println("vehicle status: >1 matches, giving up") - return nil - } + if status == lpStatus { + if exactMatch != nil { + c.log.WARN.Println("vehicle status: >1 matches, giving up") + return nil + } - res = vehicle + exactMatch = vehicle + } else { + // vehicle is plugged or charging, so it should be the right one if there is no exact match + approximateMatches = append(approximateMatches, vehicle) + } } } } - return res + if exactMatch != nil { + return exactMatch + } + if len(approximateMatches) == 1 { + return approximateMatches[0] + } + if len(approximateMatches) > 1 { + c.log.WARN.Println("vehicle status: >1 matches, giving up") + } + + return nil } diff --git a/core/coordinator/coordinator_test.go b/core/coordinator/coordinator_test.go index ce5016840..b92a3e09e 100644 --- a/core/coordinator/coordinator_test.go +++ b/core/coordinator/coordinator_test.go @@ -31,7 +31,14 @@ func TestVehicleDetectByStatus(t *testing.T) { {"B/A->1", api.StatusB, api.StatusA, v1}, {"A/B->2", api.StatusA, api.StatusB, v2}, {"A/B->2", api.StatusA, api.StatusB, v2}, + {"A/C->2", api.StatusA, api.StatusC, v2}, + {"A/C->2", api.StatusA, api.StatusC, v2}, {"B/B->1", api.StatusB, api.StatusB, nil}, + {"B/C->1", api.StatusB, api.StatusC, v1}, + {"B/C->1", api.StatusB, api.StatusC, v1}, + {"C/B->2", api.StatusC, api.StatusB, v2}, + {"C/B->2", api.StatusC, api.StatusB, v2}, + {"C/C->1", api.StatusC, api.StatusC, nil}, } log := util.NewLogger("foo") @@ -52,7 +59,7 @@ func TestVehicleDetectByStatus(t *testing.T) { v2.MockChargeState.EXPECT().Status().Return(tc.v2, nil) available := c.availableDetectibleVehicles(lp) // include id-able vehicles - res := c.identifyVehicleByStatus(available) + res := c.identifyVehicleByStatus(available, api.StatusB) if tc.res != res { t.Errorf("expected %v, got %v", tc.res, res) }