Loadpoint: prefer exact status match for vehicle identification (#29591)

This commit is contained in:
Markus Kaindl 2026-06-07 17:25:50 +02:00 • committed by GitHub
parent 07a19d69a6
commit a1e62748e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 11 deletions

View file

@ -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)
}

View file

@ -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
}

View file

@ -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)
}