Skip to content

Commit 910ff18

Browse files
authored
Merge branch 'main' into dynamic_status_trait
2 parents aab737c + e438364 commit 910ff18

File tree

6 files changed

+146
-89
lines changed

6 files changed

+146
-89
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22

33
<!-- version list -->
44

5+
## v4.5.0 (2026-01-14)
6+
7+
### Chores
8+
9+
- Add test ([#743](https://github.com/Python-roborock/python-roborock/pull/743),
10+
[`e26e351`](https://github.com/Python-roborock/python-roborock/commit/e26e351474a006485c6a7b5a5dcdbbe9fab8572e))
11+
12+
### Features
13+
14+
- Raise no account error when bad login
15+
([#743](https://github.com/Python-roborock/python-roborock/pull/743),
16+
[`e26e351`](https://github.com/Python-roborock/python-roborock/commit/e26e351474a006485c6a7b5a5dcdbbe9fab8572e))
17+
18+
519
## v4.4.0 (2026-01-12)
620

721
### Features

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "python-roborock"
3-
version = "4.4.0"
3+
version = "4.5.0"
44
description = "A package to control Roborock vacuums."
55
authors = [{ name = "humbertogontijo", email = "humbertogontijo@users.noreply.github.com" }, {name="Lash-L"}, {name="allenporter"}]
66
requires-python = ">=3.11, <4"

roborock/data/zeo/zeo_code_mappings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class ZeoState(RoborockEnum):
1818
cooling = 8
1919
under_delay_start = 9
2020
done = 10
21+
aftercare = 12
22+
waiting_for_aftercare = 13
2123

2224

2325
class ZeoProgram(RoborockEnum):

roborock/web_api.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ async def code_login_v4(
359359
raise RoborockInvalidUserAgreement(
360360
"User agreement must be accepted again - or you are attempting to use the Mi Home app account."
361361
)
362+
if response_code == 3039:
363+
raise RoborockAccountDoesNotExist(
364+
"This account does not exist - please ensure that you selected the right region and email."
365+
)
362366
raise RoborockException(f"{login_response.get('msg')} - response code: {response_code}")
363367
user_data = login_response.get("data")
364368
if not isinstance(user_data, dict):

tests/test_web_api.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from aioresponses.compat import normalize_url
77

88
from roborock import HomeData, HomeDataScene, UserData
9+
from roborock.exceptions import RoborockAccountDoesNotExist
910
from roborock.web_api import IotLoginInfo, RoborockApiClient
1011
from tests.mock_data import HOME_DATA_RAW, USER_DATA
1112

@@ -88,6 +89,42 @@ async def test_code_login_v4_flow(mock_rest) -> None:
8889
assert ud == UserData.from_dict(USER_DATA)
8990

9091

92+
async def test_code_login_v4_account_does_not_exist(mock_rest) -> None:
93+
"""Test that response code 3039 raises RoborockAccountDoesNotExist."""
94+
mock_rest.clear()
95+
96+
mock_rest.post(
97+
re.compile(r"https://.*iot\.roborock\.com/api/v1/getUrlByEmail.*"),
98+
status=200,
99+
payload={
100+
"code": 200,
101+
"data": {"country": "US", "countrycode": "1", "url": "https://usiot.roborock.com"},
102+
"msg": "success",
103+
},
104+
)
105+
mock_rest.post(
106+
re.compile(r"https://.*iot\.roborock\.com/api/v4/email/code/send.*"),
107+
status=200,
108+
payload={"code": 200, "data": None, "msg": "success"},
109+
)
110+
mock_rest.post(
111+
re.compile(r"https://.*iot\.roborock\.com/api/v3/key/sign.*"),
112+
status=200,
113+
payload={"code": 200, "data": {"k": "mock_k"}, "msg": "success"},
114+
)
115+
mock_rest.post(
116+
re.compile(r"https://.*iot\.roborock\.com/api/v4/auth/email/login/code.*"),
117+
status=200,
118+
payload={"code": 3039, "data": None, "msg": "account does not exist"},
119+
)
120+
121+
api = RoborockApiClient(username="test_user@gmail.com")
122+
await api.request_code_v4()
123+
with pytest.raises(RoborockAccountDoesNotExist) as exc_info:
124+
await api.code_login_v4(4123, "US", 1)
125+
assert "This account does not exist" in str(exc_info.value)
126+
127+
91128
async def test_url_cycling(mock_rest) -> None:
92129
"""Test that we cycle through the URLs correctly."""
93130
# Clear mock rest so that we can override the patches.

0 commit comments

Comments
 (0)