@@ -8,28 +8,38 @@ import {
88} from './base'
99import { Config } from '../../config'
1010
11- const DEFAULT_API_DOMAIN = 'https://api.telematics.hyundaiusa.com/ac/v2/ '
11+ const DEFAULT_API_DOMAIN = 'https://api.telematics.hyundaiusa.com/'
1212const API_DOMAINS : Record < string , string > = {
13- hyundai : 'https://api.telematics.hyundaiusa.com/ac/v2/' ,
13+ hyundai : 'https://api.telematics.hyundaiusa.com/' ,
14+ kia : 'https://api.owners.kia.com/apigw/v1/' ,
1415}
1516
1617export class BluelinkUSA extends Bluelink {
18+ private carVin : string | undefined
19+ private carId : string | undefined
20+
1721 constructor ( config : Config , statusCheckInterval ?: number ) {
1822 super ( config )
1923 this . apiDomain = config . manufacturer
2024 ? this . getApiDomain ( config . manufacturer , API_DOMAINS , DEFAULT_API_DOMAIN )
2125 : DEFAULT_API_DOMAIN
26+
2227 this . statusCheckInterval = statusCheckInterval || DEFAULT_STATUS_CHECK_INTERVAL
2328 this . additionalHeaders = {
2429 from : 'SPA' ,
30+ to : 'ISS' ,
2531 language : '0' ,
2632 offset : `-${ new Date ( ) . getTimezoneOffset ( ) / 60 } ` ,
2733 gen : '2' ,
28- client_id : 'm66129Bb-em93-SPAHYN-bZ91-am4540zp19920' ,
29- clientSecret : 'v558o935-6nne-423i-baa8' ,
34+ client_id :
35+ config . manufacturer && config . manufacturer === 'kia' ? 'MWAMOBILE' : 'm66129Bb-em93-SPAHYN-bZ91-am4540zp19920' ,
36+ clientSecret :
37+ config . manufacturer && config . manufacturer === 'kia' ? '98er-w34rf-ibf3-3f6h' : 'v558o935-6nne-423i-baa8' ,
3038 username : this . config . auth . username ,
31- blueLinkServicePin : this . config . auth . pin ,
39+ blueLinkServicePin : `${ this . config . auth . pin } ` ,
40+ brandIndicator : 'H' ,
3241 }
42+
3343 this . authHeader = 'accessToken'
3444 this . tempLookup = {
3545 F : [ 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 ] ,
@@ -67,22 +77,23 @@ export class BluelinkUSA extends Bluelink {
6777 }
6878
6979 private requestResponseValid ( resp : Record < string , any > ) : boolean {
70- if ( Object . hasOwn ( resp , 'statusCode' ) && resp [ ' statusCode' ] == ' 200' ) {
80+ if ( Object . hasOwn ( resp , 'statusCode' ) && resp . statusCode === 200 ) {
7181 return true
7282 }
7383 return false
7484 }
7585
7686 private carHeaders ( ) : Record < string , string > {
7787 return {
78- registrationId : this . cache . car . id ,
79- vin : this . cache . car . vin ,
88+ // on first load cache is not populated - hence default to optional local vars set when fetching the car.
89+ registrationId : this . cache ? this . cache . car . id : this . carId ! ,
90+ vin : this . cache ? this . cache . car . vin : this . carVin ! ,
8091 }
8192 }
8293
8394 protected async login ( ) : Promise < BluelinkTokens | undefined > {
8495 const resp = await this . request ( {
85- url : this . apiDomain . replace ( '/ac/v2/' , '/ v2/ac/oauth/token') ,
96+ url : this . apiDomain + ' v2/ac/oauth/token',
8697 data : JSON . stringify ( {
8798 username : this . config . auth . username ,
8899 password : this . config . auth . password ,
@@ -93,7 +104,7 @@ export class BluelinkUSA extends Bluelink {
93104 return {
94105 accessToken : resp . json . access_token ,
95106 refreshToken : resp . json . refresh_token ,
96- expiry : Math . floor ( Date . now ( ) / 1000 ) + resp . json . result . token . expires_in , // we only get a expireIn not a actual date
107+ expiry : Math . floor ( Date . now ( ) / 1000 ) + resp . json . expires_in , // we only get a expireIn not a actual date
97108 }
98109 }
99110
@@ -104,7 +115,7 @@ export class BluelinkUSA extends Bluelink {
104115
105116 protected async refreshTokens ( ) : Promise < BluelinkTokens | undefined > {
106117 const resp = await this . request ( {
107- url : this . apiDomain . replace ( '/ac/v2/' , '/ v2/ac/oauth/token/refresh') ,
118+ url : this . apiDomain + ' v2/ac/oauth/token/refresh',
108119 data : JSON . stringify ( {
109120 refresh_token : this . cache . token . refreshToken ,
110121 } ) ,
@@ -114,7 +125,7 @@ export class BluelinkUSA extends Bluelink {
114125 return {
115126 accessToken : resp . json . access_token ,
116127 refreshToken : resp . json . refresh_token ,
117- expiry : Math . floor ( Date . now ( ) / 1000 ) + resp . json . result . token . expires_in , // we only get a expireIn not a actual date
128+ expiry : Math . floor ( Date . now ( ) / 1000 ) + resp . json . expires_in , // we only get a expireIn not a actual date
118129 }
119130 }
120131
@@ -125,20 +136,22 @@ export class BluelinkUSA extends Bluelink {
125136
126137 protected async getCar ( ) : Promise < BluelinkCar > {
127138 const resp = await this . request ( {
128- url : this . apiDomain + `enrollment/details/${ this . config . auth . username } ` ,
129- method : 'POST' ,
139+ url : this . apiDomain + `ac/v2/enrollment/details/${ this . config . auth . username } ` ,
130140 } )
131141 if ( this . requestResponseValid ( resp . resp ) && resp . json . enrolledVehicleDetails . length > 0 ) {
132- let vehicle = resp . json . result . enrolledVehicleDetails [ 0 ]
142+ let vehicle = resp . json . enrolledVehicleDetails [ 0 ] . vehicleDetails
133143 if ( this . vin ) {
134- for ( const v of resp . json . result . enrolledVehicleDetails ) {
135- if ( v . vin === this . vin ) {
136- vehicle = v
144+ for ( const v of resp . json . enrolledVehicleDetails ) {
145+ if ( v . vehicleDetails . vin === this . vin ) {
146+ vehicle = v . vehicleDetails
137147 break
138148 }
139149 }
140150 }
141151
152+ await this . logger . log ( `Choose car ${ JSON . stringify ( vehicle ) } ` )
153+ this . carVin = vehicle . vin
154+ this . carId = vehicle . regid
142155 return {
143156 id : vehicle . regid ,
144157 vin : vehicle . vin ,
@@ -165,9 +178,9 @@ export class BluelinkUSA extends Bluelink {
165178 isCharging : status . evStatus . batteryCharge ,
166179 isPluggedIn : status . evStatus . batteryPlugin > 0 ? true : false ,
167180 chargingPower : status . evStatus . batteryCharge // only check for charging power if actually charging
168- ? ( status . evStatus . batteryPower . batteryFstChrgPower && status . evStatus . batteryPower . batteryFstChrgPower ) > 0
169- ? status . evStatus . batteryPower . batteryFstChrgPower
170- : status . evStatus . batteryPower . batteryStndChrgPower
181+ ? ( status . evStatus . batteryFstChrgPower && status . evStatus . batteryFstChrgPower ) > 0
182+ ? status . evStatus . batteryFstChrgPower
183+ : status . evStatus . batteryStndChrgPower
171184 : 0 ,
172185 remainingChargeTimeMins : status . evStatus . remainTime2 . atc . value ,
173186 // sometimes range back as zero? if so ignore and use cache
@@ -186,14 +199,12 @@ export class BluelinkUSA extends Bluelink {
186199 }
187200
188201 protected async getCarStatus ( id : string , forceUpdate : boolean ) : Promise < BluelinkStatus > {
189- const api = 'rcs/rvs/vehicleStatus'
202+ const api = 'ac/v2/ rcs/rvs/vehicleStatus'
190203 const resp = await this . request ( {
191204 url : this . apiDomain + api ,
192205 headers : {
193206 ...this . carHeaders ( ) ,
194- ...( forceUpdate && {
195- REFRESH : 'true' ,
196- } ) ,
207+ refresh : forceUpdate ? 'true' : 'false' ,
197208 } ,
198209 } )
199210
0 commit comments