Cupra: keep plugged "NotReadyForCharging" as connected status (#30140)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
andig 2026-05-23 10:28:45 +02:00 • committed by GitHub
parent 55dd26b3c0
commit 18cadfa7a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 1 deletions

View file

@ -66,13 +66,17 @@ func (v *Provider) Status() (api.ChargeStatus, error) {
return api.StatusNone, err
}
// BatteryCardStatus is the authoritative disconnect signal — the Cupra API
// only emits "notConnected" when the cable is unplugged. When the car is
// plugged the field is omitted and Status alone is unreliable: it reports
// "NotReadyForCharging" both for an unplugged car.
// https://github.com/evcc-io/evcc/issues/30045
if strings.ToLower(res.Services.Charging.BatteryCardStatus) == "notconnected" {
return api.StatusA, nil
}
switch strings.ToLower(res.Services.Charging.Status) {
case "connected", "readyforcharging", "error":
case "connected", "readyforcharging", "notreadyforcharging", "error":
return api.StatusB, nil
case "charging":
return api.StatusC, nil

View file

@ -0,0 +1,53 @@
package cupra
import (
"testing"
"github.com/evcc-io/evcc/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestProviderStatus covers the Cupra v5 charging-status payload variants
// captured in issues #30045 and #30118.
func TestProviderStatus(t *testing.T) {
cases := []struct {
name string
statusField string
batteryCardStatus string
want api.ChargeStatus
}{
// cable not plugged in: API emits batteryCardStatus=notConnected
{"unplugged", "NotReadyForCharging", "notConnected", api.StatusA},
// charging: API omits batteryCardStatus
{"charging", "Charging", "", api.StatusC},
// plugged but not charging (e.g. chargeMode=off): API omits
// batteryCardStatus, Status reports NotReadyForCharging — must NOT be
// misread as disconnected (#30118)
{"plugged_paused", "NotReadyForCharging", "", api.StatusB},
// plugged, ready to charge but not yet started
{"ready", "ReadyForCharging", "", api.StatusB},
// already-connected pre-v5 payload
{"connected", "Connected", "", api.StatusB},
// fault / error while plugged
{"error", "error", "", api.StatusB},
// unknown future status with no card info defaults to disconnected
{"unknown", "SomethingNew", "", api.StatusA},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
var s Status
s.Services.Charging.Status = tc.statusField
s.Services.Charging.BatteryCardStatus = tc.batteryCardStatus
v := &Provider{
statusG: func() (Status, error) { return s, nil },
}
got, err := v.Status()
require.NoError(t, err)
assert.Equal(t, tc.want, got)
})
}
}