Kia Uvo api

Hi

I have one Kia Soul EV eurooean market and I found a developer site for Kia but it’s in Korean (I beleive).

I can’t find any binding as of other brands but, I will try to ineract with the api via rules.

Is there anyone who have managed to figure out Kia uvo api endpoints?
First of all for loggin in and retreiving token, and ofcourse some endpoint to get started.

1 Like

Is this something that helps: GitHub - wcomartin/kiauvo: API Wrapper for Kia Uvo Service ?

I had a look at it earlier but in the docs it says N/A for euope and if that’s because it really doesn’t exist or because it’s just not yet reverese engineerd at all.

should work with GitHub - Hacksore/bluelinky: An unofficial nodejs API wrapper for Hyundai bluelink and Kia UVO
we need an bridge for openhab

1 Like

see also my thread here:

Presently I use node-red, which uses the bluelinky unofficial API wrapper to get information and trigger commands. A binding for openHAB would better of course! :wink:

1 Like

All this seems a little to advanced for me, I just have to wait and see if anyone start on a bindning for it or if there will be som tutorials about how to make any of the suggestions to work. My electrical company has an integration for Kia/hyundai that works so it is possible but, for the omen t beyond my knowledge, not even knowing where to start.

I’ve come that far that I installed KiaUvo and Requests module using pip, but I can’t figure out how to set username and password.

Installed package
API wrapper

Kia_test.py

from KiaUvo import KiaUvo

client = KiaUvo("my_actual username", "my actual password")
client.login()

# To see available vehicles
client.get_vehicle_list()

Throws

oot@openhab-openhab1:/usr/local/lib/python3.9/dist-packages/KiaUvo# python3 /openhab/conf/scripts/kia_test.py                                                                                              
Traceback (most recent call last):                                                                                                                                                                          
  File "/openhab/conf/scripts/kia_test.py", line 4, in <module>                                                                                                                                             
    client.login()                                                                                                                                                                                          
  File "/usr/local/lib/python3.9/dist-packages/KiaUvo/__init__.py", line 44, in login                                                                                                                       
    self.auth = self.__login(self.username, self.password)                                                                                                                                                  
  File "/usr/local/lib/python3.9/dist-packages/KiaUvo/__init__.py", line 56, in __login                                                                                                                     
    return AuthToken(xhr['result']['accessToken'], xhr['result']['refreshToken'])                                                                                                                           
KeyError: 'result'                                                                                            

And I can’t see any vehiclelist or any other data, but maybe output will not be visible in bash commandpromt?

Where should one set username and password I tried to modify init.py self.username and sel.password to contain my username and password as a string in “actual username” and “actual password” as below

 def __init__(self, username, password):                                                                                                                                                                 
        self.username = "actual username"                                                                                                                                                       
        self.password = "actual password"                                                                                                                                                                         
        self.pin = None                                                                                                                                                                                     
        self.vehicle_id = None                      

But there’s no differnet in the output however i make it.

Hi Folks

A little summary in case others are struggeling I did get this API to work. Im running

Hyundai Kia Connect API pypi package

In

OH 3.3.0 In Synology DSM 7.1 Docker

I had to install python in that container (which I already had) (apt-get install python3)
I had to install pip (apt get install pip)
Installed python package by (pip install hyundai-kia-connect-api)

There was two different dependencies that was missing, just install them using same method as above, missing dependencies will show as missing modules.
If your lucky you end up with a json respons.

Just supplied region, brand username, password and pin code as described in the link and made a carstatus.py that I hooked up with excecbinding (don’t forget whitelist) and a RAW string item

from hyundai_kia_connect_api import *
vm = VehicleManager(region=2, brand=1, username="username@gmail.com", password="password", pin="1234")
vm.check_and_refresh_token()
vm.update_all_vehicles_with_cached_state()
print(vm.vehicles)
1 Like

Now I have another issue to Jsonpath for the respons, Json validates in some json validators but fails in jsonpath validators. Could anyone point me into the right direction for jsonpath or any other solution?

String Item whre I would like to catch value 130 for _ev_estimated_station_charge_duration_value=130,

EV_estimated_charging.postUpdate(transform("JSONPATH", "$.e238a624-1aa3-4d40-bed4-5fe3fcc9fde2.Vehicle._ev_estimated_station_charge_duration", json))

Response string or json or however to handle it
Kia json.txt (6.8 KB)

Samplecode from txt file

