Skip to content

Q7 (B01 / sc01): working zone cleaning command format (set_zone_points + set_zone_clean) #992

Open

Description

@luckiesdavid

Summary

Zone cleaning on the Roborock Q7 (B01 protocol, model roborock.vacuum.sc01, tested on a Q7 L5+) works via raw send_command calls. The format does not seem to be documented anywhere yet (roborock-q7x lists it as "not reverse-engineered"), so I'm sharing what I verified. It would be great to see this as a clean_zone trait for Q7, so HA's roborock.set_vacuum_zoned_cleaning can support it.

Working command sequence

The order matters. This is the same sequence the Roborock app uses:

  1. service.set_preference_type with {"prefer_type": 4} → afterwards custom_type reads 4 (= zones)
  2. service.set_zone_points with {"zone_points": [x1, y1, x2, y1, x2, y2, x1, y2]}
    • flat list of the rectangle's corner points
    • response on success: {"map_id": <current map id>, "map_type": 0, "timestamp": ...}
  3. service.set_zone_clean with {"ctrl_value": 1} (no zone data here)

→ the robot reports work_mode: 30 (plan_area), cleans the zone, and creates a history record with record_clean_mode: 3.

Coordinate system (the important part)

  • zone_points are floats in meters in the map's world coordinate system, i.e. the same frame as cur_path, MapHeadInfo.minX/minY and chargeStation in the SCMap protobuf (y axis pointing up, origin near the dock).
  • Projection used by the app: px = (x - minX) / resolution, py = sizeY - (y - minY) / resolution.
  • Example that cleaned a ~1.1 × 1.2 m zone correctly:
    [2.0, -3.9, 3.1, -3.9, 3.1, -2.7, 2.0, -2.7]
  • Integer values in mm (e.g. 2000) are interpreted as meters → the target is far outside the map → after ~60 s fault 2007 (cannot_reach_target) and the robot returns.

Pitfalls observed

  • set_zone_clean without a preceding successful set_zone_points → code 1, and in some cases the robot afterwards falls back to a full cleaning (custom_type 0).
  • When a task is running (e.g. returning to dock), stop it first (set_room_clean {"clean_type":0,"ctrl_value":0,"room_ids":[]} / set_zone_clean {"ctrl_value":0}). Otherwise the zone may not be applied and a full clean can start.
  • Stop zone cleaning: service.set_zone_clean with {"ctrl_value": 0}.
  • After re-mapping, the map id changes (room IDs and possibly the coordinate origin shift as well), so HA's vacuum.clean_area area mapping has to be updated.

Home Assistant workaround (until native support)

sequence:
  - action: vacuum.send_command
    target: {entity_id: vacuum.roborock_q7_l5}
    data: {command: service.set_preference_type, params: {prefer_type: 4}}
  - delay: {seconds: 1}
  - action: vacuum.send_command
    target: {entity_id: vacuum.roborock_q7_l5}
    data:
      command: service.set_zone_points
      params: {zone_points: [2.0, -3.9, 3.1, -3.9, 3.1, -2.7, 2.0, -2.7]}
  - delay: {seconds: 3}
  - action: vacuum.send_command
    target: {entity_id: vacuum.roborock_q7_l5}
    data: {command: service.set_zone_clean, params: {ctrl_value: 1}}

Happy to test a PR on my Q7 L5+.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions