@@ -18,16 +18,38 @@ import {
1818 RawVehicleStatus ,
1919 FullVehicleStatus ,
2020 EVChargeModeTypes ,
21+ VehicleInfo ,
22+ VehicleFeatureEntry ,
2123} from '../interfaces/common.interfaces' ;
22-
2324import { Vehicle } from './vehicle' ;
2425import { celciusToTempCode , parseDate } from '../util' ;
2526import { CanadianController } from '../controllers/canadian.controller' ;
2627import { ManagedBluelinkyError } from '../tools/common.tools' ;
2728
29+
30+ export interface CanadianInfo {
31+ vehicle : VehicleInfo ;
32+ features : {
33+ seatHeatVent : {
34+ drvSeatHeatOption : number ;
35+ astSeatHeatOption : number ;
36+ rlSeatHeatOption : number ;
37+ rrSeatHeatOption : number ;
38+ } ;
39+ hvacTempType : number ;
40+ targetMinSoc : number ;
41+ strgWhlHeatingOption : number ;
42+ } ;
43+ featuresModel : {
44+ features : [ VehicleFeatureEntry ] ;
45+ } ;
46+ status : RawVehicleStatus ;
47+ }
48+
2849export default class CanadianVehicle extends Vehicle {
2950 public region = REGIONS . CA ;
3051 private timeOffset = - ( new Date ( ) . getTimezoneOffset ( ) / 60 ) ;
52+ private _info : CanadianInfo | null = null ;
3153
3254 constructor ( public vehicleConfig : VehicleRegisterOptions , public controller : CanadianController ) {
3355 super ( vehicleConfig , controller ) ;
@@ -48,60 +70,70 @@ export default class CanadianVehicle extends Vehicle {
4870
4971 logger . debug ( 'Begin status request, polling car' , statusConfig . refresh ) ;
5072 try {
51- const endpoint = statusConfig . refresh
52- ? this . controller . environment . endpoints . remoteStatus
53- : this . controller . environment . endpoints . status ;
54- const response = await this . request ( endpoint , { } ) ;
55- const vehicleStatus = response . result ?. status ;
56-
57- if ( response ?. error ) {
58- throw response ?. error ?. errorDesc ;
73+ let vehicleStatus : RawVehicleStatus | null = null ;
74+ if ( statusConfig . useInfo ) {
75+ await this . setInfo ( statusConfig . refresh ) ;
76+ if ( this . _info ) {
77+ vehicleStatus = this . _info . status ;
78+ }
79+ } else {
80+ const endpoint = statusConfig . refresh
81+ ? this . controller . environment . endpoints . remoteStatus
82+ : this . controller . environment . endpoints . status ;
83+ const response = await this . request ( endpoint , { } ) ;
84+ vehicleStatus = response . result ?. status ;
85+
86+ if ( response ?. error ) {
87+ throw response ?. error ?. errorDesc ;
88+ }
5989 }
60-
6190 logger . debug ( vehicleStatus ) ;
62- const parsedStatus : VehicleStatus = {
63- chassis : {
64- hoodOpen : vehicleStatus ?. hoodOpen ,
65- trunkOpen : vehicleStatus ?. trunkOpen ,
66- locked : vehicleStatus ?. doorLock ,
67- openDoors : {
68- frontRight : ! ! vehicleStatus ?. doorOpen ?. frontRight ,
69- frontLeft : ! ! vehicleStatus ?. doorOpen ?. frontLeft ,
70- backLeft : ! ! vehicleStatus ?. doorOpen ?. backLeft ,
71- backRight : ! ! vehicleStatus ?. doorOpen ?. backRight ,
91+ let parsedStatus : VehicleStatus | null = null ;
92+ if ( vehicleStatus ) {
93+ parsedStatus = {
94+ chassis : {
95+ hoodOpen : vehicleStatus ?. hoodOpen ,
96+ trunkOpen : vehicleStatus ?. trunkOpen ,
97+ locked : vehicleStatus ?. doorLock ,
98+ openDoors : {
99+ frontRight : ! ! vehicleStatus ?. doorOpen ?. frontRight ,
100+ frontLeft : ! ! vehicleStatus ?. doorOpen ?. frontLeft ,
101+ backLeft : ! ! vehicleStatus ?. doorOpen ?. backLeft ,
102+ backRight : ! ! vehicleStatus ?. doorOpen ?. backRight ,
103+ } ,
104+ tirePressureWarningLamp : {
105+ rearLeft : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampRearLeft ,
106+ frontLeft : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampFrontLeft ,
107+ frontRight : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampFrontRight ,
108+ rearRight : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampRearRight ,
109+ all : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampAll ,
110+ } ,
72111 } ,
73- tirePressureWarningLamp : {
74- rearLeft : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampRearLeft ,
75- frontLeft : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampFrontLeft ,
76- frontRight : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampFrontRight ,
77- rearRight : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampRearRight ,
78- all : ! ! vehicleStatus ?. tirePressureLamp ?. tirePressureWarningLampAll ,
112+ climate : {
113+ active : vehicleStatus ?. airCtrlOn ,
114+ steeringwheelHeat : ! ! vehicleStatus ?. steerWheelHeat ,
115+ sideMirrorHeat : false ,
116+ rearWindowHeat : ! ! vehicleStatus ?. sideBackWindowHeat ,
117+ defrost : vehicleStatus ?. defrost ,
118+ temperatureSetpoint : vehicleStatus ?. airTemp ?. value ,
119+ temperatureUnit : vehicleStatus ?. airTemp ?. unit ,
79120 } ,
80- } ,
81- climate : {
82- active : vehicleStatus ?. airCtrlOn ,
83- steeringwheelHeat : ! ! vehicleStatus ?. steerWheelHeat ,
84- sideMirrorHeat : false ,
85- rearWindowHeat : ! ! vehicleStatus ?. sideBackWindowHeat ,
86- defrost : vehicleStatus ?. defrost ,
87- temperatureSetpoint : vehicleStatus ?. airTemp ?. value ,
88- temperatureUnit : vehicleStatus ?. airTemp ?. unit ,
89- } ,
90121
91- // TODO: fix props for parsed???
92- // Seems some of the translation would have to account for EV and ICE
93- // as they are often in different locations on the response
94- // example EV status is in lib/__mock__/canadianStatus.json
95- engine : {
96- ignition : vehicleStatus ?. engine ,
97- accessory : vehicleStatus ?. acc ,
98- range : vehicleStatus ?. dte ?. value ,
99- charging : vehicleStatus ?. evStatus ?. batteryCharge ,
100- batteryCharge12v : vehicleStatus ?. battery ?. batSoc ,
101- batteryChargeHV : vehicleStatus ?. evStatus ?. batteryStatus ,
102- } ,
103- lastupdate : vehicleStatus ?. time ? parseDate ( vehicleStatus ?. lastStatusDate ) : null ,
104- } ;
122+ // TODO: fix props for parsed???
123+ // Seems some of the translation would have to account for EV and ICE
124+ // as they are often in different locations on the response
125+ // example EV status is in lib/__mock__/canadianStatus.json
126+ engine : {
127+ ignition : vehicleStatus ?. engine ,
128+ accessory : vehicleStatus ?. acc ,
129+ range : vehicleStatus ?. dte ?. value ,
130+ charging : vehicleStatus ?. evStatus ?. batteryCharge ,
131+ batteryCharge12v : vehicleStatus ?. battery ?. batSoc ,
132+ batteryChargeHV : vehicleStatus ?. evStatus ?. batteryStatus ,
133+ } ,
134+ lastupdate : parseDate ( vehicleStatus ?. lastStatusDate ) ,
135+ } ;
136+ }
105137
106138 this . _status = statusConfig . parsed ? parsedStatus : vehicleStatus ;
107139 return this . _status ;
@@ -289,8 +321,17 @@ export default class CanadianVehicle extends Vehicle {
289321 }
290322
291323 // TODO: @Seb to take a look at doing this
292- public odometer ( ) : Promise < VehicleOdometer | null > {
293- throw new Error ( 'Method not implemented.' ) ;
324+ public async odometer ( ) : Promise < VehicleOdometer | null > {
325+ try {
326+ await this . setInfo ( ) ;
327+ if ( this . _info ) {
328+ return { unit : this . _info . vehicle . odometer , value : this . _info . vehicle . odometerUnit } ;
329+ } else {
330+ throw 'error: no info' ;
331+ }
332+ } catch ( err ) {
333+ throw 'error: ' + err ;
334+ }
294335 }
295336
296337 public async location ( ) : Promise < VehicleLocation > {
@@ -325,7 +366,7 @@ export default class CanadianVehicle extends Vehicle {
325366
326367 // TODO: not sure how to type a dynamic response
327368 /* eslint-disable @typescript-eslint/no-explicit-any */
328- private async request ( endpoint , body : any , headers : any = { } ) : Promise < any | null > {
369+ private async request ( endpoint : string , body : any , headers : any = { } ) : Promise < any | null > {
329370 logger . debug ( `[${ endpoint } ] ${ JSON . stringify ( headers ) } ${ JSON . stringify ( body ) } ` ) ;
330371
331372 // add logic for token refresh to ensure we don't use a stale token
@@ -361,4 +402,21 @@ export default class CanadianVehicle extends Vehicle {
361402 throw 'error: ' + err ;
362403 }
363404 }
405+
406+ private async setInfo ( refresh = false ) : Promise < void > {
407+ if ( this . _info !== null && ! refresh ) {
408+ return ;
409+ }
410+ try {
411+ const preAuth = await this . getPreAuth ( ) ;
412+ const response = await this . request (
413+ this . controller . environment . endpoints . vehicleInfo ,
414+ { } ,
415+ { pAuth : preAuth }
416+ ) ;
417+ this . _info = response . result as CanadianInfo ;
418+ } catch ( err ) {
419+ throw 'error: ' + err ;
420+ }
421+ }
364422}
0 commit comments