Howto: Xiaomi vacuum zoned cleaning

Interesting, I don’t get these options, just facebook and LINE. I might have an idea why I have different options here. Since I have the v2 vacuum (roborock), I did not change my region to Mainland China - it’s still set to europe.

Either you have to use oneof the other services, do a screenshot on your device of the map (and then send this via email or so to your pc), or once you have updated the firmware (if you use a v1), change the region back to Europe/US.

Hi ciB,

I love your work, it is great! I have added all of my rooms in and can now control it via Google Home, thanks!

Just thought I would share my way of getting the coordinates. There still is some trial and error but it is much quicker to make the change and see the result on the map instantly.

First I estimate how many metres away one corner of the zone is in both the x and y directions and multiply that by 1000. I add/subtract that from the 25500/25500 starting value.
Do that again for the opposite corner of the zone.
eg. the top left of a 3x3m zone, located 5 metres to the left (x), and 8 metres forward (y) would make it 20500,33500,17500,30500

Next I open up the mi home app and open up the vacuum so I can see the map.

I then bring up the Service Calls section in HA and use those values with the app_zoned_clean command.

{
  "entity_id": "vacuum.SuckBot2K",
  "command": "app_zoned_clean",
  "params": [[20500,33500,17500,30500,1]]
}

Now look at the mi home app and you can see the estimated path and also the zone overlayed onto the house map. Pause the vacuum and see what figures need adjusting (location/size).
Cancel the vacuum through mi app, then try the new adjusted figures in Service Calls.

Sorry if this is doesn’t make sense, I have had a few late nights playing around with all the awesome things HA can do!

ps. I have the Roborock v2 and am attached to the chinese server if that makes a difference anywhere.

Cheers!

7 Likes

Also, the scripts you made connect perfectly with Google Home via the Google Assistant plugin if you want to bypass IFTTT. You do lose the ability to reply with custom responses though.

Nice work, thanks again mate!

Hey @rohan thanks for a different way of gettingthe coordinates.

Quick question does the roborock v2 has zoning in built the app? Can I say clean my kitchen like the way @ciB has implemented it on HA?

The Mi Home App does not support predefined zones. You can draw a zone (or multiple zones) on the map and then start the cleaning process, but you cannot save them, nor does it display which coordinates you have chosen. All you can do is drag a box where your kitchen is on the map and start the cleaning.

Right I see!

Apologies for all the questions as I am fairly new with the Xiaomi vacuum. I have just ordered the roborock v2 and it’s on its way to me.

Have you got any tips for setting it up or things which I should avoid whilst setting it up?

I will definitely try your zoning method and getting HA to clean a specific room of choice.

Thanks.

Don’t move the station/robot around since that will mess up your map. It seems to work best if you have it sitting in a corner, so if the map gets corrupted, it always starts the new map exactly like the old one :slight_smile:

So I move it once I have set up your method and clean individuals zones like you described?

If you move the robot (not the station), e.g. by carrying it around, it will still think that it’s at its old position when you turn it on. This can be “fixed” though by letting the robot build a new map from the station (by starting a new cleaning task from the station). But if you move the station, the starting point of the map (which is in front of the station) will still be [25500,25500], but is then a different location on your map - then you would have to go through the entire process again, yes. The zones might just be shifted according on how much you moved the station, but it’ll be a hassle anyway ;). So better decide where to set up the station before getting all the coordinates :wink:

1 Like

@Cib it was really good if you made a video , how we can draw a map and all the process. what do you think about that?

I measured in my home and mm seems right.

I.e. 1 “Xiaomi Unit” == 1 mm.

Use the “app_goto_target” command and see where the point is in the Xiaomi app. I.e. no need to wait for the vacuum to actually get there.

The same works for zones, test sending a zone via HA and see what it looks like in the app. Then modify accordingly.

1 Like

Hi @ciB, great post.
I have a doubt: You mention you have your v2 vacuum registered on europe server. I’ve tried a time ago, but it was not possible for me. Registering on china mainland worked. Do you know if it’s a new feature, or did you do some trick to register it?
Thanks!

My app is set to Europe, and if I press the “+” in the top right it shows me a list 9 items that are sold in europe, including the “Roborock Vacuum” which is the v2. No other vacuum is listed, for that you would have to switch to Mainland China.

It does not really matter though which region you have set it to, so if Europe does not work for you just use China instead.

Ok, I will give it a try. The main issue I see when working with MiHome app are the delays. It’s very slow to get information from the vacuum (status, map, etc.). An I often get timeouts messages. So that’s the reason I want to try on Europe’s server

Great write up! Thank you ciB!

I found a cool thing that you can do when you can send it to a predetermined spot. I was trying to make the vacuum cross a threshold it was struggling with. I then noticed that if you go backwards using the command velocity (-x) it helps a lot. So, if you go to the spot where the threshold is, make a 180 degree turn by:

  - service: vacuum.xiaomi_remote_control_move_step
    data:
      entity_id: vacuum.dammsugare
      velocity: "0"
      rotation: "115"

…then back up using:

sequence:
  - service: vacuum.xiaomi_remote_control_move_step
    data:
      entity_id: vacuum.dammsugare
      velocity: "-0.29"
      duration: "6000"

It can now get places it couldn’t before.

Now, I only need to string all the steps together. Can you make a script wait for a previous step to have completed? That is, not just a time delay, but when the vacuum is actually finished with the last step?

1 Like

Yes, that should be possible. The robot has a status depending on what it is doing right now. E.g, if you send it to a specif spot the status is “going to target”, then, once it reached the target, the new status is “idle”. Once the status updates to idle, you could then send a new command.

So basically if you want the vacuum to clean a room that you need to enter via your trick, you could start the script by sending him to the spot that you need him to go (infront of the ridge) and activate an automation that waits for the status to change to “idle”. Once the robot reaches the spot (status goes to idle), you call a new script through that automation that then starts your sequence for going over the ridge backwards and that also turns off that automation again and turn on another one. The 2nd automation starts the cleaning process in that area when your vacuum is idle again. That automation also turns itself off again. Makes any sense?

Yes. I actually started to implement something very much like that solution, but it fast became very muddy.

Since the action after “idle” (or ‘going back to dock’ after the cleaning) is different every time I have to use an input_number to keep track at what step the vacuum is at. Then the whole jinja if else machinery. It is doable, but it’s very hack-ish and cumbersome.

So I put that on hold and tried to use a python script instead. Given how new I am to python that will take some time. But if I could use something like:

hass.services.call('vacuum', 'send_command', 'entity_id': 'vacuum.dammsugare', 'command':'app_goto_target', 'params':'[23350,23600]')

if N == 100:
    if hass.states.get(vacuum.dammsugare) == 'idle':
        break
    time.sleep(7)
	N = N+1

…instead, then a lot of complications could be avoided. Ideally I would like to just get a callback to the python script but, I don’t know how you do that.
I’m new at this, the code above is probably wrong in more ways than one, but do you think that it could lead somewhere?

I don’t think that it would be that complicated to do with automations (depending on your acutal needs). You can DM me and I can try to tinker a solution for you. Doing it with a python script would work similarily, but keep in mind that you would have to start a loop for checking the condition, since you would never know when to actually call the python script:

while hass.states.get(vacuum.dammsugare) != 'idle':
  do nothing
....

What you could also try is Node-RED, maybe thats easier, but I just started looking into that myself.

1 Like

I didn’t manage to get very far with the python script. I couldn’t even get the test case of:

hass.services.call('vacuum', 'locate', { 'entity_id': 'vacuum.dammsugare' })

For curiosities sake, why does that not work?

I then revisited the original plan and I found the wait command, which I missed the first time. So now it looks something like:

  vaccum_barnrum_go_and_clean_and_go_home:
    alias: "Go to childrens room, clean and then go home"
    sequence:
      # Go to starting point in the kids room
      - service: vacuum.send_command
        data:
          entity_id: vacuum.dammsugare
          command: app_goto_target
          params: [23350,23600]
      #Wait untill done
      - wait_template: "{{ states.vacuum.dammsugare.attributes.status == 'Idle'}}"
      - service: input_number.set_value
        data:
          entity_id: input_number.vaccum_progress
          value: 1
      - delay: '00:00:30'
      #clean room
      - service: vacuum.send_command
        data:
          entity_id: vacuum.dammsugare
          command: app_zoned_clean
          params: [[20613,19502,24163,25002,1]]
      #Wait untill done
      - wait_template: "{{ states.vacuum.dammsugare.attributes.status == 'Returning home'}}"
      - service: input_number.set_value
        data:
          entity_id: input_number.vaccum_progress
          value: 2
      - delay: '00:00:05'
      #Stop going home
      - service: vacuum.stop
        data:
          entity_id: vacuum.dammsugare

…and it goes on. It becomes pretty long when you have to specify each step.

This seems to work well, but It needs a bit more polish. The input_number is just for debugging.

So it seems I got it under control for now, but I do thank you for your kind offer of assistance.

1 Like

TBH, I don’t know why your service call does not work…to my understanding that’s how it should work :face_with_raised_eyebrow: