Howto: Xiaomi vacuum zoned cleaning

Needs HA Version later than 0.68.xx

Hey there,

Xiaomi has recently released an update for its v1 vacuum that enabled it for the zoned cleaning and goto function that was previously only available to the v2 vacuum.

In this post you will get to know how to:

  • update to the latest firmware on your v1 to get access to the new functions
  • extract your token quickly and easily and setup the component
  • use the new commands (zoned cleaning and goto)
  • figure out the coordinates for your map / floor layout
  • use a script/switch to start your vacuum for specific rooms
  • use Google Home + IFTTT to start cleaning any room you wish

Update your v1 to the latest firmware to enable new functions
DISCLAIMER: Updating your firmware results in the reset of your token

To update your firmware on your v1, you have to make sure that your region is set to Mainland China in your Mi Home App. Please also make sure you run a recent Mi Hime App version (5.x).


Go to Profile → Settings → Region to select it.


Don't worry if your vacuum does not show up anymore. You have to readd it now. You might have to restart the paring process on the robot by long-pressing on the power and home button at the same time. Once its synced again with your Mi Home app, you can install the firmware update:

Click on the robot → Open the settings (top right corner, three dots) → General settings → check for firmware updates


extract your token and setup component

Setup component

Please also refer to the manual.

configuration.yaml:

vacuum:
  - platform: xiaomi_miio
    host: VACUUM_IP_ADRESSE
    token: YOUR_TOKEN
    name: DustyMcDustface

Extract token

Android:
Download a modified Mi Home app from this russian website. (Direct Link v.5.1.29)
You need to readd the robot to the app. Restart the pairing process on the robot by long-pressing on the power and home button at the same time (v1) or by long-pressing the power button (v2).
Once it’s added in the app again, you can find the token in the Networks info of your robot:



Click on the robot → Open the settings (top right corner, three dots) → General settings → Network info

iOS:
I have no faster way of retrieving the token. Please refer to the component documentation to extract the token.

how the new commands work

The new commands that we can now use are called app_goto_target and app_zoned_clean. Both commands take coordinates and we have to call them via the “vacuum.send_command” service.

app_goto_target
Takes one coordinate: [x,y]

Example:

{
  "entity_id": "vacuum.DustyMcDustface",
  "command": "app_goto_target",
  "params": [25000, 25000]
}

app_zoned_clean
Takes a list of zones. A zone contains two coordinates (button left, top right) and a number indicating how often the zones should be cleaned: [[x1, y1, x2, y2, i], [x1, y1 , x2, y2, i], ...]

Example:

{
  "entity_id": "vacuum.DustyMcDustface",
  "command": "app_zoned_clean",
  "params": [[25000, 25000, 23000, 23000, 3]]
}

Update: Since Version 103 there has been an update to the service call:

Instead of vacuum.XX you have to use xiaomi_miio.XX. Keep this change in mind for the further instructions.

In addition, there has been added a command for the cleaning zones:
xiaomi_miio.vacuum_clean_zone
The service call is used with the additional keys entity_id, zone and repeats. E.g.:

service: xiaomi_miio.vacuum_clean_zone
      data_template:
        entity_id: vacuum.xiaomi_vacuum
        repeats: 1
        zone: [[30914,26007,35514,28807], [20232,22496,26032,26496]]
map and coordinates

Unfortunately there is no easy way without rooting the device to directly access the map with its coordinates, so you have to do some manual labor. The way the map is created works like this: The starting point of the map (which should be right in front of the dockings station - where your robot starts off at) is [25500,25500] and the map is then build around this coordinates. All you have to do is figure out a grid and then read off the coordinates that you need:
Step 1: Make sure your docking station is at a fixed position (so your starting point will ALWAYS be the same).
Step 2: If not yet created, let your robot create a full map of your apartment/flat by starting the cleaning from the Mi Home App.
Step 3: Use the share button on the top right while accessing the map on the app and share the map to facebook (you can set it to private so that only you can see the post). Then, download the map to your PC.
Step 4: Use the app_goto_target command to send your robot to a new location. coord Increasing the x coordinate will move the robot relative to the starting point to the right (decreasing to the left), increasing the y coordinate will move the robot relative to the starting point to the top (decreasing to the bottom)
Figure out a few points that your robot can reach (preferably a few that aren’t to close to the starting point). Then once you have reached those points, extract the map again and of course write down the coordinates of your robots location.
Step 5: Now you can either work with Photoshop or any other desired editing software, or you can go old-school and print the maps. Now calculate the distance between two of the coordinates by calculating the difference (e.g. if you have the coordinate [25500, 25500] and [20000, 20000], the distance would be 5500 on the x-axis and 5500 on the y-axis). I then chose steps of 500 for my coordinate grid. You then have to take measure and figure out the actual distance between the two points on your map (cm / pixels) and divide that number by the number of steps that you need (in our example 5500:500 = 11). Do that for both axis and continue the grid for the entire map, add some values for reference and you should end up with something like this (depending on how much effort you put into it ;)):


Step 6: If you have done everything correctly, you should now be able to read off your coordinates. For most parts you don’t have to be exact: The robot will not get stuck if your zone is bigger than the actual room or parts of your zone are outside the building. If you need a more precise zone, (e.g. if you want to exclude a carpet in a certain setup), you can use the app_goto_target command again with smaller steps to find the exact coordinates that you need in that area.

Update: You can use the app VloleVac as an alternative to the Xiaomi Home App - here you can directly extract the coordinates of a zone that you have drawn. Beware, for some users the app does not work.

script/switch to clean certain areas

On your map, read off the coordinates that you need to define the zone/room you want to clean. You can also use multiple zones. A zone takes two coordinates, the first one is the bottom left corner, the other one the top right corner.

For every room/area that you want to use, you have to create a separate script that contains those coordinates. This is the easiest way, since we cannot use lists (which the coordinates are) in templates. We then can of course use templates to start the according script, e.g. through an input_select or switches for each individual room. This is of course up to you and what you prefer. The script (place this in scripts.yaml that starts the vacuum for a specific room then looks something like this:

vacuum_kitchen:
      alias: "Vacuum the kitchen"
      sequence:
        - service: vacuum.send_command
          data:
            entity_id: vacuum.DustyMcDustface
            command: app_zoned_clean
            params: [[26500, 20500, 29000, 23000, 1]]

Example Configuration with input_select

If you plan on using this for multiple rooms, and might be a little bit tidier if you use an input select for choosing a room from a list and then simply pressing a button to start the cleaning, e.g.:

vacuum_select

Similarily to using this with IFTTT, we have to run another script that reads the input and then calls the respective script that has the coordinates for cleaning the desired room. First, we are going to create the input select in the configuration.yaml:

input_select
  vacuum_room_select:
    name: Choose a room to clean
    options:
      - Kitchen
      - Living room
      - more rooms

Then we add the script that reads the input and calls the respective script to scripts.yaml

vacuum_room:
    alias: "Start cleaning"
    sequence:
      - service: script.turn_on
        data_template:
          entity_id: >
            {% if is_state("input_select.vacuum_room_select", "Kitchen") %}
              script.vacuum_kitchen
            {% elif is_state("input_select.vacuum_room_select", "Living room") %}
              script.vacuum_living_room
            {% endif %}

Be aware that you must have created scripts for each room that contains the coordinates (as in the example above). Next, we can group the input_select and the script in groups.yaml:

vacuum:
    name: Vacuum a room
    entities:
      - input_select.vacuum_room_select
      - script.vacuum_room
Google Home + IFTTT

Note: Since there is a good integration with Google Assistant and Home Assistant through the Home Assistant Cloud, using IFTTT is not necessary in order to control your vacuum through voice commands. If you still want to set up IFTTT, continue as follows.


Make sure you IFTTT and Home Assistant are setup properly. Please refer the manual if you haven’t done so yet.

The goal here is to tell your Google Assistant to start cleaning a certain room that you have predefined with your voice. We have set up the scripts for each room already. It seems obvious that we could create a webhook and trigger for each of these scripts now, but that seems like a lot of work.
So what we are going to do instead is use a text ingredient that is passed to another script which processes that text ingredient and starts the respective script.

Vacuum room select script

vacuum_room_select:
      sequence:
        - service: script.turn_on
          data_template:
            entity_id: >
              {% if (room== "kitchen") %}
                script.vacuum_kitchen
              {% elif (room== "living room") %}
                script.vacuum_living_room
              {% endif %}

IFTT setup
Step 1: Create a new Google Assistant trigger and select “Say a phrase with text ingredient”
Step 2: Choose your phrases to start your vacuum, make sure that you put a “$” where you would like to say the room name, e.g. “clean the $”
Step 3: Choose webhook as the action. Set it up as follows

URL: https://xxx.duckdns.org:8123/api/services/script/vacuum_room_select?api_password=xxxxx
Method: POST
Content Type: application/json
Body: {“room”: “{{TextField}}”}

That’s it. You are good to go.

Troubleshooting
I sometimes had troubles with the text ingredient. Especially when you use two words like “living room”, it sometimes only would take “room”. If you are having troubles, you can always add more words to the condition in the script, e.g.

vacuum_select_script:
      sequence:
        - service: script.turn_on
          data_template:
            entity_id: >
              {% if (room== "kitchen") %}
                script.vacuum_kitchen
              {% elif (room== "living room" or "room") %}
                script.vacuum_living_room
              {% endif %}

Also be aware that this method is case sensitive. So, if for example you are speaking German to your Google Assistant, it might process “Küche” sometimes as “küche” or “Küche”

If you have suggestions/changes or ideas you would like to add, please let me know.

45 Likes

Hi,

i would love to have this option to say exactly what room should be cleaned.

From what i understood so far is, that i work with x and y coordinates, and the start-point is always the 2500x and 2500y or something like this.

And then have a room as a kind of a switch, so i can tell Alexa to clean the bathroom.

Will this be the kind of stuff which will be covered here?

Regards
Crey

Im interested too in this

I really rushed this now, I hope there aren’t too many mistakes :wink:

Roughly, how far away were the points you used for the calibration process? Just looking at your map it looks like 1000 xiaomi steps is ~ 1000mm / 1m

I actually haven’t looked into that, but it seems about right. Could also be a bit less, it’s for sure not more.

EDIT: Just tested it, it seems to be a bit less than 50cm when you just send him 500 units - but I think that could be due to inaccuracy. for the last couple of centimeters.

1 Like

AWESOME !
I will have a look in this, this coming weekend, but on first view it looks brilliant, thanks for sharing.

Will give feedback asap.

Regards
Crey

I can’t get this to work. I’ve put the lines above in the automations.yaml file and it’s always and invalid configuration.

Will this necessary change be included in the normal release?

@Matt_TheGeologist: The above script is a script, not an automation. Put the lines into the scripts.yaml and it should work. I have added another example for a configuration to use an input_select and a group to create something like this:
vacuum_select

@Ener-G: What do you mean? Changes to HA? There was just a bug in the last version of HA, it’s currently fixed in beta and should hit stable tomorrow. The vacuum component already exists and the new commands are sent using the raw data, so the vacuum willl understand them right away. No changes needed at the vacuum component.

You guys are legends!!! Just upgraded to Hassio 0.68.0 and the JSON commands work flawlessly.

Given this works as a JSON request I’m going to make the calls directly in IFTTT and use the maker channel to send the request to HASS. No YAML changes needed!

First off, thanks for the excellent and detailed instructions.

I have a question about the map, it seems the robot re-scan/re-create map every time I start the cleaning from dock and it is not always aligned ‘correctly’. The coordinates I found for an area does not work if the current map changes, am I missing something?
Is there a way to save and always use a created map?

I too had the problem at the very beginning of losing my map data quite frequently. It seemed like every time I started the cleaning directly from the robot (pushing the botton on the vacuum), the map was then gone. If I started the cleaning from the app, the map never disappeared. What could help against loosing your map data is not using the normal cleaning function anymore but only the zoned_cleaning (you can create multiple zones and use them in one call, practically covering your entire apartment).

I also now about a bug where the map suddenly rotates 90 degrees. That has to do with how the robot decides which direction/wall is top/left/right/bottom. If the station is in the middle of a room e.g., then he might recognize a different first wall which can result into a rotation if the map. It also seems to help to have the station locateded in a corner to prevent this and for increasing the accuracy. I have mine in a corner, and my map is always exactly the same.

Thank you for getting back to me on this.
The kids and DW will not want or remember only using zoned-clean :slight_smile: and we use the robot at different levels of the house.

Your recommendation about fix dock/starting position is key. I tested if I start my script with vacuum.turn_on for 10-20s, it will redraw enough of the same map (given that dock position) to use my defined zone coordiates consistently.

Hope there’ll be update of the Mi app to store map and zone.

Yeah, unfortunately the robot/map does not support multiple floors. But I think you found a good way to cope with that :slight_smile:

It works,
But my god what a chore to get those coordinates

Anyone found a way to easily get the coordinates of the vacuum at a specific location?

The only other solution I have heard of was to root the robo, add a custom firmware to use dustcloud instead of the xiaomi cloud service, access the map on the robo, retrieve it and then run a script that adds markers onto the map according to the coordinates the robot was send to go to… But I think taking a few screenshots is a little faster in the end :wink:

I don’t know if its only my problem, but I can’t find the part of your guide where you explain how to add the Script and to understand the coordinates of the different zones, the link with the duckdns is not working anymore! :frowning:

There should be everything in there that you need. What exactly are you trying to do? The part with the duckdns is only necessary when you try to setup ifttt.

@ciB when i click on my share button to sharing the map , facebook not show me , only;
mi talk - wechat -moments -weibo

how can to do?