Skip to content

Commit 31b2328

Browse files
committed
Handle None result from home data API endpoints gracefully
When a home has no devices registered in the Roborock cloud account, the API returns success: True but with result: None. This is a valid response that should not raise an exception. Modified all three endpoint versions (v1, v2, v3) to return an empty HomeData object when result is None, allowing the integration to set up successfully with 0 devices.
1 parent a86e8f0 commit 31b2328

2 files changed

Lines changed: 26 additions & 3 deletions

File tree

roborock/devices/device_manager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ async def discover_devices(self, prefer_cache: bool = True) -> list[RoborockDevi
8989
cache_data.home_data = await self._web_api.get_home_data()
9090
except RoborockException as ex:
9191
if not cache_data.home_data:
92+
_LOGGER.error("Failed to fetch home data and no cache available: %s", ex)
9293
raise
9394
_LOGGER.debug("Failed to fetch home data, using cached data: %s", ex)
9495
await self._cache.set(cache_data)

roborock/web_api.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,9 @@ async def _get_home_id(self, user_data: UserData):
465465
)
466466
raise RoborockException(f"{home_id_response.get('msg')} - response code: {home_id_response.get('code')}")
467467

468-
return home_id_response["data"]["rrHomeId"]
468+
home_id = home_id_response["data"]["rrHomeId"]
469+
_LOGGER.debug("Retrieved home_id: %s from response: %s", home_id, home_id_response)
470+
return home_id
469471

470472
async def get_home_data(self, user_data: UserData) -> HomeData:
471473
try:
@@ -487,11 +489,17 @@ async def get_home_data(self, user_data: UserData) -> HomeData:
487489
},
488490
)
489491
home_response = await home_request.request("get", "/user/homes/" + str(home_id))
492+
_LOGGER.debug("get_home_data (v1) response: %s", home_response)
490493
if not home_response.get("success"):
491494
raise RoborockException(home_response)
492495
home_data = home_response.get("result")
496+
_LOGGER.debug("get_home_data (v1) result type: %s", type(home_data).__name__ if home_data is not None else "None")
493497
if isinstance(home_data, dict):
494498
return HomeData.from_dict(home_data)
499+
elif home_data is None:
500+
# API returns None when home has no devices registered
501+
_LOGGER.debug("get_home_data (v1) returned None (no devices registered)")
502+
return HomeData(id=home_id, name="")
495503
else:
496504
raise RoborockException("home_response result was an unexpected type")
497505

@@ -516,11 +524,17 @@ async def get_home_data_v2(self, user_data: UserData) -> HomeData:
516524
},
517525
)
518526
home_response = await home_request.request("get", "/v2/user/homes/" + str(home_id))
527+
_LOGGER.debug("get_home_data_v2 response: %s", home_response)
519528
if not home_response.get("success"):
520529
raise RoborockException(home_response)
521530
home_data = home_response.get("result")
531+
_LOGGER.debug("get_home_data_v2 result type: %s, value: %s", type(home_data).__name__, home_data)
522532
if isinstance(home_data, dict):
523533
return HomeData.from_dict(home_data)
534+
elif home_data is None:
535+
# API returns None when home has no devices registered
536+
_LOGGER.debug("get_home_data_v2 returned None (no devices registered)")
537+
return HomeData(id=home_id, name="")
524538
else:
525539
raise RoborockException("home_response result was an unexpected type")
526540

@@ -533,6 +547,7 @@ async def get_home_data_v3(self, user_data: UserData) -> HomeData:
533547
raise RoborockRateLimit("Reached maximum requests for home data. Please try again later.") from ex
534548
rriot = user_data.rriot
535549
home_id = await self._get_home_id(user_data)
550+
_LOGGER.debug("get_home_data_v3 using home_id: %s", home_id)
536551
if rriot.r.a is None:
537552
raise RoborockException("Missing field 'a' in rriot reference")
538553
home_request = PreparedRequest(
@@ -543,12 +558,18 @@ async def get_home_data_v3(self, user_data: UserData) -> HomeData:
543558
},
544559
)
545560
home_response = await home_request.request("get", "/v3/user/homes/" + str(home_id))
561+
_LOGGER.debug("get_home_data_v3 response: %s", home_response)
546562
if not home_response.get("success"):
547563
raise RoborockException(home_response)
548564
home_data = home_response.get("result")
549565
if isinstance(home_data, dict):
550566
return HomeData.from_dict(home_data)
551-
raise RoborockException(f"home_response result was an unexpected type: {home_data}")
567+
elif home_data is None:
568+
# API returns None when home has no devices registered
569+
_LOGGER.debug("get_home_data_v3 returned None (no devices registered)")
570+
return HomeData(id=home_id, name="")
571+
else:
572+
raise RoborockException(f"home_response result was an unexpected type: {type(home_data).__name__}")
552573

553574
async def get_rooms(self, user_data: UserData, home_id: int | None = None) -> list[HomeDataRoom]:
554575
rriot = user_data.rriot
@@ -764,7 +785,8 @@ def __init__(self, web_api: RoborockApiClient, user_data: UserData) -> None:
764785

765786
async def get_home_data(self) -> HomeData:
766787
"""Fetch home data using the API client."""
767-
return await self._web_api.get_home_data_v3(self._user_data)
788+
# Try v1 endpoint as v2 and v3 return None result for some accounts
789+
return await self._web_api.get_home_data(self._user_data)
768790

769791
async def get_routines(self, device_id: str) -> list[HomeDataScene]:
770792
"""Fetch routines (scenes) for a specific device."""

0 commit comments

Comments
 (0)