Xiaomi Vacuum S1/S60/T60/S61/T61 room cleaning by room name

Hello Guys,

with the new Xiaomi S1, and maybe with S6, and S50 also, it is possible to clean one room with the xiaomi app by name. Is it possible to implement this feature in HA ? Or maybe it’s already implemented ?!

At this time you can only clean zones via coordinates, but not by given room names in Xiaomi APP.

The APP looks like this:

Greetz!

I would also love that. I have not setup any room, but I have setup some zones and I want for ex to run the vacuum on all zones and also on specific zones (for ex when the washing part is installed).
I hope you get an answer :slight_smile:

Valetudo will offer this soon

But valetudo doesn’t work on s6/t6 and S1 at this time.

I removed certificate pinning from xiaomi smarthome app and captured data.

There is a lot of data but maybe the following is intressting:

{
	"code": 0,
	"message": "ok",
	"result": {
		"list": [{
			"did": "260XXX",
			"token": "316742527370XXX,
			"longitude": "XXXX",
			"latitude": "XXXX",
			"name": "Mi Robot Vacuum 1S",
			"pid": "0",
			"localip": "192.168.50.15",
			"mac": "50:EC:50:01:XX:XX",
			"ssid": "smartnet",
			"bssid": "AC:84:C6:A1:XX:XX",
			"parent_id": "",
			"parent_model": "",
			"show_mode": 1,
			"model": "roborock.vacuum.m1s",
			"adminFlag": 1,
			"shareFlag": 0,
			"permitLevel": 16,
			"isOnline": true,
			"desc": "Zurück zum Dock...",
			"extra": {
				"isSetPincode": 0,
				"fw_version": "3.4.5_0800",
				"needVerifyCode": 0,
				"isPasswordEncrypt": 0
			},
			"event": {
				"consumable_item_prop_cache": "{\"filter_work_time\":\"61915\",\"main_brush_work_time\":\"61915\",\"sensor_dirty_time\":\"61915\",\"side_brush_work_time\":\"61915\"}",
				"event.back_to_dock": "{\"timestamp\":1561455580,\"value\":[0]}",
				"event.back_to_dock_no_power": "{\"timestamp\":1560703972,\"value\":[0]}",
				"event.bin_full": "{\"timestamp\":1561366361,\"value\":[0]}",
				"event.clean_complete": "{\"timestamp\":1561366182,\"value\":[0]}",
				"event.error_code": "{\"timestamp\":1561455748,\"value\":[0]}",
				"event.low_power_back": "{\"timestamp\":1559745457,\"value\":[0]}",
				"event.power_resume_clean": "{\"timestamp\":1559752937,\"value\":[0]}",
				"event.segment_clean_succ": "{\"timestamp\":1561455493,\"value\":[0]}",
				"event.segment_map_done": "{\"timestamp\":1561366283,\"value\":[0]}",
				"event.status": "{\"timestamp\":1561455748,\"value\":[{\"battery\":86,\"clean_area\":2565000,\"clean_time\":103,\"dnd_enabled\":0,\"error_code\":0,\"fan_power\":102,\"in_cleaning\":0,\"in_fresh_state\":0,\"in_returning\":1,\"lab_status\":1,\"map_present\":1,\"map_status\":3,\"msg_seq\":2489,\"msg_ver\":1,\"state\":6}]}",
				"prop.battery": "86",
				"prop.fan_power": "102",
				"prop.ota_progress": "101",
				"prop.ota_progress_ts": "1559736713",
				"prop.ota_state": "idle",
				"prop.ota_state_ts": "1561425797",
				"prop.scene_check_pre_battery": "86",
				"prop.state": "6"
			},
			"uid": 1685998586,
			"pd_id": 66080,
			"password": "",
			"p2p_id": "",
			"rssi": -47,
			"family_id": 0,
			"reset_flag": 0
		}]
	}
}

