Hyundai Bluelink: add Australia and New Zealand regions (#30037)

This commit is contained in:
aldasilva0 2026-06-02 16:53:44 +10:00 • committed by GitHub
parent 42f4281e68
commit a05eb42ffd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 83 additions and 20 deletions

View file

@ -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" . }}

View file

@ -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
}{

View file

@ -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)