feat: multi-region support (fixes 1501 "geelyos verify error" outside the EU) - #3
Open
alexandrepossebom wants to merge 1 commit into
Open
feat: multi-region support (fixes 1501 "geelyos verify error" outside the EU)#3alexandrepossebom wants to merge 1 commit into
alexandrepossebom wants to merge 1 commit into
Conversation
The integration hard-coded the EU backend (api/apis.ecloudeu.com, m-lcmsam-eu.geely.com) and the EU app credentials (GEELYE245). Vehicles registered in another region fail device-cert provisioning with `1501 geelyos verify error`, because the cert server verifies the token against that region's GeelyOS — see nitaybz#1. Region is now derived from the login response (`tspInfo[].serviceRegion` / `edgeInfo.code`), NOT the country code: a Brazil account can have an NA-region vehicle. A `REGIONS` table in const.py maps each region to its hosts + app credentials, and the client / provisioning / vehicle-list calls resolve hosts per-region. The chosen region is stored on the config entry (CONF_REGION). - const.py: add REGIONS table (EU + NA confirmed; APAC/SA hosts noted, credentials pending) + region_config() helper + CONF_REGION. - api.py: GeelyApi takes `region` and derives cert/control/app hosts + app_id/secret; provision_user_cert takes cert_host; list_vehicles takes app_host; add region_from_login(); rename EU-specific signer. - config_flow.py: derive + store region, provision on the right host. - __init__.py: build the client with the stored region. Verified end-to-end on a Brazil-market Geely EX2 (region NA, GEELYUS): device cert provisions and read + control (find_car) work. EU users are unaffected — their region resolves to EU with the same hosts/credentials as before.
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.
Refs #1 — this fixes the NA region (and lays the table down for the rest); AU
and TH are still blocked on credentials nobody has extracted yet, so the issue
should stay open for them.
The problem
Every host and credential is hardcoded to the EU region (
api/apis.ecloudeu.com,m-lcmsam-eu.geely.com, app idGEELYE245). A car registered in another regionfails certificate provisioning with
1501 geelyos verify error, because thecert server validates the token against the GeelyOS of its own region. That is
the error in #1, and it is not recoverable by retrying or by re-authenticating.
What I found
The region is not derivable from the account's country code. My test car is
a Geely EX2 bought in Brazil, on an account registered as BR, and it is
registered in the NA region. The authoritative source is the login response:
tspInfo[].serviceRegion— the vehicle's telematics regionedgeInfo.code— same value, at the top levelmasterInfo.codeis the identity centre (EU for my account) and is misleading;using it is what sends a Brazilian car to the EU hosts.
I verified the failure is invariant:
1501happens identically on the EU and SAhosts, with either the raw token or an accessCode obtained from getCode. Only
pointing at the correct region (NA) provisions the certificate.
What this PR changes
const.py: aREGIONStable (EU and NA) plusregion_config()andCONF_REGION. Each entry carries itsapp_id/app_secretand the three hoststhat differ per region: cert (provisioning), control (mTLS commands) and app
(getCode / vehicle list).
api.py:GeelyApi(region=...)derives hosts and credentials from that table;new
region_from_login();provision_user_cert()andlist_vehicles()takethe host explicitly. The request signer is renamed
_sign_request_for_api_ecloudeu→_sign_cert_request, since it was neverEU-specific.
config_flow.py: derives the region from the login response, provisionsagainst the right cert host, and stores
CONF_REGIONin the entry.__init__.py: builds the client with the stored region.Login (
access-app-global.geely.com) and captcha are global and unchanged.Compatibility
Existing EU installs keep working unchanged: the EU parameters are exactly the
current constants, and anything the login does not identify falls back to EU. No
entity IDs, unique IDs or config-entry keys change for them.
Verified
On a real car (EX2 MAX, model code
E22H-G, NA region):region_from_login()returns NA for the Brazilian car and EU for an EU account,
provision_user_cert()provisions a real certificate against the NA host(
cert/infoandcert/fileboth return code 1000), and the integration pollsstatus and executes commands normally afterwards. @Nathan-Cunha independently
confirmed the same branch works on a Geely EX5 in Brazil (49 entities, HA
2026.7.4) — see his comment in #1.
Two things worth calling out
GEELYUSis clearly regional, butGEELYE245is a model name (EX5). With only two data points (EU/EX5 andNA/EX2) I cannot separate the two hypotheses. This PR keys on region and says
so in a comment. If you have a third data point, it settles the question.
assets/host.txt(
*.ecloudkr.com,m-lcmsam-kr,tsp-geely-api-sa.xcloudsvc.com) but I haveno way to obtain their app id / secret, so they are commented out rather than
guessed. That is why this is
Refs #1and notFixes #1: the AU and THreporters in that thread need those credentials, and anyone who can capture a
login from those regions can fill the table in without touching any other
code.
The NA credentials are in the table in the same form the EU ones already are in
this repo.