From 6dd353b6139b260ba094bbb6d1cfd3eed8e1eb44 Mon Sep 17 00:00:00 2001 From: andig Date: Thu, 1 Apr 2021 19:11:08 +0200 Subject: [PATCH] Unserialize temperature (#832) --- internal/vehicle/vw/api.go | 29 ------------------ internal/vehicle/vw/provider.go | 7 ++--- internal/vehicle/vw/types.go | 50 +++++++++++++++++++++++++++++++ internal/vehicle/vw/types_test.go | 29 ++++++++++++++++++ 4 files changed, 82 insertions(+), 33 deletions(-) create mode 100644 internal/vehicle/vw/types.go create mode 100644 internal/vehicle/vw/types_test.go diff --git a/internal/vehicle/vw/api.go b/internal/vehicle/vw/api.go index dd8dfdd09..a6dc57f7e 100644 --- a/internal/vehicle/vw/api.go +++ b/internal/vehicle/vw/api.go @@ -2,7 +2,6 @@ package vw import ( "fmt" - "math" "net/http" "strings" @@ -17,34 +16,6 @@ const DefaultBaseURI = "https://msg.volkswagen.de/fs-car" // RegionAPI is the VW api used for determining the home region const RegionAPI = "https://mal-1a.prd.ece.vwg-connect.com/api" -// TimedInt is an int value with timestamp -type TimedInt struct { - Content int - Timestamp string -} - -// TimedString is a string value with timestamp -type TimedString struct { - Content string - Timestamp string -} - -// TimedTemperature is a interface to handle api temp (float + string) values with timestamp -type TimedTemperature struct { - Content interface{} `json:"content"` - Timestamp string -} - -// Temp2Float converts api temp to float value -func Temp2Float(i interface{}) float64 { - switch i := i.(type) { - case float64: - return (i)/10 - 273 - default: - return math.NaN() - } -} - // API is the VW api client type API struct { *request.Helper diff --git a/internal/vehicle/vw/provider.go b/internal/vehicle/vw/provider.go index 5e6211f77..3d2d10b8c 100644 --- a/internal/vehicle/vw/provider.go +++ b/internal/vehicle/vw/provider.go @@ -105,11 +105,10 @@ func (v *Provider) Climater() (active bool, outsideTemp float64, targetTemp floa state := strings.ToLower(res.Climater.Status.ClimatisationStatusData.ClimatisationState.Content) active := state != "off" && state != "invalid" && state != "error" - targetTemp = Temp2Float(res.Climater.Settings.TargetTemperature.Content) - - outsideTemp = Temp2Float(res.Climater.Status.TemperatureStatusData.OutdoorTemperature.Content) + targetTemp = res.Climater.Settings.TargetTemperature.Content + outsideTemp = res.Climater.Status.TemperatureStatusData.OutdoorTemperature.Content if math.IsNaN(outsideTemp) { - outsideTemp = targetTemp // to cover "invalid" json content and avoid wrong climater behaviour + outsideTemp = targetTemp // cover "invalid" } return active, outsideTemp, targetTemp, nil diff --git a/internal/vehicle/vw/types.go b/internal/vehicle/vw/types.go new file mode 100644 index 000000000..d04ec3bfb --- /dev/null +++ b/internal/vehicle/vw/types.go @@ -0,0 +1,50 @@ +package vw + +import ( + "encoding/json" + "math" + "strconv" +) + +// TimedInt is an int value with timestamp +type TimedInt struct { + Content int + Timestamp string +} + +// TimedString is a string value with timestamp +type TimedString struct { + Content string + Timestamp string +} + +// TimedTemperature is the api temperature with timestamp +type TimedTemperature struct { + Content float64 + Timestamp string +} + +func (t *TimedTemperature) UnmarshalJSON(data []byte) error { + var temp struct { + Content json.RawMessage // handle "invalid" + Timestamp string + } + + err := json.Unmarshal(data, &temp) + if err == nil { + (*t).Timestamp = temp.Timestamp + + if val, err := strconv.Atoi(string(temp.Content)); err == nil { + (*t).Content = temp2Float(val) + } else { + (*t).Content = math.NaN() + } + } + + return err +} + +// temp2Float converts api temp to float value +func temp2Float(i int) float64 { + return float64(i)/10 - 273 +} diff --git a/internal/vehicle/vw/types_test.go b/internal/vehicle/vw/types_test.go new file mode 100644 index 000000000..c1ddddbf0 --- /dev/null +++ b/internal/vehicle/vw/types_test.go @@ -0,0 +1,29 @@ +package vw + +import ( + "encoding/json" + "math" + "testing" +) + +func TestTemp(t *testing.T) { + data := `[{ + "content": 2930, + "timestamp": "time" + }, { + "content": "invalid", + "timestamp": "time" + }]` + + var temps []TimedTemperature + if err := json.Unmarshal([]byte(data), &temps); err != nil { + t.Error(err) + } else { + if v := temps[0].Content; v != 20 { + t.Error("invalid temp 0", v) + } + if v := temps[1].Content; !math.IsNaN(v) { + t.Error("invalid temp 1", v) + } + } +}