The clean_area\":2565000 changes every time if I start an cleaning by room.
So every room has an unique ID.

Can some pls help to implement this ?

After this, I started to check the local connection between xiaomi app and vacuum…
With wireshark and miio i found this:

 ->  192.168.50.65 data= {"id":3111,"method":"get_status"}
 <-  192.168.50.15 data= {"result":[{"msg_ver":1,"msg_seq":3032,"state":8,"battery":100,"clean_time":30,"clean_area":0,"error_code":0,"map_present":1,"in_cleaning":0,"in_returning":0,"in_fresh_state":1,"lab_status":1,"fan_power":102,"dnd_enabled":0,"map_status":3}],"id":3111}
 ->  192.168.50.65 data= {"id":3112,"method":"get_map_v1"}
 <-  192.168.50.15 data= {"result":["ruby2%2F260223565%2F2"],"id":3112}
 ->  192.168.50.65 data= {"id":3113,"method":"app_segment_clean","params":[17]}
 <-  192.168.50.15 data= {"result":["ok"],"id":3113}
 ->  192.168.50.65 data= {"id":3114,"method":"get_status"}
 <-  192.168.50.15 data= {"result":[{"msg_ver":1,"msg_seq":3033,"state":8,"battery":100,"clean_time":30,"clean_area":0,"error_code":0,"map_present":1,"in_cleaning":0,"in_returning":0,"in_fresh_state":1,"lab_status":1,"fan_power":102,"dnd_enabled":0,"map_status":3}],"id":3114}
 ->  192.168.50.65 data= {"id":3115,"method":"get_status"}
 <-  192.168.50.15 data= {"result":[{"msg_ver":1,"msg_seq":3036,"state":18,"battery":100,"clean_time":0,"clean_area":0,"error_code":0,"map_present":1,"in_cleaning":3,"in_returning":0,"in_fresh_state":0,"lab_status":1,"fan_power":102,"dnd_enabled":0,"map_status":3}],"id":3115}
 ->  192.168.50.65 data= {"id":3116,"method":"get_map_v1"}
 ->  192.168.50.65 data= {"id":3116,"method":"get_map_v1"}
 <-  192.168.50.15 data= {"result":["ruby2%2F260223565%2F3"],"id":3116}

The section with {"id":3113,"method":"app_segment_clean","params":[17]} looks really intressting.

Looking deeper now…

Anyone know’s how to use this:

miio protocol call id-or-address app_segment_clean '["17"]'

with the token ?

EDIT: Got it working !
Set the token with:
miio tokens update <roboip> --token YOURTOKENHERE

You can get the room ID by using
miio protocol call <roboip> get_room_mapping

and then start app_segment_clean with:
miio protocol call <roboip> app_segment_clean '[ROOMID]'

EDIT 2: Multiroom cleaning with:
miio protocol call <roboip> app_segment_clean '[17,18]'

1 Like

I did not find how to set room name in the app. Is it the Xiaomi Mi Home app ?

Yes, it is the Xiaomi home app. Which vacuum do you have ?

Roborock s50. Is it linked to a specific version of the app?

Sure, it is. This works only with listet vacuums in the title.

I hope they will deploy the feature for older version like they have done for zone cleaning.

How would you integrate those miio protocol commands into a home assistant automation?

Have a look at the shell_command section from HA.
I can provide some samples tomorrow.

First, install python-miio on your home assistant host.

Then use this to make zoned cleanup work:

input_select:
  zone_cleanup:
      name: Raumreinigung
      options:
        - Wähle...
        - Küche
        - 'Essecke + Küche'                                                          
        - 'Wohnzimmer + Essecke'
        - Wohnbereich
        - Wohnzimmer
        - 'Wohnzimmer + Küche'
        - Essecke
        - Schlafzimmer
        - Badezimmer
        - Flur
        - Kinderzimmer
      initial: Wähle...
