hyundai-kia-connect-api 3.17.6__py2.py3-none-any.whl → 3.32.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,9 +8,14 @@ import logging
8
8
  import pytz
9
9
 
10
10
  from .exceptions import APIError
11
- from .ApiImpl import ApiImpl, ClimateRequestOptions, WindowRequestOptions
12
- from .HyundaiBlueLinkAPIUSA import HyundaiBlueLinkAPIUSA
13
- from .KiaUvoAPIUSA import KiaUvoAPIUSA
11
+ from .ApiImpl import (
12
+ ApiImpl,
13
+ ClimateRequestOptions,
14
+ WindowRequestOptions,
15
+ ScheduleChargingClimateRequestOptions,
16
+ )
17
+ from .HyundaiBlueLinkApiUSA import HyundaiBlueLinkApiUSA
18
+ from .KiaUvoApiUSA import KiaUvoApiUSA
14
19
  from .KiaUvoApiCA import KiaUvoApiCA
15
20
  from .KiaUvoApiEU import KiaUvoApiEU
16
21
  from .KiaUvoApiCN import KiaUvoApiCN
@@ -32,6 +37,7 @@ from .const import (
32
37
  VEHICLE_LOCK_ACTION,
33
38
  CHARGE_PORT_ACTION,
34
39
  OrderStatus,
40
+ VALET_MODE_ACTION,
35
41
  )
36
42
 
37
43
  _LOGGER = logging.getLogger(__name__)
@@ -91,23 +97,28 @@ class VehicleManager:
91
97
  _LOGGER.debug(f"{DOMAIN} - Vehicle Disabled, skipping.")
92
98
 
93
99
  def check_and_force_update_vehicles(self, force_refresh_interval: int) -> None:
100
+ for vehicle_id in self.vehicles.keys():
101
+ self.check_and_force_update_vehicle(force_refresh_interval, vehicle_id)
102
+
103
+ def check_and_force_update_vehicle(
104
+ self, force_refresh_interval: int, vehicle_id: str
105
+ ) -> None:
94
106
  # Force refresh only if current data is older than the value bassed in seconds.
95
107
  # Otherwise runs a cached update.
96
108
  started_at_utc: dt = dt.datetime.now(pytz.utc)
97
- for vehicle_id in self.vehicles.keys():
98
- vehicle = self.get_vehicle(vehicle_id)
99
- if vehicle.last_updated_at is not None:
100
- _LOGGER.debug(
101
- f"{DOMAIN} - Time differential in seconds: {(started_at_utc - vehicle.last_updated_at).total_seconds()}" # noqa
102
- )
103
- if (
104
- started_at_utc - vehicle.last_updated_at
105
- ).total_seconds() > force_refresh_interval:
106
- self.force_refresh_vehicle_state(vehicle_id)
107
- else:
108
- self.update_vehicle_with_cached_state(vehicle_id)
109
+ vehicle = self.get_vehicle(vehicle_id)
110
+ if vehicle.last_updated_at is not None:
111
+ _LOGGER.debug(
112
+ f"{DOMAIN} - Time differential in seconds: {(started_at_utc - vehicle.last_updated_at).total_seconds()}" # noqa
113
+ )
114
+ if (
115
+ started_at_utc - vehicle.last_updated_at
116
+ ).total_seconds() > force_refresh_interval:
117
+ self.force_refresh_vehicle_state(vehicle_id)
109
118
  else:
110
119
  self.update_vehicle_with_cached_state(vehicle_id)
120
+ else:
121
+ self.update_vehicle_with_cached_state(vehicle_id)
111
122
 
112
123
  def force_refresh_all_vehicles_states(self) -> None:
113
124
  for vehicle_id in self.vehicles.keys():
@@ -155,11 +166,24 @@ class VehicleManager:
155
166
  def stop_charge(self, vehicle_id: str) -> str:
156
167
  return self.api.stop_charge(self.token, self.get_vehicle(vehicle_id))
157
168
 
