From 4b286148daca0241b4c3f7fe276b7367dd8f8a8f Mon Sep 17 00:00:00 2001 From: andig Date: Thu, 8 Dec 2022 13:24:29 +0100 Subject: [PATCH] Audi eTron: fix soc and range on hybrid vehicles --- vehicle/vw/id/provider.go | 16 +++++++----- vehicle/vw/id/types.go | 54 ++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/vehicle/vw/id/provider.go b/vehicle/vw/id/provider.go index 971abfec1..f6c5d97b3 100644 --- a/vehicle/vw/id/provider.go +++ b/vehicle/vw/id/provider.go @@ -33,12 +33,14 @@ var _ api.Battery = (*Provider)(nil) // SoC implements the api.Vehicle interface func (v *Provider) SoC() (float64, error) { res, err := v.statusG() - if err == nil && res.FuelStatus == nil { - err = errors.New("missing fuel status") + + var eng EngineRangeStatus + if err == nil { + eng, err = res.FuelStatus.EngineRangeStatus("electric") } if err == nil { - return float64(res.FuelStatus.RangeStatus.Value.PrimaryEngine.CurrentSOCPct), nil + return float64(eng.CurrentSOCPct), nil } return 0, err @@ -88,12 +90,14 @@ var _ api.VehicleRange = (*Provider)(nil) // Range implements the api.VehicleRange interface func (v *Provider) Range() (int64, error) { res, err := v.statusG() - if err == nil && res.FuelStatus == nil { - err = errors.New("missing fuel status") + + var eng EngineRangeStatus + if err == nil { + eng, err = res.FuelStatus.EngineRangeStatus("electric") } if err == nil { - return int64(res.FuelStatus.RangeStatus.Value.TotalRangeKm), nil + return int64(eng.RemainingRangeKm), nil } return 0, err diff --git a/vehicle/vw/id/types.go b/vehicle/vw/id/types.go index 9d66d1e20..c9887b47a 100644 --- a/vehicle/vw/id/types.go +++ b/vehicle/vw/id/types.go @@ -1,6 +1,8 @@ package id import ( + "errors" + "fmt" "strings" "time" ) @@ -153,21 +155,8 @@ type Status struct { } `json:"value"` } `json:"climatisationTimersStatus"` } `json:"climatisationTimers"` - FuelStatus *struct { - RangeStatus struct { - Value struct { - CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` - CarType string `json:"carType"` - PrimaryEngine struct { - Type string `json:"type"` - CurrentSOCPct int `json:"currentSOC_pct"` - RemainingRangeKm int `json:"remainingRange_km"` - } `json:"primaryEngine"` - TotalRangeKm int `json:"totalRange_km"` - } `json:"value"` - } `json:"rangeStatus"` - } `json:"fuelStatus"` - Readiness *struct { + FuelStatus *FuelStatus `json:"fuelStatus"` + Readiness *struct { ReadinessStatus struct { Value struct { ConnectionState struct { @@ -194,6 +183,41 @@ type Status struct { } `json:"chargingProfiles"` } +// FuelStatus is the engine range status +type FuelStatus struct { + RangeStatus struct { + Value struct { + CarCapturedTimestamp Timestamp `json:"carCapturedTimestamp"` + CarType string `json:"carType"` + PrimaryEngine EngineRangeStatus `json:"primaryEngine"` + SecondaryEngine EngineRangeStatus `json:"secondaryEngine"` + TotalRangeKm int `json:"totalRange_km"` + } `json:"value"` + } `json:"rangeStatus"` +} + +func (f *FuelStatus) EngineRangeStatus(typ string) (EngineRangeStatus, error) { + if f == nil { + return EngineRangeStatus{}, errors.New("missing fuel status") + } + + if f.RangeStatus.Value.PrimaryEngine.Type == typ { + return f.RangeStatus.Value.PrimaryEngine, nil + } + if f.RangeStatus.Value.SecondaryEngine.Type == typ { + return f.RangeStatus.Value.SecondaryEngine, nil + } + + return EngineRangeStatus{}, fmt.Errorf("unknown engine type: %s", typ) +} + +// EngineRangeStatus is the engine range status +type EngineRangeStatus struct { + Type string `json:"type"` + CurrentSOCPct int `json:"currentSOC_pct"` + RemainingRangeKm int `json:"remainingRange_km"` +} + // Timestamp implements JSON unmarshal type Timestamp struct { time.Time