Open-source project
Hyundai-Kia-Connect/kia_uvo avatar
Hyundai-Kia-Connect/kia_uvo

kia_uvo: putting a Kia or a Hyundai into Home Assistant

A Home Assistant HACS integration that supports Kia Connect(Uvo) and Hyundai Bluelink. The integration supports the EU, Canada and the USA.

968 stars206 forksPythonMIT

At a glance

What is it?
kia_uvo is a HACS custom integration that connects Kia Uvo and Hyundai Bluelink vehicles to Home Assistant, with a large entity surface covering range, charging, climate, locks, windows and even surround-view camera images. Its most interesting feature is also its risk, because a force refresh is a message to a parked car, and the maintainer now says openly that they no longer own one of these vehicles and are looking for help.
Who is it for?
Adopt kia_uvo if you own a Kia or Hyundai in a supported region and want your car in Home Assistant for charging control, preconditioning and location, since the entity list is thorough and the polling model is conservative by default. It is the wrong tool for a Genesis, for China, India or Brazil where support is limited, and the wrong tool if you want the car to answer instantly, because a fresh reading means waking the vehicle.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the integration covers and where it works

kia_uvo is a custom integration for Home Assistant that supports Kia Uvo and Hyundai Bluelink, and it is not a self contained piece of code. The README points at the underlying Python package, hyundai_kia_connect_api, and that separation is the architecture: the API library handles talking to the manufacturer's cloud, and the integration maps that onto Home Assistant entities and services.

The regional picture is stated precisely, and it is the first thing to check before anything else. Australia, the EU, Canada, Switzerland, India, New Zealand, Brazil and the USA are supported, but the README qualifies that with a note that support for the USA, India, China and Brazil is limited. Genesis support has not been tested and has just been added for Canada only, with feedback invited. That is a different thing from unsupported, and it is worth reading as such: a vehicle brand with a half finished code path behind it.

The service availability table at the end of the README is the other half of the picture, and it is a wide table that runs from EU and the newer EU, New Zealand and Australia columns through Canada, USA Kia, USA Hyundai, USA Genesis, China, India and Brazil. The implication is obvious once you see it: the same service, for example releasing a car lock or sending a destination to the navigation system, is not equally available everywhere, and the integration will expose what the regional API supports rather than what the hardware could do.

The entity list is where most of the value is, and it is long enough that a reader should sample it rather than read it whole. There are sensors for odometer, total range, EV range, fuel range, the twelve volt battery, EV battery level, state of health, capacity and remaining charge, estimated charge duration for current, fast, portable and station charging, target range for AC and DC, interior and outside temperature, fuel level, power consumed and regenerated, seat and heater status, service distances, engine type, DTC count, charging power and current, geocoded location, daily driving statistics, and the time of the last surround-view capture. There is a separate EV diagnostics group for CCS2 vehicles, covering pack voltage, battery temperature, chiller speed, power consumption for air conditioning and battery cooling and heating, and the off-peak and departure times.

The binary sensors are the state of the car as switches: engine running, ignition, accessory, defrost, heated rear window, heated steering wheel, mirror heater, charging, plugged in, charge port open, winter mode, preconditioning, heating state, vehicle to load and vehicle to everything status, scheduled charging, off-peak only, individual doors, trunk, hood, individual windows, individual door locks, per-wheel tyre pressure warnings, low fuel, smart key battery, brake fluid, washer fluid, headlamps, turn signals, stop lamps, sunroof, sleep mode and transmission condition.

Installing it and the first configuration

There are two installation paths, and the first is the one most people will use.

HACS, the Home Assistant Community Store, is the standard route for custom integrations. You install HACS if you do not have it, open HACS inside Home Assistant, search for Kia Uvo, and press the download button. The manual alternative is to copy the custom_components/kia_uvo directory into your config/custom_components directory and restart Home Assistant.

The configuration itself is inside Home Assistant, under Settings, then Devices and Services, then Integrations, where you search for Kia Uvo and configure the vehicle with your username and password. That is a cloud account credential, which is the price of the whole thing: the integration authenticates against the manufacturer's servers, and the vehicle is reached through them rather than directly.

Multiple cars and multiple accounts are supported, and the README explains the mechanism, which is to go through the setup flow a second time. A reconfigure flow is available from the integration options, and that is where you change credentials or set the PIN, which matters because some vehicles in some regions require a PIN for the vehicle API rather than the account password.

A subtlety worth knowing is that the geocoded location sensor is optional and disabled by default, so a fresh install does not send your car's position to a geocoding service until you ask for it. For a car, that is the right default, and it is the sort of detail that tells you the author thought about privacy rather than assuming it.

The distance unit is also handled with a similar default. By default it follows the metric or imperial preference of your Home Assistant instance, and you configure each entity individually if you want something else. The per-entity approach is more work than a global setting, and it is the right trade for a vehicle that may report in the unit of its home market.

The polling model and why it is deliberately slow

The timing configuration is the part of this integration that a user has to understand before enabling anything, and the defaults are conservative in a way that reflects the real behaviour of a parked car.

The scan interval fetches cached information from the servers every thirty minutes, and it is configurable. That is a poll of the manufacturer's cloud, which is cheap for the car and cheap for the integration. The force refresh interval is a different thing: it asks the car for the latest data, and the default is every four hours. Also configurable.

And the force refresh is disabled between 10PM and 6AM by default, also configurable. A car that is asked for its latest state over a cellular connection has to wake up, and waking a parked car at three in the morning is both slow and expensive in battery terms, and in some regions the vehicle may be asleep in a way that makes the request take a while to answer. The quiet window is the sensible default, and turning it off is a decision about your battery.

The services list repeats the same warning in a more direct form. The force_update service, which asks the vehicle for its latest data, carries the instruction do not overuse. That is not a stylistic flourish in the documentation, it is the difference between a cached reading that costs nothing and a wake-up that takes a car out of a deep sleep state.

For an integration that also exposes buttons, this matters. The button that captures a surround-view image is documented as a remote command that can wake the vehicle, and the same is true of the start and stop climate service, which the README notes starts the internal combustion engine in some regions. A Home Assistant automation that fires on a schedule can therefore keep a car awake, and that is the thing to check before writing one.

The command surface: services you can call from an automation

The services are the write side of the integration, and they are extensive enough that a careful reading is worthwhile before you wire any of them into an automation.

There is the update service, which gets the latest cached vehicle data, and force_update, which asks the vehicle itself. Climate control has start_climate and stop_climate, with the ICE note attached. Charging has start_charge and stop_charge, set_charge_limits for the AC and DC capacity, and set_charging_current with three levels, 100 per cent, 90 per cent or 60 per cent. The charge port can be opened and closed. There are the lock and unlock services, set_windows to open or close individual windows where that is supported, and the hazard lights with and without the horn, the latter being what the README calls panic mode.

There is also valet mode, start and stop. There is schedule_charging_and_climate to set a planned departure schedule, and set_off_peak_charging to set the off-peak mode and its window. There is set_navigation, which sends a destination to the vehicle's navigation system.

And there is capture_svm_image, which triggers a fresh surround-view capture.

What stands out is the mixture of things. Some of these services are convenience, sending a destination, checking the charge level. Others are physical actions on a car that is parked away from you, releasing door locks, starting the engine, opening the charge port, setting the climate so the cabin is warm when you arrive. A Home Assistant integration that exposes all of them as services gives you the ability to build exactly the automation you want, and also the ability to lock yourself out of your own car, wake it repeatedly, or leave the climate running.

The region table is the constraint on all of it, and it is worth checking before you design the automation rather than after. A service that works on an EU vehicle may not exist for a US Genesis, and the integration will simply not offer what the regional API does not.

Surround-view images and the dewarp switch

The image entity group is the most unusual feature in the integration, and it is Hyundai only.

It exposes the SVM, the 360 degree surround view, as separate images: front camera, rear camera, left camera and right camera, cropped from the latest capture, plus a bird's-eye view, which is the top-down image. These come out of the vehicle's surround-view camera system, and the newest capture is what is available at any moment, which is a meaningful constraint, because the images are only as fresh as the last capture.

The complication is that the side cameras output raw fisheye. The dewarp switch, listed among the switches as SVM Dewarp, rectifies them using the per-camera field of view when the API provides it, and falls back to the raw fisheye when it does not. The README is explicit that the switch is a presentation preference only and sends no vehicle command, which is the right distinction to make in a project where most switches are things that reach out to the car.

The processing itself is done by the library rather than by the integration. The README says the views are cropped, rectified and encoded by the library, with the image extra of hyundai_kia_connect_api, and that the dewarp switch refreshes the image entities immediately with no new capture needed. That is a sensible division, because the heavy lifting belongs next to the API code, and the integration should be a mapping layer.

The capture itself is a different matter. The Capture SVM Image button triggers a fresh capture, and that is a remote command that can wake the vehicle. So the dewarp switch is free and local, and the capture button is not, and the difference between the two is the difference between a display setting and an action on hardware sitting in a car park.

Maintenance: the maintainer is asking for help

The first section of the README is the one an adopter should read first, and it is a warning rather than a pitch. It says code maintainers are wanted, that the author no longer has a Kia or a Hyundai, and therefore does not maintain the project the way they used to. Others who are interested in taking it on are welcome, and even pull requests alone are appreciated.

That is an unusually candid statement, and it should change how you read the rest. The project is not abandoned, and the release history says the opposite: v3.19.0 on 2026-10-19, v3.18.0 on 2026-10-14 and v3.17.1 on 2026-10-11 are three releases in eight days, and the last push was on 2026-10-19. Someone is writing code and releasing it. What the notice says is that the person doing it no longer has the hardware to verify it against.

That distinction matters for this particular integration. Most of it is mapping cloud API responses onto entities, and that can be done without the car in front of you. But the parts that need the vehicle, the region specific behaviour, the PIN flows, the wake-up semantics, the surround-view quirks, are exactly the parts that need one, and those are the parts most likely to rot.

The repository itself is in good order. There is a hacs.json for the community store, a.pre-commit-config.yaml, a.devcontainer for development, a.vscode directory, a pytest.ini and a tests directory, a renovate.json for dependency updates, and a pyproject.toml whose ruff configuration is worth reading because the ignores come with explanations. The blind except exception rule is ignored with the comment that it is a resilience pattern, the catch-all in the config entry and force refresh paths, and it is marked permanent. The naive datetime rules are ignored with a note that they are deferred to a separate time zone aware migration pull request, all or nothing. That is a project with a considered approach to its own technical debt, which is a better sign than a clean lint run.

The licence is MIT, so forking it is allowed as long as the copyright and licence notice stay with the code, and for a project whose maintainer has said they are looking for someone else to own it, that is the practical path if you own one of these cars.

Editorial conclusion

Adopt kia_uvo if you own a Kia or Hyundai in a supported region and want your car in Home Assistant for charging control, preconditioning and location, since the entity list is thorough and the polling model is conservative by default. It is the wrong tool for a Genesis, for China, India or Brazil where support is limited, and the wrong tool if you want the car to answer instantly, because a fresh reading means waking the vehicle. Before installing, read the polling section and set the force refresh interval to something you can live with, and if you have a PIN protected account, check the reconfigure flow, which is where you set it.

Frequently asked questions

Which cars and regions does the kia_uvo Home Assistant integration support?

It supports Kia Uvo and Hyundai Bluelink, with Australia, the EU, Canada, Switzerland, India, New Zealand, Brazil and the USA listed, and the README noting that support for the USA, India, China and Brazil is limited. Genesis support has not been tested and has been added for Canada only.

How do I install the Kia Uvo integration in Home Assistant?

Through HACS: install HACS if needed, open it in Home Assistant, search for Kia Uvo and press the download button. The manual route is to copy the custom_components/kia_uvo directory into config/custom_components and restart Home Assistant, then add the integration under Settings, Devices and Services, Integrations with your username and password.

How often does kia_uvo contact the car?

The scan interval fetches cached data from the servers every thirty minutes, and the force refresh interval asks the car itself every four hours, both configurable. Force refresh is disabled between 10PM and 6AM by default, and the force_update service is documented as something not to overuse, since it can wake the vehicle.

What can the kia_uvo services do to my car?

They can start and stop climate control, which starts the internal combustion engine in some regions, start and stop charging, set charge limits and charging current, open and close the charge port, locking and releasing the doors, open and close windows, trigger the hazard lights with or without the horn, set valet mode, set off-peak charging, send a destination to the navigation system and trigger a surround-view capture. Availability differs by region.

What does the SVM Dewarp switch do?

It rectifies the raw fisheye images from the Hyundai surround-view cameras using the per-camera field of view when the API provides it, falling back to the raw fisheye otherwise. It is a presentation preference that sends no vehicle command, and it refreshes the image entities without triggering a new capture.

Official sources

  1. Hyundai-Kia-Connect/kia_uvo on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hyundai-kia-connect-kia-uvo.svg)](https://hysenlabs.com/projects/hyundai-kia-connect-kia-uvo)