Skip to content

Trigger viomi map upload before downloading the map#745

Open
swingerman wants to merge 1 commit into
PiotrMachowski:dev_extracted_librariesfrom
swingerman:fix/viomi-cloud-map-upload
Open

Trigger viomi map upload before downloading the map#745
swingerman wants to merge 1 commit into
PiotrMachowski:dev_extracted_librariesfrom
swingerman:fix/viomi-cloud-map-upload

Conversation

@swingerman
Copy link
Copy Markdown

Problem

Viomi vacuums never produce a map. ViomiCloudVacuum inherits get_map_name()
from BaseXiaomiCloudVacuum, which returns "0", so the download requests cloud
object <user_id>/<device_id>/0. For viomi devices that object does not exist —
every download fails (FailedMapDownloadException; FDS returns Object Not Found).

Root cause: unlike roborock, viomi vacuums do not keep a map in the cloud. They
upload the current map to Xiaomi FDS storage only when explicitly told to, via the
set_uploadmap miio command, and the uploaded map is stored as object 1 — not
0. The Mi Home app sends set_uploadmap whenever its map view is opened; the
integration never does.

Fix

ViomiCloudVacuum now overrides get_map_name() to:

  1. send set_uploadmap to the vacuum through the existing cloud miio relay
    XiaomiCloudConnector.get_other_info()/v2/home/rpc/<device_id> — so the
    viomi platform stays pure-cloud (no local miio connection added);
  2. wait briefly for the vacuum to push the map;
  3. return map name "1".

If the upload request is not acknowledged it returns None, so the caller raises
FailedMapDownloadException and retries on the next cycle (rather than masking the
failure) — consistent with the other vacuum implementations.

This also widens get_other_info()'s parameters annotation from dict to
dict | list: legacy miio commands such as set_uploadmap take positional list
params, whereas the existing dreame caller passes a dict.

Testing

Verified end-to-end against a live viomi.vacuum.v8 ("Mi Robot Vacuum-Mop P", EU
server):

  • get_other_info(device_id, "set_uploadmap", [1]){"code":0,"message":"ok","result":["ok"]}
  • afterwards cloud object 1 contains the map; object 0 stays absent
  • the real ViomiCloudVacuum.get_map() then downloads (~8 KB zlib) and parses it
    into an 800×800, 5-room map

Before this change the same vacuum produced no map on v3 (or on v2.2.x).

Notes

  • The map slot (1) and the set_uploadmap parameter ([1]) were determined
    empirically on viomi.vacuum.v8; set_uploadmap [0] did not populate slot 0
    on the test unit. Other viomi models would benefit from validation.
  • Possible follow-up: viomi inherits the base should_update_map (always True),
    so the upload is requested every coordinator cycle even when the vacuum is idle.
    An override that checks vacuum state (as roborock does) could avoid that.

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.
@swingerman swingerman force-pushed the fix/viomi-cloud-map-upload branch from d152ed1 to 1008cb8 Compare May 18, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant