Hyundai Bluelink: add Australia and New Zealand regions (#30037)
This commit is contained in:
parent
42f4281e68
commit
a05eb42ffd
3 changed files with 83 additions and 20 deletions
|
|
@ -16,7 +16,14 @@ requirements:
|
|||
params:
|
||||
- preset: vehicle-base
|
||||
- preset: vehicle-language
|
||||
- name: region
|
||||
default: Europe
|
||||
choice: ["Europe", "Australia", "New Zealand"]
|
||||
description:
|
||||
en: Region your Bluelink account is registered in
|
||||
de: Region, in der dein Bluelink-Konto registriert ist
|
||||
render: |
|
||||
type: hyundai
|
||||
region: {{ .region }}
|
||||
{{ include "vehicle-base" . }}
|
||||
{{ include "vehicle-language" . }}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package vehicle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
|
|
@ -25,16 +27,46 @@ func init() {
|
|||
|
||||
// NewHyundaiFromConfig creates a new vehicle
|
||||
func NewHyundaiFromConfig(other map[string]any) (api.Vehicle, error) {
|
||||
settings := bluelink.Config{
|
||||
URI: "https://prd.eu-ccapi.hyundai.com:8080",
|
||||
CCSPServiceID: "6d477c38-3ca4-4cf3-9557-2a1929a94654",
|
||||
CCSPServiceSecret: "KUy49XxPzLpLuoK0xhBC77W6VXhmtQR9iQhmIFjjoY4IpxsV",
|
||||
CCSPApplicationID: "014d2225-8495-4735-812d-2616334fd15d",
|
||||
Cfb: "RFtoRq/vDXJmRndoZaZQyfOot7OrIqGVFj96iY2WL3yyH5Z/pUvlUhqmCxD2t+D65SQ=",
|
||||
BasicToken: "NmQ0NzdjMzgtM2NhNC00Y2YzLTk1NTctMmExOTI5YTk0NjU0OktVeTQ5WHhQekxwTHVvSzB4aEJDNzdXNlZYaG10UVI5aVFobUlGampvWTRJcHhzVg==",
|
||||
PushType: "GCM",
|
||||
LoginFormHost: "https://idpconnect-eu.hyundai.com",
|
||||
Brand: "hyundai",
|
||||
// Decode region early so we can select the right config
|
||||
cc := struct {
|
||||
Region string
|
||||
}{
|
||||
Region: "Europe",
|
||||
}
|
||||
if region, ok := other["region"].(string); ok {
|
||||
cc.Region = strings.TrimSpace(region)
|
||||
}
|
||||
|
||||
var settings bluelink.Config
|
||||
switch strings.ToLower(cc.Region) {
|
||||
case "europe", "":
|
||||
settings = bluelink.Config{
|
||||
URI: "https://prd.eu-ccapi.hyundai.com:8080",
|
||||
CCSPServiceID: "6d477c38-3ca4-4cf3-9557-2a1929a94654",
|
||||
CCSPServiceSecret: "KUy49XxPzLpLuoK0xhBC77W6VXhmtQR9iQhmIFjjoY4IpxsV",
|
||||
CCSPApplicationID: "014d2225-8495-4735-812d-2616334fd15d",
|
||||
Cfb: "RFtoRq/vDXJmRndoZaZQyfOot7OrIqGVFj96iY2WL3yyH5Z/pUvlUhqmCxD2t+D65SQ=",
|
||||
BasicToken: "NmQ0NzdjMzgtM2NhNC00Y2YzLTk1NTctMmExOTI5YTk0NjU0OktVeTQ5WHhQekxwTHVvSzB4aEJDNzdXNlZYaG10UVI5aVFobUlGampvWTRJcHhzVg==",
|
||||
PushType: "GCM",
|
||||
LoginFormHost: "https://idpconnect-eu.hyundai.com",
|
||||
Brand: "hyundai",
|
||||
}
|
||||
case "australia", "new zealand":
|
||||
settings = bluelink.Config{
|
||||
URI: bluelink.HyundaiAUBaseURI,
|
||||
CCSPServiceID: bluelink.HyundaiAUCCSPServiceID,
|
||||
CCSPServiceSecret: "e6fbwHM32YNbhQl0pviaPp3rf4t3S6k91eceA3MJLdbdThCO",
|
||||
CCSPApplicationID: bluelink.HyundaiAUCCSPAppID,
|
||||
Cfb: bluelink.HyundaiAUCfb,
|
||||
BasicToken: bluelink.HyundaiAUBasicToken,
|
||||
PushType: "GCM",
|
||||
LoginFormHost: bluelink.HyundaiAUBaseURI,
|
||||
TokenURL: "/api/v1/user/oauth2/token",
|
||||
Brand: "hyundai",
|
||||
UseBasicAuth: true,
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown region: %s", cc.Region)
|
||||
}
|
||||
|
||||
return newBluelinkFromConfig("hyundai", other, settings)
|
||||
|
|
@ -82,6 +114,7 @@ func newBluelinkFromConfig(brand string, other map[string]any, settings bluelink
|
|||
User, Password string
|
||||
VIN string
|
||||
Language string
|
||||
Region string
|
||||
Expiry time.Duration
|
||||
Cache time.Duration
|
||||
}{
|
||||
|
|
|
|||
|
|
@ -20,12 +20,15 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
DeviceIdURL = "/api/v1/spa/notifications/register"
|
||||
IntegrationInfoURL = "/api/v1/user/integrationinfo"
|
||||
SilentSigninURL = "/api/v1/user/silentsignin"
|
||||
LanguageURL = "/api/v1/user/language"
|
||||
LoginURL = "/api/v1/user/signin"
|
||||
TokenURL = "/auth/api/v2/user/oauth2/token"
|
||||
LanguageURL = "/api/v1/user/language"
|
||||
LoginURL = "/api/v1/user/signin"
|
||||
TokenURL = "/auth/api/v2/user/oauth2/token"
|
||||
// AU region constants (sourced from hyundai_kia_connect_api KiaUvoApiAU.py)
|
||||
HyundaiAUBaseURI = "https://au-apigw.ccs.hyundai.com.au:8080"
|
||||
HyundaiAUCCSPServiceID = "855c72df-dfd7-4230-ab03-67cbf902bb1c"
|
||||
HyundaiAUCCSPAppID = "f9ccfdac-a48d-4c57-bd32-9116963c24ed"
|
||||
HyundaiAUBasicToken = "ODU1YzcyZGYtZGZkNy00MjMwLWFiMDMtNjdjYmY5MDJiYjFjOmU2ZmJ3SE0zMllOYmhRbDBwdmlhUHAzcmY0dDNTNms5MWVjZUEzTUpMZGJkVGhDTw=="
|
||||
HyundaiAUCfb = "nGDHng3k4Cg9gWV+C+A6Yk/ecDopUNTkGmDpr2qVKAQXx9bvY2/YLoHPfObliK32mZQ="
|
||||
)
|
||||
|
||||
// Config is the bluelink API configuration
|
||||
|
|
@ -39,6 +42,8 @@ type Config struct {
|
|||
Cfb string
|
||||
LoginFormHost string
|
||||
Brand string
|
||||
TokenURL string
|
||||
UseBasicAuth bool
|
||||
}
|
||||
|
||||
// Identity implements the Kia/Hyundai bluelink identity.
|
||||
|
|
@ -90,7 +95,7 @@ func (v *Identity) getDeviceID() (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
req, err := request.New(http.MethodPost, v.config.URI+DeviceIdURL, request.MarshalJSON(data), headers)
|
||||
req, err := request.New(http.MethodPost, v.config.URI+"/api/v1/spa/notifications/register", request.MarshalJSON(data), headers)
|
||||
if err == nil {
|
||||
err = v.DoJSON(req, &res)
|
||||
}
|
||||
|
|
@ -106,16 +111,34 @@ func (v *Identity) getDeviceID() (string, error) {
|
|||
func (v *Identity) refreshToken(token *oauth2.Token) (*oauth2.Token, error) {
|
||||
var res oauth2.Token
|
||||
|
||||
uri := v.config.LoginFormHost + TokenURL
|
||||
tokenURL := TokenURL
|
||||
if v.config.TokenURL != "" {
|
||||
tokenURL = v.config.TokenURL
|
||||
}
|
||||
uri := v.config.LoginFormHost + tokenURL
|
||||
|
||||
headers := map[string]string{
|
||||
"Content-type": "application/x-www-form-urlencoded",
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19_CCS_APP_AOS",
|
||||
}
|
||||
|
||||
data := url.Values{
|
||||
"grant_type": {"refresh_token"},
|
||||
"refresh_token": {token.RefreshToken},
|
||||
"client_id": {v.config.CCSPServiceID},
|
||||
"client_secret": {v.config.CCSPServiceSecret},
|
||||
}
|
||||
|
||||
// EU uses client_id/secret in body; AU uses Basic auth header
|
||||
if v.config.UseBasicAuth {
|
||||
stamp, err := v.stamp()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headers["Authorization"] = "Basic " + v.config.BasicToken
|
||||
headers["Stamp"] = stamp
|
||||
headers["User-Agent"] = "okhttp/3.12.0"
|
||||
} else {
|
||||
data.Set("client_id", v.config.CCSPServiceID)
|
||||
data.Set("client_secret", v.config.CCSPServiceSecret)
|
||||
}
|
||||
|
||||
req, err := request.New(http.MethodPost, uri, strings.NewReader(data.Encode()), headers)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue