Hyundai-Kia-Connect / hyundai_kia_connect_api

This is a Kia UVO and Hyundai Bluelink written in python. It is primary consumed by home assistant. If you are looking for a home assistant Kia / Hyundai implementation please look here: https://github.com/Hyundai-Kia-Connect/kia_uvo. Much of this base code came from reading bluelinky and contributions to the kia_uvo home assistant project.
MIT License
116 stars 69 forks source link

force_refresh_all_vehicles_states() - doesn't return odometer values #290

Open eili77 opened 1 year ago

eili77 commented 1 year ago

Description

Using force_refresh_all_vehicles_states(self) method doesn't return odometer values (all "none").

Vehicle(id='xxx', name='KONA', model='KONA', registration_date='2021-10-20 17:59:26.158', year=None, VIN='xxx', key=None, enabled=True, _total_driving_range=369.0, _total_driving_range_value=369.0, _total_driving_range_unit='km', _odometer=None, _odometer_value=None, _odometer_unit=None, _geocode_address=None, _geocode_name=None, car_battery_percentage=80, engine_is_running=False, last_updated_at=datetime.datetime(2023, 3, 6, 9, 2, 12, tzinfo=tzfile('/usr/share/zoneinfo/Europe/Berlin')), timezone=None, dtc_count=None, dtc_descriptions=None, smart_key_battery_warning_is_on=False,...

Using update_all_vehicles_with_cached_state(self) works fine and returns odometer values.

Vehicle(id='xxx', name='KONA', model='KONA', registration_date='2021-10-20 17:59:26.158', year=None, VIN='xxx', key=None, enabled=True, _total_driving_range=394.0, _total_driving_range_value=394.0, _total_driving_range_unit='km', _odometer=22471.5, _odometer_value=22471.5, _odometer_unit='km', _geocode_address=None, _geocode_name=None, car_battery_percentage=85, engine_is_running=False, last_updated_at=datetime.datetime(2023, 3, 4, 16, 14, 21, tzinfo=tzfile('/usr/share/zoneinfo/Europe/Berlin')), timezone=None, dtc_count=None, dtc_descriptions=None, smart_key_battery_warning_is_on=False,...

It's a repeatable issue. Is this a wanted/known behaviour?

cdnninja commented 1 year ago

Which region and brand?

eili77 commented 1 year ago

Europe, Hyundai

ZuinigeRijder commented 1 year ago

I can confirm that force_refresh_all_vehicles_states() will NOT fill odometer. I digged into the differences of the responses:

DEBUG:hyundai_kia_connect_api.KiaUvoApiEU:hyundai_kia_connect_api - get_cached_vehicle_status response: {
    "retCode": "S",
    "resCode": "0000",
    "resMsg": {
        "vehicleStatusInfo": {
            "vehicleLocation": {
                "coord": {"lat": 12.3456, "lon": 5.123456, "alt": 0, "type": 0},
                "head": 330,
                "speed": {"value": 0, "unit": 0},
                "accuracy": {"hdop": 0, "pdop": 0},
                "time": "20230306201120",
            },
            "vehicleStatus": {
                "airCtrlOn": False,
                "engine": False,
                "doorLock": True,
....
                "systemCutOffAlert": 0,
                "tailLampStatus": 0,
                "hazardStatus": 0,
            },
            "odometer": {"value": 23864.9, "unit": 1},
        }
    },

and

DEBUG:hyundai_kia_connect_api.KiaUvoApiEU:hyundai_kia_connect_api - Received forced vehicle data: {
    "retCode": "S",
    "resCode": "0000",
    "resMsg": {
        "airCtrlOn": False,
        "engine": False,
        "doorLock": True,
....
        "systemCutOffAlert": 0,
        "tailLampStatus": 0,
        "hazardStatus": 0,
    },

It appears that in Received forced vehicle data the following information is NOT returned:

In the source code of KiaUvoApiEU.py the location is separately called, when force_refresh_all_vehicles_states() is called, to circumvent the absense of location (but nothing done for odometer).

DEBUG:hyundai_kia_connect_api.KiaUvoApiEU:hyundai_kia_connect_api - _get_location response: {'...

I do not know if this odometer was never returned in Received forced vehicle data. The workaround for the library user would be to call force_refresh_all_vehicles_states() first en then update_all_vehicles_with_cached_state(). Or KiaUvoApiEU.py should do this internally?

ZuinigeRijder commented 1 year ago

Because I tested with force_refresh_all_vehicles_states(), you can see well in the below Battery Monitor screenshot how much impact a force refresh has on your 12 volt battery. At 8:07 I did the refresh. Your battery will be definitely drain if you use the refresh often. Especially when the SOC of your car is below 20%, because then the battery saver function will not kick in to top up your 12 volt battery, at least with the IONIQ 5. That is why my tool, hyundai_kia_connect_monitor does no longer do a force refresh anymore.

Screenshot_20230307-102514

eili77 commented 1 year ago

Because I tested with force_refresh_all_vehicles_states(), you can see well in the below Battery Monitor screenshot how much impact a force refresh has on your 12 volt battery. At 8:07 I did the refresh. Your battery will be definitely drain if you use the refresh often. Especially when the SOC of your car is below 20%, because then the battery saver function will not kick in to top up your 12 volt battery, at least with the IONIQ 5. That is why my tool, hyundai_kia_connect_monitor does no longer do a force refresh anymore.

Screenshot_20230307-102514

Thanks for sharing these insights - understood :-)

Nevertheless, I think there's no obvious reason to omit the odometer information in this (force-) function, since all the other datapoints as far as I checked do exist... - or am I wrong ?

ZuinigeRijder commented 1 year ago

@eili77 Yep, unfortunately the bluelink API does not return the odometer (and locations) values in the vehicles/[id]/status call, while it does in vehicles/[id]/status/latest So then the library or the user has to work around it, e.g. by calling both after each other. Or do you see another solution?

eili77 commented 1 year ago

Or do you see another solution?

Nope, unfortunately I don't. Thanks!

cdnninja commented 1 year ago

I thought I had this one fixed awhile back by not putting the value into vehicle unless provided. This only works if you call cache regularly and occasionally call force.