Skip to content

Fix room detection and extract no-go zones, virtual walls and obstacles for xiaomi.vacuum.ov21gl#748

Open
luchusnet wants to merge 3 commits into
PiotrMachowski:dev_extracted_librariesfrom
luchusnet:fix/xiaomi-ov21gl-rooms-and-map-objects
Open

Fix room detection and extract no-go zones, virtual walls and obstacles for xiaomi.vacuum.ov21gl#748
luchusnet wants to merge 3 commits into
PiotrMachowski:dev_extracted_librariesfrom
luchusnet:fix/xiaomi-ov21gl-rooms-and-map-objects

Conversation

@luchusnet

@luchusnet luchusnet commented Jun 7, 2026

Copy link
Copy Markdown

Problem

On some Xiaomi models (confirmed: xiaomi.vacuum.ov21gl / Xiaomi Robot Vacuum 5 Pro), every entry in map_room_info has room_id=0 due to a firmware quirk. The vacuum_map_parser_xiaomi library uses room_id as a dict key, so all rooms overwrite each other and collapse into a single Room object — resulting in 1 room instead of the actual 14.

Additionally, the library does not parse fb_regions (no-go zones), fb_walls (virtual walls), or ai_obj (AI-detected obstacles) from the JSON payload.

Finally, when the vacuum's LAN is temporarily unreachable (e.g. during active cleaning), the should_update_map MiOT status check throws a DeviceException. The previous code returned False on any non-token exception, stopping all cloud map downloads for the rest of the session.

Fix

Room detection (_fix_map_room_info)

In decode_and_parse(), the JSON payload is intercepted before being passed to parse(). If all room_id values are identical, each is replaced with its grid_id (which is unique and matches the id field used in room_attrs). This restores correct room detection.

No-go zones & virtual walls (_normalize_firmware_map_objects)

Normalizes the firmware-specific fb_regions/fb_walls format to the library's expected format before calling parse(), so the library renders them in the camera image.

AI obstacles (_extract_obstacles)

Extracts ai_obj entries post-parse and injects them into MapData.obstacles (non-destructive, only if the library left it empty).

Map not updating during cleaning (should_update_map)

When the LAN status check fails with a non-token DeviceException, now returns True instead of False, so cloud map downloads continue even when LAN is temporarily unreachable.

Tested on

  • xiaomi.vacuum.ov21gl (Xiaomi Robot Vacuum 5 Pro)
  • 14 rooms correctly detected ✓
  • 2 no-go zones correctly exposed ✓
  • 1 virtual wall correctly exposed ✓
  • Map continues updating from cloud when LAN is unresponsive ✓

Luciano Benitez and others added 3 commits June 7, 2026 16:22
…es for xiaomi.vacuum.ov21gl

Some Xiaomi models (e.g. xiaomi.vacuum.ov21gl / Xiaomi Robot Vacuum 5 Pro) have a
firmware quirk where every entry in map_room_info has room_id=0. The upstream
vacuum_map_parser_xiaomi library uses room_id as a dict key, which causes all rooms
to collapse into a single Room object.

Fix: in decode_and_parse(), intercept the JSON payload before passing it to parse().
If all room_ids are identical, replace each room_id with its grid_id (which is unique
and matches the id field used in room_attrs). This restores correct room detection
(14 rooms instead of 1).

Additionally, the library does not parse fb_regions (no-go zones), fb_walls
(virtual walls), or ai_obj (AI-detected obstacles). These are now extracted manually
in a new _extract_map_objects() static method and injected into the MapData after
the library parse, only if the library left those fields empty.
The library's parse() calls draw_map() internally, so zones injected
after parse() were never rendered. Fix by normalizing the firmware's
fb_regions/fb_walls format to the library's expected format before
calling parse(), so all elements are rendered in the camera image.

Firmware format:
  fb_regions: [{"fb_point": [x0,y0,x1,y1,x2,y2,x3,y3]}]
  fb_walls:   [{"wall_points": [x0,y0,x1,y1]}]

Library expected format:
  fb_regions: [{"type": "no_go"|"wall", "points": [{"x":..,"y":..},...]}]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the vacuum is actively cleaning its LAN may be unresponsive,
causing should_update_map's MiOT property read to throw a DeviceException.
The previous code returned False on any non-token DeviceException, which
stopped all cloud map downloads for the rest of the session.

Return True instead so the cloud map continues to be fetched even when the
local LAN status check fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@luchusnet

Copy link
Copy Markdown
Author

@PiotrMachowski Friendly bump 🙂

This PR has been running on my OV21GL (Xiaomi Robot Vacuum 5 Pro) for the past week without issues — room detection, no-go zones, virtual walls and obstacles all extract correctly. Happy to address any feedback or make adjustments if you have time to take a look.

Diff is small (+125/-3), focused on OV21GL specifics. Thanks for maintaining this great project!

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