Howto: Xiaomi vacuum zoned cleaning

I’m using the Xiaomi integration plus the cloud Map extractor. I want to be able to pull out the rooms easier…but not sure how to install the MauricioXavier13/vacuum_miio. I tried via HACS, but the repository was not listed in HACs and I could not install it as a customer repository.

Looking at your Mi Home picture map, not sure if your vacuum was able to properly determine rooms.

Please start from the Mi Home vacuum function ‘Edit zone’, to make sure all your individual rooms are identified (usually coloured in different colours in the map).

After this, if you have access to a Debian environment with Python, you can get your rooms, by doing the following:

  1. Install Python Miio
  2. Follow instructions in https://www.home-assistant.io/integrations/xiaomi_miio/#retrieving-room-numbers.

Please let us know if you succeed, as getting this to work will make your life MUCH easier in getting HA to control your vacuum.

1 Like

Trying to retrieve the room IDs with miiocli was kind of a failure as described here.

The good news is I managed to find the right combination in my script using the zone coordinates but with a different service :tada:

service: xiaomi_miio.vacuum_clean_zone
target:
  entity_id: vacuum.vacuum
data:
  zone:
    - - 28625
      - 23989
      - 32288
      - 27123
  repeats: 1
1 Like

Do you know if it’s possible to add repeats to this method?

Hi, in the script is it possible to add the suction power? Thanks

Same problem here… were you able to resolve it?

May I ask you how did you get the zone coordinates?

I got the coordinates following this video, especially at this precise time Roborock Vacuum // Zone & Voice Assistant Control in Home Assistant - YouTube
The trick is to use debug: true
It’s very well explained and following this guy’s tutorial I was able to create this card

Its yaml code is :

type: vertical-stack
cards:
  - type: custom:xiaomi-vacuum-map-card
    map_source:
      camera: camera.xiaomi_cloud_map_extractor
    calibration_source:
      camera: true
    entity: vacuum.vacuum
    vacuum_platform: default
  - type: button
    tap_action:
      action: toggle
    entity: script.vacuum_kitchen_with_zone
    show_icon: true
    show_name: true
    name: Vacuum Kitchen
    show_state: true

The button’s script above (script.vacuum_kitchen_with_zone) is :

alias: Vacuum kitchen with zone
sequence:
  - service: xiaomi_miio.vacuum_clean_zone
    target:
      entity_id: vacuum.vacuum
    data:
      zone:
        - - 28625
          - 23989
          - 32288
          - 27123
      repeats: 1
mode: single
icon: mdi:robot-vacuum

Hope this helps !

2 Likes

Do you know if you can select the “Cleanup Mode” as part of your script?
I assume this is possible via “Send_Command” but I don’t know where to find a list of command codes.


Selecting Vacuum Only prevents the unit from cleaning the mop, a waste when cleaning carpet only rooms.

Sorry for the late response.
I don’t know much about those vacuum options and I heavily rely on video tutorials and posts on this forum.
I found the correct syntax above after quite some research and tests.
It really is a hit-and-miss experience :sweat:

I heavily rely on video tutorials and posts on this forum.

Which videos or posts?
I’ve not seen any to change to vacuum only mode. I wonder if it is unique to the Max V Ultra (since it can clean the mop)

I was refering to this video in my earlier post

But I don’t know about the mode. Haven’t played with it myself.

conchita_pasillo:

  alias: "Conchita Pasillo"

  icon: mdi:robot-vacuum

  mode: single

  sequence:

    - service: xiaomi_miio.vacuum_clean_zone

      target:

        entity_id: vacuum.roborock_s5

      data:

        zone: [[23439,21645,24239,25295]]

        repeats: 1

Or simple like this:

alias: Run Vacuum
sequence:
  - service: roborock.vacuum_clean_segment
    data_template:
      segments: |
        {% set vacrooms = namespace(roomid=[]) %}
        {% for rooms in state_attr('sensor.roborock_rooms','rooms') -%}
          {% if is_state(rooms.boolean,'on') %}
            {% set room = rooms.id %}
            {% set vacrooms.roomid = vacrooms.roomid + [room] %}
          {% endif %}
        {%- endfor %}
        {{ vacrooms.roomid }}
    target:
      entity_id: vacuum.roborock_s7
mode: single
icon: mdi:robot-vacuum

And have a sensor with all your data in it for the rooms. Read this (of course with you data into a sensor):

