Xiaomi Roborock zone cleanup rule

Hi,

For some reason the FloleVac stopped showing me the map and I couldn’t get zone coordinates. The Mi app do show the map but there is no way that I know how to get the zone coordinates. So following this I wrote a rule for my vacuum. Improvements are more than welcome :slight_smile:

I have a map file for the zones:

kitchen=-5,0.5,3.6,2.6,1
livingroom=0,0.5,4.2,5.2,1
diningroom=-1.6,5.9,2.9,2.7,1

The parameters are:

bottom (y) - meter from the docking point
left (x) - meter from the docking point
w - zone width in meters
h - zone height in meters
repeat - number of times to clean the zone

Note! I’ve chose to use bootom / left / width / height as for me it was simpler to set the coordinates. The vacuum needs bottom / left / top / right.

I defined a zone item:

String Vacuum_Action_Zone "Zone [%s]"

And the rule is:

rule "Vacuum zone cleanup"
when
	Item Vacuum_Action_Zone received command
then
  if (Vacuum_Status_Status.state == "Charging") {
    // Get zone coordinates
    val zone = transform("MAP", "zones.map", receivedCommand.toString)
    // Make sure we have zone parameters
    if (zone != "") {
      // Zone parameters: bottom(y), left(x), width, height, repeats
      var parameters = zone.split(',')
      // Docking point start position
      val double x = 25500.0;
      val double y = 25500.0;
      // Bottom (y) left (x)
      val double b = Double::parseDouble(parameters.get(0)) * 1000.0 + x
      val double l = Double::parseDouble(parameters.get(1)) * 1000.0 + y
      // Top (y) right (x)
      val double t = b + Double::parseDouble(parameters.get(2)) * 1000.0
      val double r = l + Double::parseDouble(parameters.get(3)) * 1000.0
      // Build zone coordinates (and number of times to scan)
      val coordinates = String::format("[[%.0f,%.0f,%.0f,%.0f,%s]]", b, l, t, r, parameters.get(4));
      logInfo(logName, "Clean {} zone coordinates {}", receivedCommand.toString, coordinates)
      Vacuum_Action_Command.sendCommand('app_zoned_clean' + coordinates)
    }
  }
end

Here more information on the map. I am using the zone cleanup editing to get the coordinates.

The main issue with the zone clean - the map rotation - is not handled here and AFAIK there is no solution for that.

4 Likes

Hi,

I have enhanced the rule to support multi zone configuration. In the zone transform file, single zone is defined by numbers, multi zone is a list of single zones, e.g:

entrance=-1.8,0,2,6,1
kitchen=-5,0.5,3.6,2.6,1
livingroom=0,0.5,4.2,5.2,1
diningroom=-1.6,5.9,2.9,2.7,1
groundfloor=entrance,kitchen

The relevant items are:

String Vacuum_Action_Control    "Control"                                   (Vacuum)            { channel="miio:vacuum:04EFCDCA:actions#control" }
String Vacuum_Action_Command    "Command"                                                       { channel="miio:vacuum:04EFCDCA:actions#commands" }

String Vacuum_Control            "Control"                                                      { expire="1s,state=UNDEF" }
String Vacuum_Zone               "Zone [%s]"                   <floor_plan>

And the rule file is:

// Logging name tag
val logName = "Vacuum"

///////////////////////////////////////////////////////////////////////////////
// Function
///////////////////////////////////////////////////////////////////////////////

val Functions$Function1<String, String> getZoneCoordinates =
[zone |
  var parameters = zone.split(',')
  // Docking point start position
  val double x = 25500.0;
  val double y = 25500.0;
  // Bottom (y) left (x)
  val double b = Double::parseDouble(parameters.get(0)) * 1000.0 + x
  val double l = Double::parseDouble(parameters.get(1)) * 1000.0 + y
  // Top (y) right (x)
  val double t = b + Double::parseDouble(parameters.get(2)) * 1000.0
  val double r = l + Double::parseDouble(parameters.get(3)) * 1000.0
  // Build zone coordinates (and number of times to scan)
  val coordinates = String::format("[%.0f,%.0f,%.0f,%.0f,%s]", b, l, t, r, parameters.get(4));
  coordinates
]

///////////////////////////////////////////////////////////////////////////////
// Rule
///////////////////////////////////////////////////////////////////////////////

rule "Vacuum control"
when
  Item Vacuum_Control received command