169
+ def start_hazard_lights(self, vehicle_id: str) -> str:
170
+ return self.api.start_hazard_lights(self.token, self.get_vehicle(vehicle_id))
171
+
172
+ def start_hazard_lights_and_horn(self, vehicle_id: str) -> str:
173
+ return self.api.start_hazard_lights_and_horn(
174
+ self.token, self.get_vehicle(vehicle_id)
175
+ )
176
+
158
177
  def set_charge_limits(self, vehicle_id: str, ac: int, dc: int) -> str:
159
178
  return self.api.set_charge_limits(
160
179
  self.token, self.get_vehicle(vehicle_id), ac, dc
161
180
  )
162
181
 
182
+ def set_charging_current(self, vehicle_id: str, level: int) -> str:
183
+ return self.api.set_charging_current(
184
+ self.token, self.get_vehicle(vehicle_id), level
185
+ )
186
+
163
187
  def set_windows_state(self, vehicle_id: str, options: WindowRequestOptions) -> str:
164
188
  return self.api.set_windows_state(
165
189
  self.token, self.get_vehicle(vehicle_id), options
@@ -209,7 +233,7 @@ class VehicleManager:
209
233
 
210
234
  def update_month_trip_info(self, vehicle_id: str, yyyymm_string: str) -> None:
211
235
  """
212
- Europe feature only.
236
+ feature only available for some regions.
213
237
  Updates the vehicle.month_trip_info for the specified month.
214
238
 
215
239
  Default this information is None:
@@ -221,7 +245,7 @@ class VehicleManager:
221
245
 
222
246
  def update_day_trip_info(self, vehicle_id: str, yyyymmdd_string: str) -> None:
223
247
  """
224
- Europe feature only.
248
+ feature only available for some regions.
225
249
  Updates the vehicle.day_trip_info information for the specified day.
226
250
 
227
251
  Default this information is None:
@@ -237,6 +261,23 @@ class VehicleManager:
237
261
  def enable_vehicle(self, vehicle_id: str) -> None:
238
262
  self.get_vehicle(vehicle_id).enabled = True
239
263
 
264
+ def schedule_charging_and_climate(
265
+ self, vehicle_id: str, options: ScheduleChargingClimateRequestOptions
266
+ ) -> str:
267
+ return self.api.schedule_charging_and_climate(
268
+ self.token, self.get_vehicle(vehicle_id), options
269
+ )
270
+
271
+ def start_valet_mode(self, vehicle_id: str) -> str:
272
+ return self.api.valet_mode_action(
273
+ self.token, self.get_vehicle(vehicle_id), VALET_MODE_ACTION.ACTIVATE
274
+ )
275
+
276
+ def stop_valet_mode(self, vehicle_id: str) -> str:
277
+ return self.api.valet_mode_action(
278
+ self.token, self.get_vehicle(vehicle_id), VALET_MODE_ACTION.DEACTIVATE
279
+ )
280
+
240
281
  @staticmethod
241
282
  def get_implementation_by_region_brand(
242
283
  region: int, brand: int, language: str
@@ -248,9 +289,9 @@ class VehicleManager:
248
289
  elif REGIONS[region] == REGION_USA and (
249
290
  BRANDS[brand] == BRAND_HYUNDAI or BRANDS[brand] == BRAND_GENESIS
250
291
  ):
251
- return HyundaiBlueLinkAPIUSA(region, brand, language)
292
+ return HyundaiBlueLinkApiUSA(region, brand, language)
252
293
  elif REGIONS[region] == REGION_USA and BRANDS[brand] == BRAND_KIA:
253
- return KiaUvoAPIUSA(region, brand, language)
294
+ return KiaUvoApiUSA(region, brand, language)
254
295
  elif REGIONS[region] == REGION_CHINA:
255
296
  return KiaUvoApiCN(region, brand, language)
256
297
  elif REGIONS[region] == REGION_AUSTRALIA:
@@ -1,12 +1,11 @@
1
1
  """Top-level package for Hyundai / Kia Connect."""
2
2
 
3
3
  # flake8: noqa
4
- from .ApiImpl import ApiImpl, ClimateRequestOptions, WindowRequestOptions
5
- from .HyundaiBlueLinkAPIUSA import HyundaiBlueLinkAPIUSA
6
- from .KiaUvoApiCA import KiaUvoApiCA
7
- from .KiaUvoApiEU import KiaUvoApiEU
8
- from .KiaUvoAPIUSA import KiaUvoAPIUSA
9
- from .KiaUvoApiCN import KiaUvoApiCN
4
+ from .ApiImpl import (
5
+ ClimateRequestOptions,
6
+ WindowRequestOptions,
7
+ ScheduleChargingClimateRequestOptions,
8
+ )
10
9
 
11
10
  from .Token import Token
12
11
  from .Vehicle import Vehicle
@@ -0,0 +1,457 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Connects to the Bluelink API and query the vehicle."""
4
+
5
+ import argparse
6
+ import datetime
7
+ import json
8
+ import logging
9
+ import os
10
+ import sys
11
+ import textwrap
12
+
13
+ import hyundai_kia_connect_api
14
+ from hyundai_kia_connect_api import const
15
+
16
+
17
+ def print_vehicle(vehicle):
18
+ print("Identification")
19
+ print(" id:", vehicle.id)
20
+ print(" name:", vehicle.name)
21
+ print(" model:", vehicle.model)
22
+ print(" registration_date:", vehicle.registration_date)
23
+ print(" year:", vehicle.year)
24
+ print(" VIN:", vehicle.VIN)
25
+ print(" key:", vehicle.key)
26
+ print("General")
27
+ print(" engine_type:", vehicle.engine_type)
28
+ print(" ccu_ccs2_protocol_support:", vehicle.ccu_ccs2_protocol_support)
29
+ print(
30
+ " total_driving_range:",
31
+ vehicle.total_driving_range,
32
+ vehicle.total_driving_range_unit,
33
+ )
34
+ print(" odometer:", vehicle.odometer, vehicle.odometer_unit)
35
+ print(" geocode:", vehicle.geocode)
36
+ print(" car_battery_percentage:", vehicle.car_battery_percentage)
37
+ print(" engine_is_running:", vehicle.engine_is_running)
38
+ print(" last_updated_at:", vehicle.last_updated_at)
39
+ print(" timezone:", vehicle.timezone)
40
+ print(" dtc_count:", vehicle.dtc_count)
41
+ print(" dtc_descriptions:", vehicle.dtc_descriptions)
42
+ print(" smart_key_battery_warning_is_on:", vehicle.smart_key_battery_warning_is_on)
43
+ print(" washer_fluid_warning_is_on:", vehicle.washer_fluid_warning_is_on)
44
+ print(" brake_fluid_warning_is_on:", vehicle.brake_fluid_warning_is_on)
45
+ print("Climate")
46
+ print(" air_temperature:", vehicle.air_temperature, vehicle._air_temperature_unit)
47
+ print(" air_control_is_on:", vehicle.air_control_is_on)
48
+ print(" defrost_is_on:", vehicle.defrost_is_on)
49
+ print(" steering_wheel_heater_is_on:", vehicle.steering_wheel_heater_is_on)
50
+ print(" back_window_heater_is_on:", vehicle.back_window_heater_is_on)
51
+ print(" side_mirror_heater_is_on:", vehicle.side_mirror_heater_is_on)
52
+ print(" front_left_seat_status:", vehicle.front_left_seat_status)
53
+ print(" front_right_seat_status:", vehicle.front_right_seat_status)
54
+ print(" rear_left_seat_status:", vehicle.rear_left_seat_status)
55
+ print(" rear_right_seat_status:", vehicle.rear_right_seat_status)
56
+ print("Doors")
57
+ print(" is_locked:", vehicle.is_locked)
58
+ print(" front_left_door_is_open:", vehicle.front_left_door_is_open)
59
+ print(" front_right_door_is_open:", vehicle.front_right_door_is_open)
60
+ print(" back_left_door_is_open:", vehicle.back_left_door_is_open)
61
+ print(" back_right_door_is_open:", vehicle.back_right_door_is_open)
62
+ print(" trunk_is_open:", vehicle.trunk_is_open)
63
+ print(" hood_is_open:", vehicle.hood_is_open)
64
+ print("Windows")
65
+ print(" front_left_window_is_open:", vehicle.front_left_window_is_open)
66
+ print(" front_right_window_is_open:", vehicle.front_right_window_is_open)
67
+ print(" back_left_window_is_open:", vehicle.back_left_window_is_open)
68
+ print(" back_right_window_is_open:", vehicle.back_right_window_is_open)
69
+ print("Tire Pressure")
70
+ print(" tire_pressure_all_warning_is_on:", vehicle.tire_pressure_all_warning_is_on)
71
+ print(
72
+ " tire_pressure_rear_left_warning_is_on:",
73
+ vehicle.tire_pressure_rear_left_warning_is_on,
74
+ )
75
+ print(
76
+ " tire_pressure_front_left_warning_is_on:",
77
+ vehicle.tire_pressure_front_left_warning_is_on,
78
+ )
79
+ print(
80
+ " tire_pressure_front_right_warning_is_on:",
81
+ vehicle.tire_pressure_front_right_warning_is_on,
82
+ )
83
+ print(
84
+ " tire_pressure_rear_right_warning_is_on:",
85
+ vehicle.tire_pressure_rear_right_warning_is_on,
86
+ )
87
+ print("Service")
88
+ print(
89
+ " next_service_distance:",
90
+ vehicle.next_service_distance,
91
+ vehicle._next_service_distance_unit,
92
+ )
93
+ print(
94
+ " last_service_distance:",
95
+ vehicle.last_service_distance,
96
+ vehicle._last_service_distance_unit,
97
+ )
98
+ print("Location")
99
+ print(" location:", vehicle.location)
100
+ print(" location_last_updated_at:", vehicle.location_last_updated_at)
101
+ print("EV/PHEV")
102
+ print(" charge_port_door_is_open:", vehicle.ev_charge_port_door_is_open)
103
+ print(" charging_power:", vehicle.ev_charging_power)
104
+ print(" charge_limits_dc:", vehicle.ev_charge_limits_dc)
105
+ print(" charge_limits_ac:", vehicle.ev_charge_limits_ac)
106
+ print(" charging_current:", vehicle.ev_charging_current)
107
+ print(" v2l_discharge_limit:", vehicle.ev_v2l_discharge_limit)
108
+ print(" total_power_consumed:", vehicle.total_power_consumed, "Wh")
109
+ print(" total_power_regenerated:", vehicle.total_power_regenerated, "Wh")
110
+ print(" power_consumption_30d:", vehicle.power_consumption_30d, "Wh")
111
+ print(" battery_percentage:", vehicle.ev_battery_percentage)
112
+ print(" battery_soh_percentage:", vehicle.ev_battery_soh_percentage)
113
+ print(" battery_remain:", vehicle.ev_battery_remain)
114
+ print(" battery_capacity:", vehicle.ev_battery_capacity)
115
+ print(" battery_is_charging:", vehicle.ev_battery_is_charging)
116
+ print(" battery_is_plugged_in:", vehicle.ev_battery_is_plugged_in)
117
+ print(" driving_range:", vehicle.ev_driving_range, vehicle._ev_driving_range_unit)
118
+ print(
119
+ " estimated_current_charge_duration:",
120
+ vehicle.ev_estimated_current_charge_duration,
121
+ vehicle._ev_estimated_current_charge_duration_unit,
122
+ )
123
+ print(
124
+ " estimated_fast_charge_duration:",
125
+ vehicle.ev_estimated_fast_charge_duration,
126
+ vehicle._ev_estimated_fast_charge_duration_unit,
127
+ )
128
+ print(
129
+ " estimated_portable_charge_duration:",
130
+ vehicle.ev_estimated_portable_charge_duration,
131
+ vehicle._ev_estimated_portable_charge_duration_unit,
132
+ )
133
+ print(
134
+ " estimated_station_charge_duration:",
135
+ vehicle.ev_estimated_station_charge_duration,
136
+ vehicle._ev_estimated_station_charge_duration_unit,
137
+ )
138
+ print(
139
+ " target_range_charge_AC:",
140
+ vehicle.ev_target_range_charge_AC,
141
+ vehicle._ev_target_range_charge_AC_unit,
142
+ )
143
+ print(
144
+ " target_range_charge_DC:",
145
+ vehicle.ev_target_range_charge_DC,
146
+ vehicle._ev_target_range_charge_DC_unit,
147
+ )
148
+
149
+ print(" first_departure_enabled:", vehicle.ev_first_departure_enabled)
150
+ print(
151
+ " first_departure_climate_temperature:",
152
+ vehicle.ev_first_departure_climate_temperature,
153
+ vehicle._ev_first_departure_climate_temperature_unit,
154
+ )
155
+ print(" first_departure_days:", vehicle.ev_first_departure_days)
156
+ print(" first_departure_time:", vehicle.ev_first_departure_time)
157
+ print(
158
+ " first_departure_climate_enabled:", vehicle.ev_first_departure_climate_enabled
159
+ )
160
+ print(
161
+ " first_departure_climate_defrost:", vehicle.ev_first_departure_climate_defrost
162
+ )
163
+ print(" second_departure_enabled:", vehicle.ev_second_departure_enabled)
164
+ print(
165
+ " second_departure_climate_temperature:",
166
+ vehicle.ev_second_departure_climate_temperature,
167
+ vehicle._ev_second_departure_climate_temperature_unit,
168
+ )
169
+ print(" second_departure_days:", vehicle.ev_second_departure_days)
170
+ print(" second_departure_time:", vehicle.ev_second_departure_time)
171
+ print(
172
+ " second_departure_climate_enabled:",
173
+ vehicle.ev_second_departure_climate_enabled,
174
+ )
175
+ print(
176
+ " second_departure_climate_defrost:",
177
+ vehicle.ev_second_departure_climate_defrost,
178
+ )
179
+ print(" off_peak_start_time:", vehicle.ev_off_peak_start_time)
180
+ print(" off_peak_end_time:", vehicle.ev_off_peak_end_time)
181
+ print(" off_peak_charge_only_enabled:", vehicle.ev_off_peak_charge_only_enabled)
182
+ print(" schedule_charge_enabled:", vehicle.ev_schedule_charge_enabled)
183
+ print("PHEV/HEV/IC")
184
+ print(
185
+ " fuel_driving_range:",
186
+ vehicle.fuel_driving_range,
187
+ vehicle._fuel_driving_range_unit,
188
+ )
189
+ print(" fuel_level:", vehicle.fuel_level)
190
+ print(" fuel_level_is_low:", vehicle.fuel_level_is_low)
191
+ print("Trips")
192
+ print(" daily_stats:", vehicle.daily_stats)
193
+ print(" month_trip_info:", vehicle.month_trip_info)
194
+ print(" day_trip_info:", vehicle.day_trip_info)
195
+ print("Debug")
196
+ print(textwrap.indent(json.dumps(vehicle.data, indent=2, sort_keys=True), " "))
197
+
198
+
199
+ def vehicle_to_dict(vehicle):
200
+ return {
201
+ "identification": {
202
+ "id": vehicle.id,
203
+ "name": vehicle.name,
204
+ "model": vehicle.model,
205
+ "registration_date": vehicle.registration_date,
206
+ "year": vehicle.year,
207
+ "VIN": vehicle.VIN,
208
+ "key": vehicle.key,
209
+ },
210
+ "general": {
211
+ "engine_type": str(vehicle.engine_type),
212
+ "ccu_ccs2_protocol_support": vehicle.ccu_ccs2_protocol_support,
213
+ "total_driving_range": [
214
+ vehicle.total_driving_range,
215
+ vehicle.total_driving_range_unit,
216
+ ],
217
+ "odometer": [vehicle.odometer, vehicle.odometer_unit],
218
+ "geocode": vehicle.geocode,
219
+ "car_battery_percentage": vehicle.car_battery_percentage,
220
+ "engine_is_running": vehicle.engine_is_running,
221
+ "last_updated_at": vehicle.last_updated_at,
222
+ "timezone": vehicle.timezone,
223
+ "dtc_count": vehicle.dtc_count,
224
+ "dtc_descriptions": vehicle.dtc_descriptions,
225
+ "smart_key_battery_warning_is_on": vehicle.smart_key_battery_warning_is_on,
226
+ "washer_fluid_warning_is_on": vehicle.washer_fluid_warning_is_on,
227
+ "brake_fluid_warning_is_on": vehicle.brake_fluid_warning_is_on,
228
+ },
229
+ "climate": {
230
+ "air_temperature": [
231
+ vehicle.air_temperature,
232
+ vehicle._air_temperature_unit,
233
+ ],
234
+ "air_control_is_on": vehicle.air_control_is_on,
235
+ "defrost_is_on": vehicle.defrost_is_on,
236
+ "steering_wheel_heater_is_on": vehicle.steering_wheel_heater_is_on,
237
+ "back_window_heater_is_on": vehicle.back_window_heater_is_on,
238
+ "side_mirror_heater_is_on": vehicle.side_mirror_heater_is_on,
239
+ "front_left_seat_status": vehicle.front_left_seat_status,
240
+ "front_right_seat_status": vehicle.front_right_seat_status,
241
+ "rear_left_seat_status": vehicle.rear_left_seat_status,
242
+ "rear_right_seat_status": vehicle.rear_right_seat_status,
243
+ },
244
+ "doors": {
245
+ "is_locked": vehicle.is_locked,
246
+ "front_left_door_is_open": vehicle.front_left_door_is_open,
247
+ "front_right_door_is_open": vehicle.front_right_door_is_open,
248
+ "back_left_door_is_open": vehicle.back_left_door_is_open,
249
+ "back_right_door_is_open": vehicle.back_right_door_is_open,
250
+ "trunk_is_open": vehicle.trunk_is_open,
251
+ "hood_is_open": vehicle.hood_is_open,
252
+ },
253
+ "windows": {
254
+ "front_left_window_is_open": vehicle.front_left_window_is_open,
255
+ "front_right_window_is_open": vehicle.front_right_window_is_open,
256
+ "back_left_window_is_open": vehicle.back_left_window_is_open,
257
+ "back_right_window_is_open": vehicle.back_right_window_is_open,
258
+ },
259
+ "tires": {
260
+ "tire_pressure_all_warning_is_on": vehicle.tire_pressure_all_warning_is_on,
261
+ "tire_pressure_rear_left_warning_is_on": vehicle.tire_pressure_rear_left_warning_is_on,
262
+ "tire_pressure_front_left_warning_is_on": vehicle.tire_pressure_front_left_warning_is_on,
263
+ "tire_pressure_front_right_warning_is_on": vehicle.tire_pressure_front_right_warning_is_on,
264
+ "tire_pressure_rear_right_warning_is_on": vehicle.tire_pressure_rear_right_warning_is_on,
265
+ },
266
+ "service": {
267
+ "next_service_distance": [
268
+ vehicle.next_service_distance,
269
+ vehicle._next_service_distance_unit,
270
+ ],
271
+ "last_service_distance": [
272
+ vehicle.last_service_distance,
273
+ vehicle._last_service_distance_unit,
274
+ ],
275
+ },
276
+ "location": {
277
+ "location": vehicle.location,
278
+ "location_last_updated_at": vehicle.location_last_updated_at,
279
+ },
280
+ "electric": {
281
+ "charge_port_door_is_open": vehicle.ev_charge_port_door_is_open,
282
+ "charging_power": vehicle.ev_charging_power,
283
+ "charge_limits_dc": vehicle.ev_charge_limits_dc,
284
+ "charge_limits_ac": vehicle.ev_charge_limits_ac,
285
+ "charging_current": vehicle.ev_charging_current,
286
+ "v2l_discharge_limit": vehicle.ev_v2l_discharge_limit,
287
+ "total_power_consumed": [vehicle.total_power_consumed, "Wh"],
288
+ "total_power_regenerated": [vehicle.total_power_regenerated, "Wh"],
289
+ "power_consumption_30d": [vehicle.power_consumption_30d, "Wh"],
290
+ "battery_percentage": vehicle.ev_battery_percentage,
291
+ "battery_soh_percentage": vehicle.ev_battery_soh_percentage,
292
+ "battery_remain": vehicle.ev_battery_remain,
293
+ "battery_capacity": vehicle.ev_battery_capacity,
294
+ "battery_is_charging": vehicle.ev_battery_is_charging,
295
+ "battery_is_plugged_in": vehicle.ev_battery_is_plugged_in,
296
+ "driving_range": [
297
+ vehicle.ev_driving_range,
298
+ vehicle._ev_driving_range_unit,
299
+ ],
300
+ "estimated_current_charge_duration": [
301
+ vehicle.ev_estimated_current_charge_duration,
302
+ vehicle._ev_estimated_current_charge_duration_unit,
303
+ ],
304
+ "estimated_fast_charge_duration": [
305
+ vehicle.ev_estimated_fast_charge_duration,
306
+ vehicle._ev_estimated_fast_charge_duration_unit,
307
+ ],
308
+ "estimated_portable_charge_duration": [
309
+ vehicle.ev_estimated_portable_charge_duration,
310
+ vehicle._ev_estimated_portable_charge_duration_unit,
311
+ ],
312
+ "estimated_station_charge_duration": [
313
+ vehicle.ev_estimated_station_charge_duration,
314
+ vehicle._ev_estimated_station_charge_duration_unit,
315
+ ],
316
+ "target_range_charge_AC": [
317
+ vehicle.ev_target_range_charge_AC,
318
+ vehicle._ev_target_range_charge_AC_unit,
319
+ ],
320
+ "target_range_charge_DC": [
321
+ vehicle.ev_target_range_charge_DC,
322
+ vehicle._ev_target_range_charge_DC_unit,
323
+ ],
324
+ "first_departure_enabled": vehicle.ev_first_departure_enabled,
325
+ "first_departure_climate_temperature": [
326
+ vehicle.ev_first_departure_climate_temperature,
327
+ vehicle._ev_first_departure_climate_temperature_unit,
328
+ ],
329
+ "first_departure_days": vehicle.ev_first_departure_days,
330
+ "first_departure_time": vehicle.ev_first_departure_time,
331
+ "first_departure_climate_enabled": vehicle.ev_first_departure_climate_enabled,
332
+ "first_departure_climate_defrost": vehicle.ev_first_departure_climate_defrost,
333
+ "second_departure_enabled": vehicle.ev_second_departure_enabled,
334
+ "second_departure_climate_temperature": [
335
+ vehicle.ev_second_departure_climate_temperature,
336
+ vehicle._ev_second_departure_climate_temperature_unit,
337
+ ],
338
+ "second_departure_days": vehicle.ev_second_departure_days,
339
+ "second_departure_time": vehicle.ev_second_departure_time,
340
+ "second_departure_climate_enabled": vehicle.ev_second_departure_climate_enabled,
341
+ "second_departure_climate_defrost": vehicle.ev_second_departure_climate_defrost,
342
+ "off_peak_start_time": vehicle.ev_off_peak_start_time,
343
+ "off_peak_end_time": vehicle.ev_off_peak_end_time,
344
+ "off_peak_charge_only_enabled": vehicle.ev_off_peak_charge_only_enabled,
345
+ "schedule_charge_enabled": vehicle.ev_schedule_charge_enabled,
346
+ },
347
+ "ic": {
348
+ "fuel_driving_range": [
349
+ vehicle.fuel_driving_range,
350
+ vehicle._fuel_driving_range_unit,
351
+ ],
352
+ "fuel_level": vehicle.fuel_level,
353
+ "fuel_level_is_low": vehicle.fuel_level_is_low,
354
+ },
355
+ "trips": {
356
+ "daily_stats": vehicle.daily_stats,
357
+ "month_trip_info": vehicle.month_trip_info,
358
+ "day_trip_info": vehicle.day_trip_info,
359
+ },
360
+ "debug": vehicle.data,
361
+ }
362
+
363
+
364
+ class DateTimeEncoder(json.JSONEncoder):
365
+ def default(self, obj):
366
+ if isinstance(obj, (datetime.date, datetime.datetime)):
367
+ return obj.isoformat()
368
+
369
+
370
+ def cmd_info(vm, args):
371
+ for vehicle_id, vehicle in vm.vehicles.items():
372
+ print_vehicle(vehicle)
373
+ if args.json:
374
+ data = {id: vehicle_to_dict(v) for id, v in vm.vehicles.items()}
375
+ json.dump(data, args.json, separators=(",", ":"), cls=DateTimeEncoder)
376
+ return 0
377
+
378
+
379
+ def main():
380
+ default_username = os.environ.get("BLUELINK_USERNAME", "")
381
+ default_password = os.environ.get("BLUELINK_PASSWORD", "")
382
+ default_pin = None
383
+ if os.environ.get("BLUELINK_PIN", ""):
384
+ try:
385
+ default_pin = int(os.environ["BLUELINK_PIN"])
386
+ except ValueError:
387
+ print("Invalid BLUELINK_PIN environment variable", file=sys.stderr)
388
+ return 1
389
+
390
+ parser = argparse.ArgumentParser(description=sys.modules[__name__].__doc__)
391
+ parser.add_argument(
392
+ "--region",
393
+ default=os.environ.get("BLUELINK_REGION", const.REGION_CANADA),
394
+ choices=sorted(const.REGIONS.values()),
395
+ help="Car's region, use env var BLUELINK_REGION",
396
+ )
397
+ parser.add_argument(
398
+ "--brand",
399
+ default=os.environ.get("BLUELINK_BRAND", const.BRAND_HYUNDAI),
400
+ choices=sorted(const.BRANDS.values()),
401
+ help="Car's brand, use env var BLUELINK_BRAND",
402
+ )
403
+ parser.add_argument(
404
+ "--username",
405
+ default=default_username,
406
+ help="Bluelink account username, use env var BLUELINK_USERNAME",
407
+ required=not default_username,
408
+ )
409
+ parser.add_argument(
410
+ "--password",
411
+ default=default_password,
412
+ help="Bluelink account password, use env var BLUELINK_PASSWORD",
413
+ required=not default_password,
414
+ )
415
+ parser.add_argument(
416
+ "--pin",
417
+ type=int,
418
+ default=default_pin,
419
+ help="Bluelink account pin, use env var BLUELINK_PIN",
420
+ required=not default_pin,
421
+ )
422
+ parser.add_argument("-v", "--verbose", action=argparse.BooleanOptionalAction)
423
+ subparsers = parser.add_subparsers(help="Commands", required=True)
424
+ parser_info = subparsers.add_parser(
425
+ "info", help="Prints infos about the cars found"
426
+ )
427
+ parser_info.set_defaults(func=cmd_info)
428
+ parser_info.add_argument(
429
+ "--json",
430
+ type=argparse.FileType("w", encoding="UTF-8"),
431
+ help="Save data to file as JSON",
432
+ )
433
+
434
+ args = parser.parse_args()
435
+ logging.basicConfig(level=logging.DEBUG if args.verbose else logging.ERROR)
436
+
437
+ # Reverse lookup.
438
+ region = [k for k, v in const.REGIONS.items() if v == args.region][0]
439
+ brand = [k for k, v in const.BRANDS.items() if v == args.brand][0]
440
+
441
+ vm = hyundai_kia_connect_api.VehicleManager(
442
+ region=region,
443
+ brand=brand,
444
+ username=args.username,
445
+ password=args.password,
446
+ pin=args.pin,
447
+ geocode_api_enable=True,
448
+ geocode_api_use_email=True,
449
+ )
450
+ # TODO: Cache token.
451
+ vm.check_and_refresh_token()
452
+ vm.update_all_vehicles_with_cached_state()
453
+ return args.func(vm, args)
454
+
455
+
456
+ if __name__ == "__main__":
457
+ sys.exit(main())
@@ -29,7 +29,13 @@ LOGIN_TOKEN_LIFETIME = datetime.timedelta(hours=23)
29
29
 
30
30
  LENGTH_KILOMETERS = "km"
31
31
  LENGTH_MILES = "mi"
32
- DISTANCE_UNITS = {None: None, 0: None, 1: LENGTH_KILOMETERS, 3: LENGTH_MILES}
32
+ DISTANCE_UNITS = {
33
+ None: None,
34
+ 0: None,
35
+ 1: LENGTH_KILOMETERS,
36
+ 2: LENGTH_MILES,
37
+ 3: LENGTH_MILES,
38
+ }
33
39
 
34
40
  TEMPERATURE_C = "°C"
35
41
  TEMPERATURE_F = "°F"
@@ -92,3 +98,8 @@ class WINDOW_STATE(IntEnum):
92
98
  CLOSED = 0
93
99
  OPEN = 1
94
100
  VENTILATION = 2
101
+
102
+
103
+ class VALET_MODE_ACTION(Enum):
104
+ ACTIVATE = "activate"
105
+ DEACTIVATE = "deactivate"