diff --git a/core/loadpoint.go b/core/loadpoint.go index f9fafee3f..d2948cfb7 100644 --- a/core/loadpoint.go +++ b/core/loadpoint.go @@ -1036,9 +1036,17 @@ func (lp *LoadPoint) identifyVehicleByStatus() { return } - _, ok := lp.charger.(api.Identifier) + // decide if id-able vehicles should be included https://github.com/evcc-io/evcc/pull/5469 + var ignoreIdCapable bool + if identifier, ok := lp.charger.(api.Identifier); ok { + id, err := identifier.Identify() + if err != nil { + lp.log.ERROR.Println("charger vehicle id:", err) + } + ignoreIdCapable = id != "" + } - if vehicle := lp.coordinator.IdentifyVehicleByStatus(!ok); vehicle != nil { + if vehicle := lp.coordinator.IdentifyVehicleByStatus(!ignoreIdCapable); vehicle != nil { lp.stopVehicleDetection() lp.setActiveVehicle(vehicle) return diff --git a/core/loadpoint_vehicle_test.go b/core/loadpoint_vehicle_test.go index afb9877bc..b21fdca67 100644 --- a/core/loadpoint_vehicle_test.go +++ b/core/loadpoint_vehicle_test.go @@ -315,75 +315,88 @@ func TestApplyVehicleDefaults(t *testing.T) { } func TestReconnectVehicle(t *testing.T) { - ctrl := gomock.NewController(t) - clck := clock.NewMock() - - type vehicleT struct { - *mock.MockVehicle - *mock.MockChargeState + tc := []struct { + name string + vehicleId []string + }{ + {"without vehicle id", nil}, + {"with vehicle id", []string{"foo"}}, } - vehicle := &vehicleT{mock.NewMockVehicle(ctrl), mock.NewMockChargeState(ctrl)} - vehicle.MockVehicle.EXPECT().Title().Return("vehicle").AnyTimes() - vehicle.MockVehicle.EXPECT().Icon().Return("").AnyTimes() - vehicle.MockVehicle.EXPECT().Capacity().AnyTimes() - vehicle.MockVehicle.EXPECT().Phases().AnyTimes() - vehicle.MockVehicle.EXPECT().OnIdentified().AnyTimes() - vehicle.MockVehicle.EXPECT().SoC().Return(0.0, nil).AnyTimes() + for _, tc := range tc { + t.Run(tc.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + clck := clock.NewMock() - charger := mock.NewMockCharger(ctrl) - charger.EXPECT().Status().Return(api.StatusB, nil).AnyTimes() + type vehicleT struct { + *mock.MockVehicle + *mock.MockChargeState + } - lp := &LoadPoint{ - log: util.NewLogger("foo"), - bus: evbus.New(), - clock: clck, - charger: charger, - chargeMeter: &Null{}, // silence nil panics - chargeRater: &Null{}, // silence nil panics - chargeTimer: &Null{}, // silence nil panics - wakeUpTimer: NewTimer(), - MinCurrent: minA, - MaxCurrent: maxA, - phases: 1, - Mode: api.ModeNow, - } + vehicle := &vehicleT{mock.NewMockVehicle(ctrl), mock.NewMockChargeState(ctrl)} + vehicle.MockVehicle.EXPECT().Title().Return("vehicle").AnyTimes() + vehicle.MockVehicle.EXPECT().Icon().Return("").AnyTimes() + vehicle.MockVehicle.EXPECT().Capacity().AnyTimes() + vehicle.MockVehicle.EXPECT().Phases().AnyTimes() + vehicle.MockVehicle.EXPECT().OnIdentified().AnyTimes() + vehicle.MockVehicle.EXPECT().Identifiers().AnyTimes().Return(tc.vehicleId) + vehicle.MockVehicle.EXPECT().SoC().Return(0.0, nil).AnyTimes() - lp.coordinator = coordinator.NewAdapter(lp, coordinator.New(util.NewLogger("foo"), []api.Vehicle{vehicle})) + charger := mock.NewMockCharger(ctrl) + charger.EXPECT().Status().Return(api.StatusB, nil).AnyTimes() - attachListeners(t, lp) + lp := &LoadPoint{ + log: util.NewLogger("foo"), + bus: evbus.New(), + clock: clck, + charger: charger, + chargeMeter: &Null{}, // silence nil panics + chargeRater: &Null{}, // silence nil panics + chargeTimer: &Null{}, // silence nil panics + wakeUpTimer: NewTimer(), + MinCurrent: minA, + MaxCurrent: maxA, + phases: 1, + Mode: api.ModeNow, + } - // mode now - charger.EXPECT().MaxCurrent(int64(maxA)) - // sync charger - charger.EXPECT().Enabled().Return(true, nil) + lp.coordinator = coordinator.NewAdapter(lp, coordinator.New(util.NewLogger("foo"), []api.Vehicle{vehicle})) - // vehicle not updated yet - vehicle.MockChargeState.EXPECT().Status().Return(api.StatusA, nil) + attachListeners(t, lp) - lp.Update(0, false, false) - ctrl.Finish() + // mode now + charger.EXPECT().MaxCurrent(int64(maxA)) + // sync charger + charger.EXPECT().Enabled().Return(true, nil) - // detection started - if lp.vehicleDetect != lp.clock.Now() { - t.Error("vehicle detection not started") - } + // vehicle not updated yet + vehicle.MockChargeState.EXPECT().Status().Return(api.StatusA, nil) - // vehicle not detected yet - if lp.vehicle != nil { - t.Error("vehicle should be ") - } + lp.Update(0, false, false) + ctrl.Finish() - // sync charger - charger.EXPECT().Enabled().Return(true, nil) - // vehicle not updated yet - vehicle.MockChargeState.EXPECT().Status().Return(api.StatusB, nil) + // detection started + if lp.vehicleDetect != lp.clock.Now() { + t.Error("vehicle detection not started") + } - lp.Update(0, false, false) - ctrl.Finish() + // vehicle not detected yet + if lp.vehicle != nil { + t.Error("vehicle should be ") + } - // vehicle detected - if lp.vehicle != vehicle { - t.Error("vehicle should be detected") + // sync charger + charger.EXPECT().Enabled().Return(true, nil) + // vehicle not updated yet + vehicle.MockChargeState.EXPECT().Status().Return(api.StatusB, nil) + + lp.Update(0, false, false) + ctrl.Finish() + + // vehicle detected + if lp.vehicle != vehicle { + t.Error("vehicle should be detected") + } + }) } }