shell_command:
  clean_essewohn: "miio protocol call 260223565 app_segment_clean '[20,17]'"
  clean_essewohnkuche: "miio protocol call 260223565 app_segment_clean '[20,17,18]'"
  clean_essekuche: "miio protocol call 260223565 app_segment_clean '[20,18]'"
  clean_wohnkuche: "miio protocol call 260223565 app_segment_clean '[17,18]'"
  clean_esse: "miio protocol call 260223565 app_segment_clean '[20]'"
  clean_schlafzimmer: "miio protocol call 260223565 app_segment_clean '[16]'"
  clean_wohnzimmer: "miio protocol call 260223565 app_segment_clean '[17]'"
  clean_kuche: "miio protocol call 260223565 app_segment_clean '[18]'"
  clean_flur: "miio protocol call 260223565 app_segment_clean '[19]'"
  clean_badezimmer: "miio protocol call 260223565 app_segment_clean '[22]'"
  clean_kinderzimmer: "miio protocol call 260223565 app_segment_clean '[21]'"

automation:

   name: zonedcleanup
   initial_state: True
   trigger:
     - platform: state
       entity_id: input_select.zone_cleanup
   action:
    - service_template: >
          {% if trigger.to_state.state == 'Wohnzimmer' %}
            shell_command.clean_wohnzimmer
          {% elif trigger.to_state.state == 'Küche' %}
            shell_command.clean_kuche
          {% elif trigger.to_state.state == 'Badezimmer' %}
            shell_command.clean_badezimmer
          {% elif trigger.to_state.state == 'Flur' %}
            shell_command.clean_flur
          {% elif trigger.to_state.state == 'Schlafzimmer' %}
            shell_command.clean_schlafzimmer
          {% elif trigger.to_state.state == 'Kinderzimmer' %}
            shell_command.clean_kinderzimmer
          {% elif trigger.to_state.state == 'Wohnzimmer + Küche'%}
            shell_command.clean_wohnkuche
          {% elif trigger.to_state.state == 'Essecke + Küche'%}
            shell_command.clean_essekuche
          {% elif trigger.to_state.state == 'Wohnbereich'%}
            shell_command.clean_essewohnkuche
          {% elif trigger.to_state.state == 'Essecke'%}
            shell_command.clean_esse
          {% elif trigger.to_state.state == 'Wohnzimmer + Essecke'%}
            shell_command.clean_essewohn
          {% endif %}
    - delay: '00:00:30'
    - service: input_select.select_option
      data:
        entity_id: input_select.zone_cleanup
        option: 'Wähle...'

3 Likes

great! Vielen Dank!

In your shell commands, what is the 260223565? Is that supposed to be the roboip of the device? as stated in an earlier post?

and then start app_segment_clean with:
miio protocol call app_segment_clean ‘[ROOMID]’

You could use the IP or ID from your Robot.

Have a look at here (bottom of the page):

miio protocol call id-or-address nameOfMethod paramsAsJSON

I’m trying to get the Roborock S6 token, I’ve tried so far looking into Android log file (Mi Home 5.5.48) and with the miio npm, without any luck… How did you guys get the token?

Cheers

Answering myself, I understood wrongly that any version FROM 5.4.49 was fine, but it seems that just THAT version shows the token unencrypted xD.

I just got it, I’m going to try to configure it now…

Regards

Thank you!
This is a great solution. especially when there are rooms which would require more than one zone defined.

I have a S6 and couldn’t get the room numbers - it is just empty:

ha$ miio protocol call 192.168.7.112 get_room_mapping
INFO Attempting to call get_room_mapping on 192.168.7.112

INFO Device found, making call

INFO Got result:
[]

I don’t know why.
The numbers of your rooms seem to be sequentially numbered.
Because it is the first run ever for my S6 creating the map, I just tried starting with 1 and it started cleaning the corresponding room:

miio protocol call 192.168.7.112 app_segment_clean ‘[1]’

I simply incremented the room number until no room was marked on the map in the app.