{
    "rooms": [
        {
            "name": "kitchen",
            "boolean": "input_boolean.vac_kitchen",
            "id": "17"
            },
        {
            "name": "dining_room",
            "boolean": "input_boolean.vac_dining_room",
            "id": "16"
            },
        {
            "name": "foyer",
            "boolean": "input_boolean.vac_foyer",
            "id": "18"
            },
        {
            "name": "laundry",
            "boolean": "input_boolean.vac_laundry",
            "id": "20"
            },
        {
            "name": "living_room",
            "boolean": "input_boolean.vac_living_room",
            "id": "19"
            },
        {
            "name": "master_bedroom",
            "boolean": "input_boolean.vac_master_bedroom",
            "id": "21"
            },
        {
            "name": "master_bathroom",
            "boolean": "input_boolean.vac_master_bathroom",
            "id": "22"
            },
        {
            "name": "guest_bathroom",
            "boolean": "input_boolean.vac_guest_bathroom",
            "id": "23"
            }
    ],
    "points": [
        {
            "name": "sink",
            "x": 17989,
            "y": 25491
         }
    ]
}

And you can have a GUI that allows you to select one or more rooms and clean them:

So I select Kitchen, Dining and Foyer and say “Clean” and away it goes.

1 Like

How do you create your sensor from the json data? Via file? Trying to figure out best way to set this up

I use this:

##
## Roborock Rooms 
##
- platform: rest
  name: roborock_rooms
  resource: http://192.168.1.245:8123/local/Roborock/roborock.json
  value_template: "{{ now() }}"
  json_attributes:
    - rooms
    - points

With this JSON file in my install:

{
    "rooms": [
        {
            "name": "kitchen",
            "boolean": "input_boolean.vac_kitchen",
            "id": "17"
            },
        {
            "name": "dining_room",
            "boolean": "input_boolean.vac_dining_room",
            "id": "16"
            },
        {
            "name": "foyer",
            "boolean": "input_boolean.vac_foyer",
            "id": "18"
            },
        {
            "name": "laundry",
            "boolean": "input_boolean.vac_laundry",
            "id": "20"
            },
        {
            "name": "living_room",
            "boolean": "input_boolean.vac_living_room",
            "id": "19"
            },
        {
            "name": "master_bedroom",
            "boolean": "input_boolean.vac_master_bedroom",
            "id": "21"
            },
        {
            "name": "master_bathroom",
            "boolean": "input_boolean.vac_master_bathroom",
            "id": "22"
            },
        {
            "name": "guest_bathroom",
            "boolean": "input_boolean.vac_guest_bathroom",
            "id": "23"
            }
    ],
    "points": [
        {
            "name": "sink",
            "x": 17989,
            "y": 25491
         }
    ]
}

Positive I could vastly improve this but it works and I have bigger things I am tackling now.

Is it possible to get a little bit more details (configuration), I would like to implement this in my home assistant instance

We’ll most all the details are posted above so its not clear what help you need.

  1. Have you created a JSON file with your rooms?
  2. In the 2 code listings above, if you did those you could look at state of sensor.roborock_rooms and see something, do you see anything?

Yeah I got it, a little bit different, but it’s working now.
But I want to set the repeat based on an input_number.

The result should be like this:

params:
  domain: vacuum
  service: send_command
  service_data:
    command: app_segment_clean
    params:
      - segments:
          - 19
          - 17
        repeat: 2
    device_id: a99866ff22359ab1ad482e60475949a3
  target: {}
running_script: false

But I dont know how to get the repeat at the correct position.

service: vacuum.send_command
data:
  command: app_segment_clean
  params:
    - segments: |
        {% set rooms = [ ['wohnen', 18],
                         ['kueche', 19],
                         ['flur', 17],
                         ['buero', 21],
                         ['essen', 20],
                         ['hwr', 16],
                         ['ar', 22] ] %}  
        {% set ns = namespace(x = '') %}

        {% for room in rooms if
        is_state('input_boolean.staubsauger_raum_eg_' ~ room[0] , 'on') %}
            {% set ns.x = ns.x ~ room[1] ~ (',') %}
        {% endfor %}

        {{ ns.x }} 
      repeat: 2

If I replace “repeat: 2” with the following line, ist not correct anymore
{{ " repeat: " ~ states(‘input_number.staubsauger_anzahl’)|round }}

params:
  domain: vacuum
  service: send_command
  service_data:
    command: app_segment_clean
    params:
      - segments: |-
          17,16, 
            repeat: 2
    device_id: a99866ff22359ab1ad482e60475949a3
  target: {}
running_script: false

Sorry for delayed response.
I use a different integration, but to understand how to build such a request I would use the Developer tools.

It looks like this:

SO the YAML you can view is this:

service: roborock.vacuum_clean_segment
data:
  segments:
    - 17
    - 18
  repeats: 2
target:
  entity_id: vacuum.roborock_s7

So your “repeat” is likely “repeats” and the indentation looks wrong.
I would also build the namespaced variable as an array and not a string with commas (but maybe your vacuum requires that).

NOTE: I could be wrong because I see value in being able to say … clean kitchen twice, clean dining room once which would imply repeats would go under each segment as an object. I use:

And that is not how it works I believe. You can establish a list of segments and set the number of times they are cleaned (but not individually).

1 Like