Xiaomi Roborock – control via socket API

Why this guide?

My need was to control the robot asking simple commands through Google Home and Alexa like: “Alexa, clean the bathroom“.

With my robot, this was not possible. With the app, you can configure the zones but you can’t simply ask for cleaning only one zone, two times, for instance, all in automatic.

CHALLENGE ACCEPTED!


The 5 identified zones. (Kitchen, bedrooms, bathrooms)

Tools needed

Basically, no particular tools are needed but if you’re not very familiar with networks, you can install some helpers:

Installation of “mirobo” on kali (original guide):

root@kali:~/roborock# apt-get install libffi-dev libssl-dev
root@kali:~/roborock# pip3 install python-miio

Discover your device IP address on network:

Using the “mirobo discover” command you can get the IP address of your robot and the token… that is encrypted and of course not valid.

root@kali:~/roborock# mirobo discover --handshake 1
INFO:miio.device:Sending discovery to with timeout of 5s..
INFO:miio.device: IP 192.168.1.180 (ID: 08058dk6) - token: b'ffffffffffffffffffffffffffffffff'
INFO:miio.device:Discovery done
root@kali:~/roborock#

Discover your device authentication TOKEN, mandatory!

The token can be grabbed through your mobile app (for both iOS and Android):

Android:

You need the Android developer tools installed, and next, with your device connected, use:

root@kali:~/roborock# adb backup -noapk com.xiaomi.smarthome -f backup.dat 

Your backup is done and using mirobo you can extract the decoded token:

root@kali:~/roborock# miio-extract-tokens backup.dat 
Opened backup/backup.dat
Extracting to /tmp/tmpasggarr
Reading tokens from Android DB
Mi Robot Vacuum
Model: rockrobo.vacuum.v2
IP address: 192.168.1.180
Token: THE-AUTH-tokEN-XXXXXX
MAC: 11:22:33:XX:XX:XX
root@kali:~/roborock#

iOS:

For iOS the solution is similar, but you need to create a full backup of your iPhone.

Connect your device, open Finder, select your device and start a new “not-encrypted” backup.

Remember to select “NOT ENCRYPT
Backup is working…

When your backup is complete, you can browse your backup data to find the Roborock app IPA or use a simple tool called iBackup Viewer to read your backup in UI mode:

Go in the folder tree, search for com.xiaomi.mihome and next filter for _mihome.sqlite that is your database. Export the file and open it using your favorite sqlite editor.

In the ZDEVICE table, you can find your big token. Copy it and paste it to the following script, that converts this token in a 32 bit Roborock encrypted.

root@kali:~/roborock# echo '0: fdcXXXXXXX-BIG-TOKEN-HEREeOC' | xxd -r -p | openssl enc -d -aes-128-ecb -nopad -nosalt -K 00000000000000000000000000000000

12345678901abcdefghyilm531754959 <- your TOKEN!

root@kali:~/roborock#

The control center

I’ve done a fork of a github project, a library for sending commands to your robot. In this fork, there is also the go-to-room function that I need.

Take a look and improve if you need: https://github.com/elpsk/miio.

Example project:

A getting started project can be founded on github (https://github.com/elpsk/Roborock-Controller).

You can simply clone it and run locally on your desktop:

root@kali:~/roborock# git clone https://github.com/elpsk/Roborock-Controller .
root@kali:~/roborock# npm install
root@kali:~/roborock# node index.js

Output for demo project:

Connected to MiioDevice {
model=roborock.vacuum.s5,
types=miio:vacuum, miio, vaccuum,
capabilities=adjustable-fan-speed, fan-speed, spot-cleaning, autonomous-cleaning, cleaning-state, error-state, charging-state, battery-level, state
}
[…]
{
fanSpeed: 60,
cleanArea: 48.4475,
cleanTime: 2459,
in_cleaning: 0,
filterWorkTime: 15617,
sensorDirtyTime: 15507
}
[…]

Available extra socket commands can be founded here:

https://github.com/elpsk/XiaomiRobotVacuumProtocol


Map zone selector

The map is an image large 52000 x 52000.

Your robot is not rooted so you need to play a little bit with the coordinates to find the exact rectangles around your rooms.

In the demo project you can find two simple methods:

  1. goToTarget
  2. startCleanZones

goToTarget(x, y)

The goToTarget function accepts two parameters, x and y positions. It sends the robot to the desired position in your house.

device.goToTarget( 25000, 25000)
.then()
.catch( err => {
console.log( err )
})

startCleanZones(zones)

The startClearZones function accepts one parameter, an array of zones. It asks the robot to clean the desired area.

Every zone is a model defined as:

[26234, 26042, 27284, 26642, 1]

Where first 4 positions are the bounds of the map and
latest one is the number of clean repetitions needed.

The coordinate order is
[bottom-left-x, bottom-left-y, top-right-x, top-right-y]

Example:

const zones = [
[26234, 26042, 27284, 26642, 1], // zone A, clear once
[26232, 25304, 27282, 25804, 2], // zone B, clear twice
[26246, 24189, 27296, 25139, 3] // zone C, clear 3 times
]

device.startCleanZones( [zones] )
.then()
.catch( err => {
console.log( err )
})

The robot now cleans the 3 zones passed for the repetitions you want.


Using the combination of these two functions, you are able to script your robot and clean your desired area only.


Alexa/Google/Siri, clean the kitchen!

For using your favourite home assistant and send a command like my original one “Alexa clean the kitchen” or “Hey Google, clean the bathroom” or “Siri, clean the bedroom“, you need to work a little bit but it is quite simple to implement by yourself.

Here some useful links:


What’s next?

A graphical tool that extracts the coordinates directly from your map.

If you’ve already done something similar, please let me know.


Update 😭

While writing this post, the Xiaomi releases a new app update with the following features:

This means that the selective room cleaning is now native!

So, all of my work is now useless, but I’ve learned a lot from doing this. No time wasted when you learn!

Enjoy cleaning!

 

Alberto Pasca

Software engineer @ Pirelli & C. S.p.A. with a strong passion for mobile  development, security, and connected things.