Xiaomi roborock room clean (multi level map)

Hi,
I am new at openHAB and I try to control my roborock s5 MAX with the xiaomi plugin.

I have a raspberry pi with openHAB 2.5.10

What I have done:

  • Changed app from roborock to xiaomi home
  • find out my token and set it up in the thing from roborock
  • reading the parameters and sending some parameters to thr roborock works.

Now I try to send a command to clean one or more rooms via openHAB and I have no idea what to do and I don’t find an example?! Maybe I am to stupid to find it.

I have Items:

String actionVacuumRoom "Raum" {channel="miio:vacuum:132E5B51:actions#segment"}
String actionCommand  "Vacuum Command" {channel="miio:vacuum:132E5B51:actions#commands" }

and I have a sitemap:

//------- Staubsauger
Text label="Staubsauger" icon="staubsauger" {
  Switch item=VacuumVirtual
  Text item=actionCommand
}

and I have a rule:

sendCommand(actionVacuumRoom,"16")

when I send this from a rule, the roborock start turning around in the docking station (docking station moves) and then roborock moves forword, stopps and moves back to docking station.

I have a multi level card so I have tested the command:

actionCommand.sendCommand("get_room_mapping")

and I received in my sitemap at actionCommand this:

{"result":[[16,"987001017278"],[17,"987001017275"],[18,"987001017279"],[19,"987001017277"],[20,"987001017276"]],"id":4397}

I have 5 rooms on level 1, so I changed the level in the app to the second level and started aagin get_room_mapping. I received this:

{"result":[[16,"987001017291"],[17,"987001017290"],[18,"987001017292"],[19,"987001017289"]],"id":4472}

I think this are the 4 rooms on level 2. I checked it with level 3(one room) and I received this:

{"result":[[16,"987001017293"]],"id":4487}

Then I startet to clean in level 1 one room and checked the log:

2020-11-23 18:10:12.030 [vent.ItemStateChangedEvent] - miio_vacuum_132E5B51_status_clean_area changed from 13.3475 to 0.0
2020-11-23 18:10:12.041 [vent.ItemStateChangedEvent] - statusArea changed from 13.3475 to 0.0
2020-11-23 18:10:12.048 [vent.ItemStateChangedEvent] - statusTime changed from 12 to 0
2020-11-23 18:10:12.063 [vent.ItemStateChangedEvent] - miio_vacuum_132E5B51_status_clean_time changed from 12 to 0
2020-11-23 18:10:12.084 [vent.ItemStateChangedEvent] - statusClean changed from 0 to 3
2020-11-23 18:10:12.089 [vent.ItemStateChangedEvent] - miio_vacuum_132E5B51_status_state changed from Charging to Room Clean
2020-11-23 18:10:12.094 [vent.ItemStateChangedEvent] - miio_vacuum_132E5B51_status_state_id changed from 8 to 18
2020-11-23 18:10:12.100 [vent.ItemStateChangedEvent] - actionControl changed from dock to vacuum
2020-11-23 18:10:12.104 [vent.ItemStateChangedEvent] - miio_vacuum_132E5B51_actions_control changed from dock to vacuum
2020-11-23 18:10:12.110 [vent.ItemStateChangedEvent] - actionVacuumOnOff changed from OFF to ON

Now I think I have to send a couple of commands to clean one ore more rooms.

I found thid command:

{
    "method": "app_segment_clean",
    "params": [16, 17, 18],
    "id": 6764
}

But I have no idea how to use this in openHAB.
I hope I gave you all the informations you need and I hope somebody can help me.

if you want to send that withOH, send it to the command channel like this: app_segment_clean [16, 17, 18]

so in your case actionCommand.sendCommand("app_segment_clean [16, 17, 18]")`

1 Like

Hi Marcel,
I have tested it an it works! Thanks a lot.
But I have to set up the map with my Xiaomi App and then i can send this command.
How can I set the map?

EDIT:
I can see the change of the map in the log.

miio_vacuum_132E5B51_cleaning_map changed from raw type (image/jpeg): 27962 bytes to raw type (image/jpeg): 28147 bytes
2020-11-24 15:48:51.534 [vent.ItemStateChangedEvent] - map changed from raw type (image/jpeg): 27962 bytes to raw type (image/jpeg): 28147 bytes

If I don’t change the map to the right level in the xiaomi app the cleaning stops:

2020-11-24 14:41:21.642 [ome.event.ItemCommandEvent] - Item 'actionCommand' received command app_segment_clean [17]
2020-11-24 14:41:21.688 [nt.ItemStatePredictedEvent] - actionCommand predicted to become app_segment_clean [17]
2020-11-24 14:41:21.712 [vent.ItemStateChangedEvent] - actionCommand changed from {"result":["ok"],"id":4163} to app_segment_clean [17]
2020-11-24 14:41:21.843 [vent.ItemStateChangedEvent] - actionCommand changed from app_segment_clean [17] to {"result":["ok"],"id":5312}
2020-11-24 14:41:48.151 [vent.ItemStateChangedEvent] - historyCount changed from 173 to 174
2020-11-24 14:41:48.167 [vent.ItemStateChangedEvent] - miio_vacuum_132E5B51_history_total_clean_count changed from 173 to 174
2020-11-24 14:41:48.315 [vent.ItemStateChangedEvent] - miio_vacuum_132E5B51_cleaning_last_clean_start_time changed from 2020-11-24T12:57:32.000+0100 to 2020-11-24T14:41:21.000+0100
2020-11-24 14:41:48.333 [vent.ItemStateChangedEvent] - lastStart changed from 2020-11-24T12:57:32.000+0100 to 2020-11-24T14:41:21.000+0100
2020-11-24 14:41:48.342 [vent.ItemStateChangedEvent] - lastEnd changed from 2020-11-24T12:58:04.000+0100 to 2020-11-24T14:41:37.000+0100

When I look into the Xiaomi App I can see “Positionierung fehlgeschlagen” so positioning didn’t work?!

Is there a way to send the correct map to the roborock s5 max?
Has someone the same problem? I couldn’t find the problem and no solution.
I hope someone can help me.
I have tested a lot and read a lot but I have no idea.

Hello gents, i am trying to use a rule to clean a predefined room in rules, but I just seem to end up with the robot saying starting room cleaning, driving off the dock for 5 sec, then saying room cleaning finished going back to the dock

    ActionsSegment.sendCommand("Room [1]")

I dont know if this room clean command is relativly new, so cant find any examples on how to formulate myself

Vacuum Room [room#]
String miio:vacuum:13339B7C:actions#segment

the rooms start with id 16 and go untill 31 or something like that. I have 16,17,18,19,20.
To clean one room you have to send in your case

ActionsSegment.sendCommand("app_segment_clean [16]")

I found out just as you replied :slight_smile:

In app the rooms ar numbered 1,2,3,4 etc
but in the binding they are
15:37:57.991 [DEBUG] [binding.miio.internal.robot.RRMapDraw] - Identified rooms in map: 16 17 18 19 20 21 22 23
16 is then room 1 and so on ( i had to test 16 was room 3 and 17 was room 1)

great.

I have still the problem with different maps for differnt floors.

I have an s5 and a s6 maxv so i dont need to mix maps.

Wondering if you have ever figured out how to change floor maps in OH?

Unfortunately I did not find out. I would be happy if there was a solution.

Hi Georg,

I have a work around that I’ve been using. I have an S4Max, not sure if other robots can do this or not but here is what I do:

  • I created two maps, one for each floor of my house.
  • When I move my robot form one floor to the next, I put it on the floor (not the dock) and hit the dock button. It attempts to return to the dock. Usually it says “invalid map” and returns to the dock. Next I hit the clean button, it comes off of the dock and says “positioning”. It will drive a round for a minute but eventually it figured out which map is the correct one for the floor it is on and says “position established”. I then hit the home button again and it goes to the dock knowing what floor it is on.

Using the get_floor_mappings command I was able to determine the rooms and their IDs for each floor.
You can see each room number has a distinct ID even when the number is repeated between floors:

//Second Floor Map
//{"id":8830,"result":[[16,"536001005515"],[17,"536001005513"],[18,"536001005511"],[20,"536001005519"],[21,"536001005517"]],"exe_time":100}

//First Floor Map
//{"id":12270,"result":[[16,"536001005545"],[17,"536001005547"],[18,"536001005549"]],"exe_time":100}

I have a set of rules to determine what floor it is on. The Test Rooms rule is run actually by another rule anytime the statue changed to charging - which happens whenever the vac returns to the dock.

rule "Test Roborock Rooms"
	when
		Item testroborooms received command
	then
		logInfo("test robo rooms", "!!!!!!!!!!!!!!!!!!!!!! testing rooms")
		actionCommand.sendCommand("get_room_mapping")
	end

rule "What Floor"
	when
		Item actionCommand received update
	then
		//When a floor map is received parse it and set to the approproate floor or warn of unknown floor
		//2nd floor - actionCommand changed to {"id":8830,"result":[[16,"536001005515"],[17,"536001005513"],[18,"536001005511"],[20,"536001005519"],[21,"536001005517"]],"exe_time":100}
		//1st floor - actionCommand changed to {"id":3010,"result":[[16,"536001005545"],[17,"536001005547"],[18,"536001005549"]]
		logInfo("Clean Room", "!!!!!!!!!!!!!!!!!!!!!! Floor Check")
		val firstRoomNumber = transform("JSONPATH", "$.result[0][0]", actionCommand.state.toString)
		if (firstRoomNumber == "16"){
			logInfo("Clean Room", "!!!!!!!!!!!!!!!!!!!!!! First Room = 16")
			val room16ID = transform("JSONPATH", "$.result[0][1]", actionCommand.state.toString)
			if (room16ID == "536001005515") {
				mapFloor.sendCommand(2)
				logInfo("Clean Room", "!!!!!!!!!!!!!!!!!!!!!! First Room ID = 536001005515 - We're on the 2nd floor")
			} else if (room16ID == "536001005545") {
				mapFloor.sendCommand(1)
				logInfo("Clean Room", "!!!!!!!!!!!!!!!!!!!!!! First Room ID = 536001005545 - We're on the 1st floor")
			} else {
				logInfo("Clean Room", "!!!!!!!!!!!!!!!!!!!!!! First Room ID = " + room16ID + " There is no floor with room 16 that matches this room ID.  Look s liek you've changed your mapping")
			}
		}
	end

So - essentially I let the vacuum determine for itself what floro it is on and load the correct map on its own. I then determine what floor it is on by parsing the room mapping IDs. This isn’t really needed, but I use it to set visibilities on my site map for things that are floor specific:

For example, I have single room cleaning set up for each room, and only have the correct set of rooms displayed for the floor the vac is on. I also have a spot cleaning set up that is only on the first floor. Also, I have a go to point set up for the var to meet me by the garbage on the first floor so I can easily empty the dust bin. So I only show that on my sitemap when the vac is on the first floor:

            Selection item=cleanRoom	mappings=[0="Select Room to Clean", 18="Bub Room", 20="Computer Room", 21="Hallway", 16="Master Bedroom", 17="Upstairs Bathroom"]	visibility=[mapFloor==2]
			Selection item=cleanRoom	mappings=[0="Select Room to Clean", 16="Kitchen", 17="Dining Room", 18="Living Room"]	visibility=[mapFloor==1]
			Switch item=cleanLVCarpet	mappings=[ON="Clean"]	visibility=[mapFloor==1]
			Switch item=meetbyTrash 	mappings=[ON="Go"]	visibility=[mapFloor==1]
1 Like

Hi Tom,
sorry for the late response and thank you very much for this solution. I think this will work for me. I will test it.

1 Like

BTW, I found that it is also possible to see when the robot is “positioning” and "Position established. I put in an issue and in like 1 day the binding author added this as a channel. Looks like it will be included in OH3.1 release (Unfortunately for me as I’m running 2.5.x for some time still) but this will make it possible to make a better rule in terms of when to parse your room map for what floor it is on. In my example I did above I waited unit it returned to the dock, but parsing the room map after position established will be better.

Thank you for the information. I’m thinking about testing version 3 soon. But a lot to do at the moment.

Hi,

thank you for the proposal of the enhancement. This is great.

BR
PeterK

Hi,

Perhaps we should combine the rules. I used the approach mentioned here in order to control room and also zone cleaning with multiple maps…

I will test “version 2 (including zones)” in the next 1-2 days.
BR PeterK

I guess I’m not really sure what the difference in these two approaches is. At the core of both is checking the room mapping for a known room ID to determine which floor map the robot is using. Can you summarize the difference in these two?

Hi,

precisely… the “find the current floor”- part is taken from this thread (linked here). I just made it easier to configure using a map-file for the room16ID and I don’t need access to the robot (hitting the button). Mostly the robot will start from the dock.

The complete set of my rules is around this part.
You have a switch “clean kitchen”. If you use this, the rule will

  • check on which floor the robot is (using this approach here)
    but then also
  • check on which floor the “to be cleaned” room is
  • get the correct ID of the room from a map-file and send the robot to this room

Next version will also be able to clean a specific zone defined in a map-file.

I did not use this “find the current floor” 1:1 as does not fit perfectly. I now think this might be a bad Idea on the long run. You are still working to improve the rule (and even the binding) and I will have to always integrate my changes.

I would be happy to just combine the rules for “finding the floor” and then use your rule 1:1 just concentrating on the “surroundings”.

BR
PeterK

Hi,

this might be interesting for you too. It is a different approach, but still using your basic Idea :wink:

BR
Peter