Skip to content

Commit d152ed1

Browse files
swingermanclaude
andcommitted
Fix viomi map download by triggering a cloud map upload
Viomi vacuums do not keep a map in the cloud. They upload the current map only when sent the set_uploadmap miio command, and the uploaded map is stored as cloud object "1" (not "0"). ViomiCloudVacuum therefore always failed to download a map with "Object Not Found". ViomiCloudVacuum now overrides get_map_name() to send set_uploadmap through the existing cloud miio relay (get_other_info -> /v2/home/rpc/<device_id>) before returning map name "1". This keeps the viomi platform pure-cloud, with no local connection added. On a failed upload it returns None so the caller raises FailedMapDownloadException and retries. Also widens get_other_info's parameters annotation to dict | list: legacy miio commands such as set_uploadmap take positional list params. Verified end-to-end against a live viomi.vacuum.v8. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 688fe3e commit d152ed1

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

custom_components/xiaomi_cloud_map_extractor/connector/vacuums/vacuum_viomi.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1+
import asyncio
2+
import logging
13
from typing import Self
24

35
from vacuum_map_parser_viomi.map_data_parser import ViomiMapDataParser
46
from .base.model import VacuumConfig, VacuumApi
57
from .base.vacuum_v2 import BaseXiaomiCloudVacuumV2
68

9+
_LOGGER = logging.getLogger(__name__)
10+
11+
# Viomi vacuums do not keep a map in the cloud. They upload the current map only
12+
# when asked to via the `set_uploadmap` miio command; the uploaded map then
13+
# becomes available as cloud object "1". Without this request the cloud object
14+
# does not exist and the map download fails with "Object Not Found".
15+
_UPLOAD_MAP_METHOD = "set_uploadmap"
16+
_UPLOAD_MAP_PARAMS = [1]
17+
_VIOMI_MAP_NAME = "1"
18+
_MAP_UPLOAD_DELAY = 3
19+
720

821
class ViomiCloudVacuum(BaseXiaomiCloudVacuumV2):
922
_viomi_map_data_parser: ViomiMapDataParser
@@ -29,3 +42,13 @@ def map_archive_extension(self: Self) -> str:
2942
@property
3043
def map_data_parser(self: Self) -> ViomiMapDataParser:
3144
return self._viomi_map_data_parser
45+
46+
async def get_map_name(self: Self) -> str | None:
47+
_LOGGER.debug("Requesting viomi map upload via cloud RPC")
48+
response = await self._connector.get_other_info(
49+
self._device_id, _UPLOAD_MAP_METHOD, _UPLOAD_MAP_PARAMS)
50+
if response is None or response.get("code") != 0:
51+
_LOGGER.warning("Viomi map upload request was not acknowledged: %s", response)
52+
return None
53+
await asyncio.sleep(_MAP_UPLOAD_DELAY)
54+
return _VIOMI_MAP_NAME

custom_components/xiaomi_cloud_map_extractor/connector/xiaomi_cloud/connector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ async def get_device_details(self: Self, device_id: str, server: Optional[str] =
714714
matching_device = filter(lambda device: device.device_id == device_id, devices)
715715
return next(matching_device, None)
716716

717-
async def get_other_info(self: Self, device_id: str, method: str, parameters: dict) -> Any:
717+
async def get_other_info(self: Self, device_id: str, method: str, parameters: dict | list) -> Any:
718718
url = self.get_api_url() + "/v2/home/rpc/" + device_id
719719
params = {
720720
"data": json.dumps({"method": method, "params": parameters}, separators=(",", ":"))

0 commit comments

Comments
 (0)