Repository navigation
fix(cloud): use the same login method as the code request in cloud im… - #115
Merged
Lash-L merged 1 commit intoSep 28, 2026
Merged
Conversation
…port RoborockApiClient.request_code_v4() silently falls back to the v1 sendEmailCode endpoint when getUrlByEmail resolves a country_code but no country (observed on usiot for at least one UK/EU account). cloud.py stored that fallback as country="None" (a string) and then built a new RoborockApiClient for submit_code(), which re-derived country from euiot and always attempted the v4 login. Sending a v1 code and logging in with v4 makes Roborock reject every code with response 2018 (RoborockInvalidCode). Record which method request_code() actually used (mirroring the library's own fallback rule) and store country as str | None instead of stringifying it. submit_code() now replays that exact method (code_login for v1, code_login_v4 with the stored country/country_code for v4) instead of re-deriving anything. Adds regression coverage in tests/test_cloud.py for both the v1 fallback path and the normal v4 path.
Contributor
|
TY! Believe it or not, I have made this mistake historically when it comes to working with regions... Appreciate the PR! |
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.
First thanks a lot for this project - happy to have now be running fully local! Hit a snag whilst implementing it myself though, hence this PR.
The Issue
Cloud import on the admin page ("Send Code" → "Fetch Data") wouldn't accept any code I gave it, just
Invalid code - check your code and try again.every time. I'm in the UK on the EU cloud. The response after sending the code also showed"country": "None", as a string, which was the first clue.Why
The code gets sent one way and the login tries another:
countrycode=44but no country, and because the lookup stops at the first answer with either, euiot never gets asked.request_code_v4()quietly falls back to the old v1 endpoint to send the code.request_code()then saved the country asstr(None), so the string"None".submit_code()makes a new client pinned to euiot and callscode_login_v4withcountry=session_data.country or None. Because the saved value is the text"None"rather than an actualNone, theor Nonenever kicks in and the login goes v4. Even with a properNoneit'd still end up v4, because euiot does return a country (GB) when you ask it directly.HA's own Roborock setup doesn't hit this because it uses the same client for both steps, so it ends up v1/v1. It only breaks here because a second client works the country out again.
The fix
countryas a properNoneinstead of the string"None".submit_code(), log in the same way:code_login()for v1, orcode_login_v4()with the stored country/country_code for v4. Nothing gets looked up again.The v4 path works the same as before, apart from using the stored values.
Testing
tests/test_cloud.pywith a faked client, so no network:countryisNone, the login usescode_login, it doesn't look the country up again, and the device identifier carries over.ValueError.cloud.py, so they do catch it.uv run pytest -qpasses, all 244.