From df5dc0e74f1db4cb9ed5fa9cb66b73d17935941b Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 12 Jul 2026 19:07:18 +0200 Subject: [PATCH] EEBus: ignore IEC61851 default current limits, honor loadpoint minCurrent (#31737) --- charger/eebus-evse.go | 10 ++++++++++ charger/eebus_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/charger/eebus-evse.go b/charger/eebus-evse.go index 862db08df..43f608aa3 100644 --- a/charger/eebus-evse.go +++ b/charger/eebus-evse.go @@ -566,6 +566,16 @@ func (c *EEBus) minMax() (minMax, error) { return zero, nil } + // IEC61851 EVs can't report their current range, so the EVSE sends generic + // defaults (6/16A) that would override the loadpoint config; trust ISO only (#14418) + switch comStandard, err := c.cem.EvCC.CommunicationStandard(evEntity); { + case err != nil: + return zero, eebus.WrapError(err) + case comStandard != model.DeviceConfigurationKeyValueStringTypeISO151182ED1 && + comStandard != model.DeviceConfigurationKeyValueStringTypeISO151182ED2: + return zero, api.ErrNotAvailable + } + minLimits, maxLimits, _, err := c.cem.OpEV.CurrentLimits(evEntity) if err != nil { return zero, eebus.WrapError(err) diff --git a/charger/eebus_test.go b/charger/eebus_test.go index c1dd77040..950069bc2 100644 --- a/charger/eebus_test.go +++ b/charger/eebus_test.go @@ -442,3 +442,48 @@ func TestEEBusCurrentPower_Elli(t *testing.T) { require.NoError(t, err) assert.Equal(t, 4002.0, power) } + +// minMax must only trust EV current limits under ISO15118; IEC61851 EVs +// report EVSE defaults that would override the loadpoint config (#14418). +func TestEEBusMinMaxCommunicationStandard(t *testing.T) { + for _, tc := range []struct { + name string + standard model.DeviceConfigurationKeyValueStringType + iso bool + }{ + {"iec", model.DeviceConfigurationKeyValueStringTypeIEC61851, false}, + {"unknown", model.DeviceConfigurationKeyValueStringType("unknown"), false}, + {"iso", model.DeviceConfigurationKeyValueStringTypeISO151182ED2, true}, + } { + t.Run(tc.name, func(t *testing.T) { + evcc := mocks.NewCemEVCCInterface(t) + opev := mocks.NewCemOPEVInterface(t) + evEntity := spinemocks.NewEntityRemoteInterface(t) + + eebus := &EEBus{ + cem: &eebus.CustomerEnergyManagement{ + EvCC: evcc, + OpEV: opev, + }, + ev: evEntity, + log: util.NewLogger("test"), + } + + evcc.EXPECT().EVConnected(evEntity).Return(true) + evcc.EXPECT().CommunicationStandard(evEntity).Return(tc.standard, nil) + + if tc.iso { + opev.EXPECT().CurrentLimits(evEntity).Return(opevLimits3p(6, 16, 0)) + } + + mm, err := eebus.minMax() + if tc.iso { + require.NoError(t, err) + assert.Equal(t, 6.0, mm.min) + assert.Equal(t, 16.0, mm.max) + } else { + require.ErrorIs(t, err, api.ErrNotAvailable) + } + }) + } +}