then
  logInfo(logName, "Vacuum command: {}", receivedCommand.toString)
  if (receivedCommand.toString == "vacuum") {
    // The final command send to the vacuum
    var String command = ""
    // Get zone coordinates
    var String zone = transform("MAP", "zones.map", Vacuum_Zone.state.toString)
    // We still don't know if this is single or multiple zone
    var parameters = zone.split(',')
    try {
      // Single zone only have numbers
      Double::parseDouble(parameters.get(0))
      command = getZoneCoordinates.apply(zone)
    } catch (Throwable t) {
      // This is multi zone
      parameters.forEach[string z|
        zone = transform("MAP", "zones.map", z)
        command = command + getZoneCoordinates.apply(zone) + ","
      ]
      // Remove last ','
      command = command.substring(0, command.length - 1)
    }
    command = String::format("[%s]", command)
    logInfo(logName, "Clean {} zone coordinates {}", receivedCommand.toString, command)
    Vacuum_Action_Command.sendCommand('app_zoned_clean' + command)
  } else {
    Vacuum_Action_Control.sendCommand(receivedCommand.toString)
  }
end

Comments, suggestion, improvements are welocme

2 Likes

Hi Team,

Where does the ‘zones.map’ file sit (path)

@crockernr

The file should be in transform folder. Here is an example of a file:

entrance=-1.8,0,2,6,1
kitchen=-5,0.5,3.6,2.6,1
livingroom=0,0.5,4.2,5.2,1
diningroom=-1.6,5.9,2.9,2.7,1
sofa=1.4,4.8,3,1,1
carpet=1.4,2.1,2,3,1
groundfloor=entrance,kitchen
1 Like

Hey @smhgit This looks great. I’ve setup the files https://github.com/imaginator/system/commit/ec179aea1e4f1d820a4ccc6334ea78a4354e71f4 and am now trying to call this from the openhab-cli.

What’s the best way to be triggering this from the openhab-cli?

openhab> smarthome:send Vacuum_Control ["vacuum", "kitchen"]
or ???

following up to my own idiocy: smarthome:send Vacuum_Action_Zone kitchen works!.

Dont understand how this work - sorry my stupidness could anyone explane me what i must do for the numbers of for example kitchen ?

Cause FloleVac dont work regarding MAP with my 1S. I have a screenshot of the created map from xi home app but dont know how can i measure now the coordinates ?!

thanks for help

I already sent you the link a couple of days ago, it is explained very well on that page how to do it:

I did it in a more try and error way:

Just open the app and show the map in zones mode
As soon as you activate one zone over openhab, the lines are shown in the map.
If the zone is not at the position you want it, then stop vacuum, modify the map and start vacuum again.
Normally I need not more then 3-5 corrections until the zone fits…

Nice step, did not know this is possible. :+1:
I will verify my coordinates tomorrow.

If you are using the app FloleVac, you could get the original coordinates of a zone to clean. You dont have to “guess” and try and error, but got the direct coordinates, which are send to the vacuum.

1 Like

According to the reports of several users, the app does not work anymore for newer vacuum models.

Hi,

thanks for this nice tutorial, but i’ve a missing link :slight_smile:

I want to use the solution from @smhgit with multi zone configuration. I’ve used his map file (for testing), the items and the rule.

But i don’t get, how to start a zone cleaning with Basic UI. If i include the items in my sitemap as “Default” i get this result:

Bildschirmfoto von 2019-12-23 12-10-41

I tried to use the “control” item as switch with mappings, but also no success:

Bildschirmfoto von 2019-12-23 12-13-19

This is, what i get in the logfile:

2019-12-23 12:00:49.638 [INFO ] [internal.handler.MiIoAbstractHandler] - Mi Device model rockrobo.vacuum.v1 identified as: Mi Robot Vacuum (rockrobo.vacuum.v1). Matches thingtype miio:vacuum
2019-12-23 12:01:58.059 [ome.event.ItemCommandEvent] - Item 'Vacuum_Control' received command entrance
2019-12-23 12:01:58.064 [vent.ItemStateChangedEvent] - Vacuum_Control changed from NULL to entrance
2019-12-23 12:02:00.862 [ome.event.ItemCommandEvent] - Item 'Vacuum_Control' received command kitchen
2019-12-23 12:02:00.869 [vent.ItemStateChangedEvent] - Vacuum_Control changed from entrance to kitchen

But no action on the vacuum…

Any hints for me?

Thanks.
Huaba

EDIT: i’ve an warning in the log:

[WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'staubsauger.rules' has errors, therefore ignoring it: [21,1]: missing EOF at 'val'

I think, thats the error…

I’ve solved the error. I had additional rules in the file and the function must place before :man_facepalming:

But no success with the zone cleaning. Errors are:

2019-12-23 12:59:55.030 [ome.event.ItemCommandEvent] - Item 'Vacuum_Control' received command kitchen
2019-12-23 12:59:55.031 [INFO ] [clipse.smarthome.model.script.Vacuum] - Vacuum command: kitchen
2019-12-23 12:59:55.037 [vent.ItemStateChangedEvent] - Vacuum_Control changed from livingroom to kitchen
2019-12-23 12:59:55.078 [INFO ] [o.internal.handler.MiIoVacuumHandler] - Command kitchen not recognised