Repository navigation
fix(vehicles/kia): restore SoC via new IDPConnect OAuth2 login - #3751
Merged
Merged
Conversation
The Kia/Hyundai SoC adapter stopped working: Hyundai/Kia decommissioned
the old Keycloak form login (eu-account.<brand>.com/auth/realms/...),
so getAuthCode() could no longer obtain an authorization code and every
SoC request failed.
This switches the login to the current IDPConnect OAuth2 flow, mirroring
the well-maintained hyundai_kia_connect_api library (KiaUvoApiEU) used by
Home Assistant:
* GET /auth/api/v2/user/oauth2/authorize (obtain session cookies)
* GET /auth/api/v1/accounts/certs (RSA public key as JWK)
* RSA/PKCS#1 v1.5 encrypt the password (hex)
* POST /auth/account/signin (302 -> ?code=...)
* POST /auth/api/v2/user/oauth2/token (client_secret, form-urlencoded)
refreshToken() is updated to the IDPConnect token endpoint and keeps a
rotated refresh_token when the server returns one. If the refresh grant
fails (expired/rotated refresh token), fetch_soc() now falls back to a
full login instead of leaving the module stuck after the first poll -
same strategy as hyundai_kia_connect_api's refresh_access_token().
Password encryption uses 'cryptography' (already pulled in transitively
by requests) with a 'pycryptodome' fallback, so no new hard dependency is
introduced.
Robustness fixes:
* getAuthCode() uses its own requests.Session for the cookie chain and
no longer calls getCookies() (dead Keycloak endpoints).
* RAMDISK_PATH import is wrapped so a missing helpermodules.constants
export falls back to <openWB-root>/ramdisk instead of crashing the
whole module import.
* postHTTP() raises RuntimeError with the HTTP status/error text, and
the token functions pre-initialise 'response' so a failed request no
longer masks the real cause with "local variable 'response'
referenced before assignment".
Tested on openWB 2.2.1 (Kia EV6): SoC is read on the initial poll and on
subsequent refresh polls, no errors in main.log; RSA round-trip verified
against a locally generated key pair.
LKuemmel
approved these changes
Aug 4, 2026
benderl
pushed a commit
that referenced
this pull request
Aug 6, 2026
* fix(vehicles/kia): restore SoC via new IDPConnect OAuth2 login
The Kia/Hyundai SoC adapter stopped working: Hyundai/Kia decommissioned
the old Keycloak form login (eu-account.<brand>.com/auth/realms/...),
so getAuthCode() could no longer obtain an authorization code and every
SoC request failed.
This switches the login to the current IDPConnect OAuth2 flow, mirroring
the well-maintained hyundai_kia_connect_api library (KiaUvoApiEU) used by
Home Assistant:
* GET /auth/api/v2/user/oauth2/authorize (obtain session cookies)
* GET /auth/api/v1/accounts/certs (RSA public key as JWK)
* RSA/PKCS#1 v1.5 encrypt the password (hex)
* POST /auth/account/signin (302 -> ?code=...)
* POST /auth/api/v2/user/oauth2/token (client_secret, form-urlencoded)
refreshToken() is updated to the IDPConnect token endpoint and keeps a
rotated refresh_token when the server returns one. If the refresh grant
fails (expired/rotated refresh token), fetch_soc() now falls back to a
full login instead of leaving the module stuck after the first poll -
same strategy as hyundai_kia_connect_api's refresh_access_token().
Password encryption uses 'cryptography' (already pulled in transitively
by requests) with a 'pycryptodome' fallback, so no new hard dependency is
introduced.
Robustness fixes:
* getAuthCode() uses its own requests.Session for the cookie chain and
no longer calls getCookies() (dead Keycloak endpoints).
* RAMDISK_PATH import is wrapped so a missing helpermodules.constants
export falls back to <openWB-root>/ramdisk instead of crashing the
whole module import.
* postHTTP() raises RuntimeError with the HTTP status/error text, and
the token functions pre-initialise 'response' so a failed request no
longer masks the real cause with "local variable 'response'
referenced before assignment".
Tested on openWB 2.2.1 (Kia EV6): SoC is read on the initial poll and on
subsequent refresh polls, no errors in main.log; RSA round-trip verified
against a locally generated key pair.
* fix(vehicles/kia): remove unused client_secret variable (flake8 F841)
ndrsnhs
pushed a commit
to ndrsnhs/core
that referenced
this pull request
Aug 24, 2026
…B#3751) * fix(vehicles/kia): restore SoC via new IDPConnect OAuth2 login The Kia/Hyundai SoC adapter stopped working: Hyundai/Kia decommissioned the old Keycloak form login (eu-account.<brand>.com/auth/realms/...), so getAuthCode() could no longer obtain an authorization code and every SoC request failed. This switches the login to the current IDPConnect OAuth2 flow, mirroring the well-maintained hyundai_kia_connect_api library (KiaUvoApiEU) used by Home Assistant: * GET /auth/api/v2/user/oauth2/authorize (obtain session cookies) * GET /auth/api/v1/accounts/certs (RSA public key as JWK) * RSA/PKCS#1 v1.5 encrypt the password (hex) * POST /auth/account/signin (302 -> ?code=...) * POST /auth/api/v2/user/oauth2/token (client_secret, form-urlencoded) refreshToken() is updated to the IDPConnect token endpoint and keeps a rotated refresh_token when the server returns one. If the refresh grant fails (expired/rotated refresh token), fetch_soc() now falls back to a full login instead of leaving the module stuck after the first poll - same strategy as hyundai_kia_connect_api's refresh_access_token(). Password encryption uses 'cryptography' (already pulled in transitively by requests) with a 'pycryptodome' fallback, so no new hard dependency is introduced. Robustness fixes: * getAuthCode() uses its own requests.Session for the cookie chain and no longer calls getCookies() (dead Keycloak endpoints). * RAMDISK_PATH import is wrapped so a missing helpermodules.constants export falls back to <openWB-root>/ramdisk instead of crashing the whole module import. * postHTTP() raises RuntimeError with the HTTP status/error text, and the token functions pre-initialise 'response' so a failed request no longer masks the real cause with "local variable 'response' referenced before assignment". Tested on openWB 2.2.1 (Kia EV6): SoC is read on the initial poll and on subsequent refresh polls, no errors in main.log; RSA round-trip verified against a locally generated key pair. * fix(vehicles/kia): remove unused client_secret variable (flake8 F841)
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Kia/Hyundai SoC adapter stopped working: Hyundai/Kia decommissioned the old Keycloak form login (eu-account..com/auth/realms/...), so getAuthCode() could no longer obtain an authorization code and every SoC request failed.
This switches the login to the current IDPConnect OAuth2 flow, mirroring the well-maintained hyundai_kia_connect_api library (KiaUvoApiEU) used by Home Assistant:
refreshToken() is updated to the IDPConnect token endpoint and keeps a rotated refresh_token when the server returns one. If the refresh grant fails (expired/rotated refresh token), fetch_soc() now falls back to a full login instead of leaving the module stuck after the first poll - same strategy as hyundai_kia_connect_api's refresh_access_token().
Password encryption uses 'cryptography' (already pulled in transitively by requests) with a 'pycryptodome' fallback, so no new hard dependency is introduced.
Robustness fixes:
Tested on openWB 2.2.1 (Kia EV6): SoC is read on the initial poll and on subsequent refresh polls, no errors in main.log; RSA round-trip verified against a locally generated key pair.