From edbc31501b59f945eb4f7033ade924271e0181e2 Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 31 Jul 2021 10:48:27 +0200 Subject: [PATCH] ID: add error message and timestamp decoding to api (#1256) --- vehicle/id/api.go | 26 +++++++++++++++++--------- vehicle/id/provider.go | 3 +-- vehicle/id/types.go | 23 +++++++++++++++++++++++ 3 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 vehicle/id/types.go diff --git a/vehicle/id/api.go b/vehicle/id/api.go index d9bdbab59..457cca0d3 100644 --- a/vehicle/id/api.go +++ b/vehicle/id/api.go @@ -83,19 +83,27 @@ type Status struct { ClimatisationSettings ClimatisationSettings ClimatisationStatus ClimatisationStatus // may be currently not available } + Error map[string]Error +} + +// Error is the error status +type Error struct { + Code int + Message, Info string } // BatteryStatus is the /status.batteryStatus api type BatteryStatus struct { - CarCapturedTimestamp string + CarCapturedTimestamp Timestamp CurrentSOCPercent int `json:"currentSOC_pct"` CruisingRangeElectricKm int `json:"cruisingRangeElectric_km"` } // ChargingStatus is the /status.chargingStatus api type ChargingStatus struct { - CarCapturedTimestamp string - ChargingState string // readyForCharging + CarCapturedTimestamp Timestamp + ChargingState string // readyForCharging/off + ChargeMode string // invalid RemainingChargingTimeToCompleteMin int `json:"remainingChargingTimeToComplete_min"` ChargePowerKW float64 `json:"chargePower_kW"` ChargeRateKmph int `json:"chargeRate_kmph"` @@ -103,7 +111,7 @@ type ChargingStatus struct { // ChargingSettings is the /status.chargingSettings api type ChargingSettings struct { - CarCapturedTimestamp string + CarCapturedTimestamp Timestamp MaxChargeCurrentAC string // reduced, maximum AutoUnlockPlugWhenCharged string TargetSOCPercent int `json:"targetSOC_pct"` @@ -111,21 +119,21 @@ type ChargingSettings struct { // PlugStatus is the /status.plugStatus api type PlugStatus struct { - CarCapturedTimestamp string + CarCapturedTimestamp Timestamp PlugConnectionState string // connected, disconnected - PlugLockState string + PlugLockState string // locked, unlocked } // ClimatisationStatus is the /status.climatisationStatus api type ClimatisationStatus struct { - CarCapturedTimestamp string + CarCapturedTimestamp Timestamp RemainingClimatisationTimeMin int `json:"remainingClimatisationTime_min"` ClimatisationState string // off } // ClimatisationSettings is the /status.climatisationSettings api type ClimatisationSettings struct { - CarCapturedTimestamp string + CarCapturedTimestamp Timestamp TargetTemperatureK float64 `json:"targetTemperature_K"` TargetTemperatureC float64 `json:"targetTemperature_C"` ClimatisationWithoutExternalPower bool @@ -139,7 +147,7 @@ type ClimatisationSettings struct { // RangeStatus is the /status.rangeStatus api type RangeStatus struct { - CarCapturedTimestamp string + CarCapturedTimestamp Timestamp CarType string PrimaryEngine struct { Type string diff --git a/vehicle/id/provider.go b/vehicle/id/provider.go index fe4eff729..19c98275c 100644 --- a/vehicle/id/provider.go +++ b/vehicle/id/provider.go @@ -65,8 +65,7 @@ func (v *Provider) FinishTime() (time.Time, error) { res, err := v.statusG() if res, ok := res.(Status); err == nil && ok { cst := res.Data.ChargingStatus - timestamp, err := time.Parse(time.RFC3339, cst.CarCapturedTimestamp) - return timestamp.Add(time.Duration(cst.RemainingChargingTimeToCompleteMin) * time.Minute), err + return cst.CarCapturedTimestamp.Add(time.Duration(cst.RemainingChargingTimeToCompleteMin) * time.Minute), err } return time.Time{}, err diff --git a/vehicle/id/types.go b/vehicle/id/types.go new file mode 100644 index 000000000..05d20baab --- /dev/null +++ b/vehicle/id/types.go @@ -0,0 +1,23 @@ +package id + +import ( + "strings" + "time" +) + +// Timestamp implements JSON unmarshal for RFC3339 string timestamp +type Timestamp struct { + time.Time +} + +// UnmarshalJSON decodes RFC3339 string timestamp into time.Time +func (ct *Timestamp) UnmarshalJSON(data []byte) error { + s := strings.Trim(string(data), "\"") + + t, err := time.Parse(time.RFC3339, s) + if err == nil { + (*ct).Time = t + } + + return err +}