From 577df71d0ba40ee972c6b82f14282384e8af4cea Mon Sep 17 00:00:00 2001 From: andig Date: Tue, 15 Sep 2020 07:57:46 +0200 Subject: [PATCH] Fix bluelink no longer working for Hyundai(#343) * Consolidate bluelink default configuration --- go.mod | 1 + go.sum | 2 + vehicle/bluelink/bluelink.go | 76 +++++++++++++++++++++++------------- vehicle/hyundai.go | 7 ---- vehicle/kia.go | 7 ---- 5 files changed, 51 insertions(+), 42 deletions(-) diff --git a/go.mod b/go.mod index 3861fe7d50..5f655a411e 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/gregdel/pushover v0.0.0-20200416074932-c8ad547caed4 github.com/grid-x/modbus v0.0.0-20200831145459-cb26bc3b5d3d // indirect github.com/hashicorp/go-version v1.2.1 + github.com/imdario/mergo v0.3.11 github.com/influxdata/influxdb-client-go/v2 v2.0.1 github.com/itchyny/gojq v0.11.0 github.com/joeshaw/carwings v0.0.0-20191118152321-61b46581307a diff --git a/go.sum b/go.sum index b3b4bd5a38..e45469b7b6 100644 --- a/go.sum +++ b/go.sum @@ -184,6 +184,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb-client-go v1.4.0 h1:+KavOkwhLClHFfYcJMHHnTL5CZQhXJzOm5IKHI9BqJk= diff --git a/vehicle/bluelink/bluelink.go b/vehicle/bluelink/bluelink.go index d52b2f8882..8dac973621 100644 --- a/vehicle/bluelink/bluelink.go +++ b/vehicle/bluelink/bluelink.go @@ -15,6 +15,7 @@ import ( "github.com/andig/evcc/provider" "github.com/andig/evcc/util" "github.com/google/uuid" + "github.com/imdario/mergo" "golang.org/x/net/publicsuffix" ) @@ -23,7 +24,19 @@ const ( resAuthFail = "F" ) -var errAuthFail = errors.New("authorization failed") +var ( + errAuthFail = errors.New("authorization failed") + + defaults = Config{ + DeviceID: "/api/v1/spa/notifications/register", + Lang: "/api/v1/user/language", + Login: "/api/v1/user/signin", + AccessToken: "/api/v1/user/oauth2/token", + Vehicles: "/api/v1/spa/vehicles", + SendPIN: "/api/v1/user/pin", + GetStatus: "/api/v2/spa/vehicles/", + } +) // Config is the bluelink API configuration type Config struct { @@ -40,7 +53,8 @@ type Config struct { GetStatus string } -// API is an api.Vehicle implementation with configurable getters and setters. +// API implements the Kia/Hyundai bluelink api. +// Based on https://github.com/Hacksore/bluelinky. type API struct { *util.HTTPHelper user string @@ -59,23 +73,24 @@ type Auth struct { } type response struct { - RetCode string `json:"retCode"` + RetCode string ResMsg struct { - DeviceID string `json:"deviceId"` + DeviceID string EvStatus struct { - BatteryStatus float64 `json:"batteryStatus"` - } `json:"evStatus"` + BatteryStatus float64 + } Vehicles []struct { - VehicleID string `json:"vehicleId"` - } `json:"vehicles"` - } `json:"resMsg"` + VehicleID string + } + } } // New creates a new BlueLink API -func New(log *util.Logger, - user, password, pin string, cache time.Duration, - config Config, -) (*API, error) { +func New(log *util.Logger, user, password, pin string, cache time.Duration, config Config) (*API, error) { + if err := mergo.Merge(&config, defaults); err != nil { + return nil, err + } + v := &API{ HTTPHelper: util.NewHTTPHelper(log), config: config, @@ -303,13 +318,7 @@ func (v *API) sendPIN(deviceID, accToken string) (string, error) { _, err = v.RequestJSON(req, &token) } - controlToken := "" - if err == nil { - controlToken = "Bearer " + token.ControlToken - - } - - return controlToken, err + return token.ControlToken, err } func (v *API) authFlow() (err error) { @@ -324,34 +333,38 @@ func (v *API) authFlow() (err error) { err = v.setLanguage(cookieClient) } - var kiaAccCode string + var accCode string if err == nil { - kiaAccCode, err = v.login(cookieClient) + accCode, err = v.login(cookieClient) } - var kiaAccToken string + var accToken string if err == nil { - kiaAccToken, err = v.getToken(kiaAccCode) + accToken, err = v.getToken(accCode) } if err == nil { - v.auth.vehicleID, err = v.getVehicles(kiaAccToken, v.auth.deviceID) + v.auth.vehicleID, err = v.getVehicles(accToken, v.auth.deviceID) } if err == nil { - err = v.preWakeup(kiaAccToken, v.auth.deviceID, v.auth.vehicleID) + err = v.preWakeup(accToken, v.auth.deviceID, v.auth.vehicleID) } if err == nil { - v.auth.controlToken, err = v.sendPIN(v.auth.deviceID, kiaAccToken) + v.auth.controlToken, err = v.sendPIN(v.auth.deviceID, accToken) } return err } func (v *API) getStatus() (float64, error) { + if v.auth.controlToken == "" { + return 0, errAuthFail + } + headers := map[string]string{ - "Authorization": v.auth.controlToken, + "Authorization": "Bearer " + v.auth.controlToken, "ccsp-device-id": v.auth.deviceID, "Content-Type": "application/json", } @@ -362,6 +375,13 @@ func (v *API) getStatus() (float64, error) { if err == nil { _, err = v.RequestJSON(req, &resp) + if err != nil { + resp := v.LastResponse() + if resp != nil && resp.StatusCode == http.StatusForbidden { + err = errAuthFail + } + } + if err == nil && resp.RetCode != resOK { err = errors.New("unexpected response") if resp.RetCode == resAuthFail { diff --git a/vehicle/hyundai.go b/vehicle/hyundai.go index 3ef427e436..106c971b84 100644 --- a/vehicle/hyundai.go +++ b/vehicle/hyundai.go @@ -37,13 +37,6 @@ func NewHyundaiFromConfig(other map[string]interface{}) (api.Vehicle, error) { TokenAuth: "NmQ0NzdjMzgtM2NhNC00Y2YzLTk1NTctMmExOTI5YTk0NjU0OktVeTQ5WHhQekxwTHVvSzB4aEJDNzdXNlZYaG10UVI5aVFobUlGampvWTRJcHhzVg==", CCSPServiceID: "6d477c38-3ca4-4cf3-9557-2a1929a94654", CCSPApplicationID: "99cfff84-f4e2-4be8-a5ed-e5b755eb6581", - DeviceID: "/api/v1/spa/notifications/register", - Lang: "/api/v1/user/language", - Login: "/api/v1/user/signin", - AccessToken: "/api/v1/user/oauth2/token", - Vehicles: "/api/v1/spa/vehicles", - SendPIN: "/api/v1/user/pin", - GetStatus: "/api/v2/spa/vehicles/", } log := util.NewLogger("hyundai") diff --git a/vehicle/kia.go b/vehicle/kia.go index e82ee5e731..2cbb4ecae3 100644 --- a/vehicle/kia.go +++ b/vehicle/kia.go @@ -37,13 +37,6 @@ func NewKiaFromConfig(other map[string]interface{}) (api.Vehicle, error) { TokenAuth: "ZmRjODVjMDAtMGEyZi00YzY0LWJjYjQtMmNmYjE1MDA3MzBhOnNlY3JldA==", CCSPServiceID: "fdc85c00-0a2f-4c64-bcb4-2cfb1500730a", CCSPApplicationID: "693a33fa-c117-43f2-ae3b-61a02d24f417", - DeviceID: "/api/v1/spa/notifications/register", - Lang: "/api/v1/user/language", - Login: "/api/v1/user/signin", - AccessToken: "/api/v1/user/oauth2/token", - Vehicles: "/api/v1/spa/vehicles", - SendPIN: "/api/v1/user/pin", - GetStatus: "/api/v2/spa/vehicles/", } log := util.NewLogger("kia")