Item 'EV_estimated_charging' changed from {'e238a624-1aa3-4d40-bed4-5fe3fcc9fde2': Vehicle(id='e238a624-1aa3-4d40-bed4-5fe3fcc9fde2', name='E-SOUL', model='E-SOUL', registration_date='2021-02-27 11:28:11.022', year=None, VIN=None, key=None, _total_driving_distance=154, _total_driving_distance_value=154, _total_driving_distance_unit='km', _odometer=21124.6, _odometer_value=21124.6, _odometer_unit='km', car_battery_percentage=99, engine_is_running=False, last_updated_at=datetime.datetime(2022, 9, 7, 18, 5, 40, tzinfo=tzfile('/usr/share/zoneinfo/Europe/Berlin')), smart_key_battery_warning_is_on=None, washer_fluid_warning_is_on=None, brake_fluid_warning_is_on=None, _air_temperature='02H', _air_temperature_value='02H', _air_temperature_unit='°C', air_control_is_on=False, defrost_is_on=False, steering_wheel_heater_is_on=0, back_window_heater_is_on=0, side_mirror_heater_is_on=None, front_left_seat_status=None, front_right_seat_status=None, rear_left_seat_status=None, rear_right_seat_status=None, is_locked=False, front_left_door_is_open=0, front_right_door_is_open=0, back_left_door_is_open=0, back_right_door_is_open=0, trunk_is_open=False, hood_is_open=None, tire_pressure_all_warning_is_on=None, tire_pressure_rear_left_warning_is_on=None, tire_pressure_front_left_warning_is_on=None, tire_pressure_front_right_warning_is_on=None, tire_pressure_rear_right_warning_is_on=None, _next_service_distance=None, _next_service_distance_value=None, _next_service_distance_unit=None, _last_service_distance=None, _last_service_distance_value=None, _last_service_distance_unit=None, _location_latitude=58.541603, _location_longitude=15.059267, _location_last_set_time=datetime.datetime(2022, 9, 7, 20, 5, 7, tzinfo=tzfile('/usr/share/zoneinfo/Europe/Berlin')), ev_battery_percentage=58, ev_battery_is_charging=False, ev_battery_is_plugged_in=0, _ev_driving_distance=154, _ev_driving_distance_value=154, _ev_driving_distance_unit='km', _ev_estimated_current_charge_duration=0, _ev_estimated_current_charge_duration_value=0, _ev_estimated_current_charge_duration_unit='m', _ev_estimated_fast_charge_duration=74, _ev_estimated_fast_charge_duration_value=74, _ev_estimated_fast_charge_duration_unit='m', _ev_estimated_portable_charge_duration=600, _ev_estimated_portable_charge_duration_value=600, _ev_estimated_portable_charge_duration_unit='m', _ev_estimated_station_charge_duration=130, _ev_estimated_station_charge_duration_value=130, _ev_estimated_station_charge_duration_unit='m', _ev_charge_limits=EvChargeLimits(ac=0, dc=0), _fuel_driving_distance=None, _fuel_driving_distance_value=None, _fuel_driving_distance_unit=None, fuel_level=None, fuel_l

I’m wondering, how this old code still works. Kia/Hyundai changed the API quite a bit - including rotating Hashes, which have to be up-to-date to allow access.
Please use “bluelinky” - the one linked at the very first sentence of this old (abandoned?) repo.

I know, it’s Javascript and no python, but works. If you have a NodeRed installation up, it’s a no-brainer, to just activate the NodeRed-contrib-Bluelinky there - as I did described here:

If you want to stay with that repo → the JSON coming out of this is broken (just paste your TXT-File into a decent JSON formatter like https://jsonformatter.org/
You have to take a look how that happened within the python.

I did started a nodered docker container and installed blue linkley via npm install node-red-contrib-bluelinky, but from there I’m all lost but that discussion will be taken in that thread

I didn’t managed to get that one running but post 8 marked as solution did run, thats a different python package.

1 Like

Perhaps I’m lost in translation here! :wink:

But I try a heads-up for NodeRed
In my linked thread above I pasted the “node”-sourcecode, which you can just copy and paste into a node in nodered.: openHAB-Binding for KIA/Hyundai (PH)EVs? - #5 by binderth
Nodered is flow-based, which means you have to have an “entry”-point and from there the “flow” generates more and more information.
So there’s a “inject”-node that triggers itself every 15mins in my case. That will then activate the next node connected “car-Full-Status” node with the “cache” option and from there it shows.

If you know, how NodeRed works, then it’s more straight-forward as coding…

Is anyone actually using an existing bluelinky docker image (like Docker Hub)? If so, could you please provide an instruction how to use it? I have installed it and am running the container with the basic configuration (not sure if correctly) and what now?

I ended up using Nodered by @binderth in the posts above.

Hi!

I also built a little integration by means of bluelinky with an NPM Docker container.
What it basically does is periodically query the KIA API and publish the result to MQTT.

prerequisites:

  • Kia Login credentials and VIN of your car
  • a Google Maps API Key, to decode the GPS coordinates into an address

first, the javascript app:


const BlueLinky = require('bluelinky');
const fetch = (url) => import('node-fetch').then(({default: fetch}) => fetch(url));
// MQTT setup
const mqtt = require('mqtt')
const mqtturl = 'mqtt://<ip of your mqtt server>:1883'
const mqttoptions = {
    // Clean session
    clean: true,
    connectTimeout: 4000,
    // Authentication
    clientId: 'kia2mqtt',
    username: 'username',
    password: 'password',
}
const mqttclient = mqtt.connect(mqtturl, mqttoptions)
var latitute;
var longitude;

const client = new BlueLinky({
    username: 'YOUR_USERNAME',
    password: 'YOUR_PASSWORD',
    brand: 'kia',
    region: 'EU',
    pin: 'YOUR_PIN'
});

client.on('ready', async () => {

    try {
        var myInterval = setInterval(async function () {
            const vehicle = client.getVehicle('YOUR_CAR_VIN');

            const date = new Date();
            const location = await vehicle.location();
            console.log(location);
            const newlatitute = location.latitude;
            const newlongitute = location.longitude
            const status = await vehicle.status();
            console.log(status);
            const soc = status.battery.batSoc

            mqttclient.publish('kia2mqtt/soc', JSON.stringify(soc))

            if (newlatitute != latitute || newlongitute != longitude) {
                latitute = newlatitute
                longitude = newlongitute
                console.log('location changed');
                mqttclient.publish('kia2mqtt/location', JSON.stringify(latitute) + ',' + JSON.stringify(longitude))
                const googleUrl = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + JSON.stringify(latitute) + ',' + JSON.stringify(longitude) + '&key=YOUR_API_KEY'
                fetch(googleUrl).then((response) => response.json()).then((data) => parseAdress(data));
            } else {
                console.log('location not updated');
            }

            mqttclient.publish('kia2mqtt/timestamp', date.toISOString())


        }, 900000)

    } catch (err) {
        console.log(err);
    }
});

client.on('error', async (err) => {
    console.log(err);
    mqttclient.publish('kia2mqtt/error', err)

});

mqttclient.on('connect', function () {
    console.log('MQTT Connected')

})

function parseAdress(adressData) {
    mqttclient.publish('kia2mqtt/adresse', adressData.results[0].formatted_address)
}

this already works if you just run it via “node kia2mqtt.js” given that you name the file kia2mqtt.js :slight_smile:

you can also put it into a docker container by using this Dockerfile:

# syntax=docker/dockerfile:1

FROM node:latest
ENV NODE_ENV=production

WORKDIR /app


RUN npm install --production
RUN npm install bluelinky
RUN npm install mqtt --save
RUN npm install node-fetch

COPY . .

CMD [ "node", "kia2mqtt.js" ]

now on to the things file:

Thing mqtt:topic:kia2mqtt "KIA EV6" (mqtt:broker:2d777009b4) {
    Channels:
        Type number : ladestand    [stateTopic="kia2mqtt/soc"]
        Type string : location    [stateTopic="kia2mqtt/location"]    
        Type string : adresse [stateTopic="kia2mqtt/adresse"]
        Type datetime : timestamp [stateTopic="kia2mqtt/timestamp"]
}

now you can use this to create an Item and do whatever you please.
Check the bluelinky documentation on what fields and actions are available. you can also subscribe to mqtt and send commands to your car from OpenHab, but I’ve not done this yet. It should be easy tough.
setInterval runs it every 15mins (900000 ms) and it checks if the location changed before it uses google maps to map it to an address. That way you save costly API calls to google.

1 Like

Hi,
I’m also struggling that issue in order to get Kia Connect (UVO) API and Connect it to my brand new Kia Seltos.
I’m living in Israel and Kia Connect services not supported here so I can’t download the official app, don’t have any Kia Connect icon at my car’s screen and can’t create a MyKia account with my car’s VIN since it keep saying “Invalid VIN number”.
I’m also an experienced mobile developer.
I wondered if there’s any way I’ll be able to
get things work for me and also if there’s any rest http API so I’ll be able to develop a mobile app with it?

If the car itself isn’t connected to the Kia API, then you can’t do anything, I’m afraid.
All communication must be directed via the API, if it is not present - then you have to find another solution.

If you’re an experienced developer, take a look at some of the OBD-Solutions out there. Especially GitHub - PowerBroker2/ELMduino: Arduino OBD-II Bluetooth Scanner Interface Library for Car Hacking Projects sounds promising. I never got around building the manufacturer-specific BEV-part of the ODB-commands (SoC, wallbox connected, …) into it, so I could use this…

Actually that’s different than what I’m trying to achieve. The library you sent using the car’s OBDII in order to read data and display it such as speed, kilometers, rpm etc. there’s already couple of devices I saw at some online stores that doing it by plug and play without any coding.
I’m willing to create an alternative for the Kia Connect app which isn’t available at my country.