Start Roborock Routine / Room / Zone Cleaning with Press on Button Card

Hi there,
is there a way to start a

  1. routine that was setup in the Roborock app
  2. room cleaning with SmartPlan AI
  3. zone cleaning with SmartPlan AI

with simple buttons on the dashboard?

I have a Roborock S8 MaxV Ultra, and the Roborock extension (HACS) + Vacuum Card is working. However I do not like to use the UI of vacuum card. My goal is to get the 3 most used tasks for the vacuum in the most simplistic way (buttons) + a return to dock button on the dashboard.

Any pointers how I can get this done?

1 Like

The solution:

  1. Install official Roborock integration (HACS version is not supported anymore by devs)
  2. Get list of room IDs through dev tools → Roborock: Get maps
  3. Create Button:
show_name: true
show_icon: true
type: button
entity: vacuum.YOURVACUUMENTITIY #replace
name: Kitchen #name this according to your room or however you want
icon: mdi:robot-vacuum
tap_action:
  action: perform-action
  perform_action: vacuum.send_command
  data:
    command: app_segment_clean
    params:
      - segments:
          - 22 #replace this number with one from step 2
        repeat: 1 #set to 2, 3 or more if you want your robot to repeat the cleaning 2, 3 or more times. 1 does only one run.
  target:
    entity_id: vacuum.YOURVACUUMENTITIY #replace

regarding my initial questions:

  1. no, you cannot integrate/sync routines from roborock app to home assistant
  2. yes you can – and the above button does so, if your Roborock is currently configured with SmartPlan AI as default. You can set this in the Roborock extension
  3. you could do this with the more complex UI of custom vacuum map, not with the button method above
1 Like

I had a Roborock S7 first, integrated through the Mii Home custom integration, which worked natively with the Custom vacuum map and camera map.

Now I have the Qrevo Master, setup with the Roborock app.

I have the native Roborock integration setup, I have made scripts to clean rooms, but how do I get a list of zones to clean, and maybe pin n go with the Custom Vacuum Map Card? I have to give a camera entity, but the Qrevo Master only gives an image entity. I’m not using the “Xiaomi Cloud Map Extractor”

Had the same issue, and ultimately used humbertogontijo/homeassistant. I know they say it’s not supported anymore, but it seems to me that the official integration is simply worse in all aspects.
Now, using this together with xiaomi vacuum map card (which has support for this hacs module) works great.
Haven’t really found any working way of fetching the roborock token for xiaomi cloud map extractor, so this seems to be the only solution for these QRevos that only work with the Roborock app

Here a Qrevo slim
The setting of rooms works like indicated in the integration doucmentation.

It there a way to specify if it should Vacuum, mop or both?
Now it does by default both. I do not want my wooden floor get moped daily…

I setup my Qrevo Curv with the core integration. What I did was create a script for each room. Each script has two steps - 1. Put the robot in the correct cleaning mode, 2. send the robot to the correct room. Then I attached these scripts to a button on my dashboard. So I can one-tap send my Robo to clean the room I want and it won’t prepare the mops for a carpet room.

Script:
Step 1: ‘Perform Action’ - (set the cleaning mode)
Action: Vacuum: Send Command
Target: Your Robo
Command: set_custom_mode
Parameters: 106

I just tried different numbers with my roborock App open and watched it change as I set different parameters 106,107,108 etc once you figure out 106 = Vacuum only then you’ve figured out what modes correlate to what number for the parameters.

Step 2: ‘Perform Action’ (Dispatch the robo to the room)
Action: Vacuum: Send Command
Target: Your Robo
Command: app_segment_clean
Parameters:

  • Segments:
  • 7 (room number from Dev.Tools)
    repeat: 2

Then you create a little “Vacuum Center” on your dashboard with a button for each room, and each button performs the script you created for each room - dispatching your robot in the correct mode for the correct room. Nailed it! Happy Tinkering!

What I haven’t figured out is zone cleaning. If I want the robot to clean around the dog bowls zone - Right now, I have to make the dogbowl area a “room”. Eventually I want a vibration sensor on the dog bowl stand, that triggers an automation that dispatches the robo to mop/vac the dog bowl zone after my 2 Saint Bernards make a mess!

I can’t seem to find my vacuum only mode. Do you happen to know where I can find it for the Roborock S8? I tried 99-120 and none of those worked.

I do not know. For me, I went into my Roborock app and set a custom cleaning mode for each room. Then in those ‘parameters’ I have set 106 = Customize mode (which is set in the Roborock app). Try opening the Roborock app, and put the robot in “mop” mode, resume to the map view in the Roborock app and leave it open, then on your computer in developer tools- I typed in command: set_custom_mode | parameters 108 and I could watch it change to Vacuum on my app and I got the green check when i hit perform action. I don’t know if the parameters numbers change per roborock model I’m sorry. I can’t remember where I even found what is working. Keep diggin though!

This is where I found the parameters - on the menu it shows the various API commands you can experiment with. Try different commands. Api Commands

I looked for a good way to allow for easy room cleaning. I did not like the hardcoded rooms most solutions called for. Unfortunately, the action to get the room numbers is not easily suited to find a segment based on the room name.

So I created a sensor that calls the action to get the map and reverses the loopup so you can find segment numbers. I also created a select entity that allows you to pick a room on the current floor. Then I created a script to use these.

Note that the room select entity does not survive a restart. It does have a default list: if it can find the default for a floor it will set that. I did that because normally my robot only does my bedroom. When you adjust the defaults, always make sure you have an “All” selection at the end of the defaults list.

The sensors (goes in template.yaml):

- trigger:
    - trigger: homeassistant
      event: start
    - trigger: state
      entity_id: select.dusty_selected_map
      from:
        - unavailable
        - unknown
      not_to:
        - unavailable
        - unknown
  action:
    - action: roborock.get_maps
      target:
        entity_id: vacuum.dusty
      data: {}
      response_variable: maps
  sensor:
    - name: "dusty roomnumbers"
      unique_id: sensor.dusty_roomnumbers
      icon: mdi:floor-plan
      state: "{{ 'OK' if maps else 'unavailable' }}"
      attributes:
        rooms: |
          {%- set ns = namespace(floors='{')-%}
          {%- for floor in maps['vacuum.dusty'].maps -%}
            {% set ns.rooms = '{ "flag":' + floor.flag | string %}
            {%- for room in floor.rooms %}
              {%- set ns.rooms = ns.rooms + ', ' + '"' + floor.rooms[room] + '": ' + room | string -%}
            {%-endfor-%}
            {%- set ns.floors = ns.floors + ('' if ns.floors=='{' else ',') + 
                                '"' + floor.name + '": ' + ns.rooms + '}' -%}
          {%-endfor%}
          {{ (ns.floors + '}') | from_json }}
- trigger:
    - trigger: state
      id: state
      entity_id: 
        - sensor.dusty_roomnumbers
        - select.dusty_selected_map
    - trigger: event
      id: pick
      event_type: dusty_room_picked
    - trigger: event
      id: "reload"
      event_type: event_template_reloaded
  action:
    variables:
      defaults: ['Bedroom', 'All']
  select:
    - name: "dusty room"
      icon: mdi:location-enter
      unique_id: sensor.dusty_room
      options: |
        {%- if has_value('select.dusty_selected_map') and has_value('sensor.dusty_roomnumbers') -%}
          {%- set rooms = state_attr('sensor.dusty_roomnumbers','rooms') | default([]) -%}
          {%- set selected = states('select.dusty_selected_map') | default('') -%}
          {{ [defaults | last] + rooms.get(selected,[]) | reject('eq','flag') | list }}
        {%- else -%}
          {{ [defaults | last] }}
        {%- endif -%}
      state: |
        {%- if trigger is defined and trigger and trigger.id == 'pick' -%}
          {%- set cur = trigger.event.data.option -%}
        {%- elif trigger is defined and trigger and trigger.id == 'state' and 
                  trigger.entity_id == 'select.dusty_selected_map' -%}
          {%- set cur = None -%}
        {%- else -%}
          {%- set cur = states('select.dusty_room') -%}
        {%- endif -%}
        {%- if has_value('select.dusty_selected_map') and has_value('sensor.dusty_roomnumbers') -%}
          {%- set rooms = state_attr('sensor.dusty_roomnumbers','rooms') | default([]) -%}
          {%- set selected = states('select.dusty_selected_map') | default('') -%}
          {%- if selected in rooms -%}
            {%- set options = [defaults | last] + rooms.get(selected,[]) | reject('eq','flag') | list -%}
          {%- else -%}
            {%- set options = [defaults | last] -%}
          {%- endif -%}
          {%- set cur = cur if cur in options else defaults | select("in", options) | first() -%}
          {{ cur if cur in options else defaults | last }}
        {%- else -%}
          {{ defaults | last if cur in ['unavailable','unknown'] else cur }}
        {%- endif -%}
      select_option: 
        - event: dusty_room_picked
          event_data: 
            option: "{{ option }}"
      optimistic: true

The script (goes in scripts.yaml):

alias: Start dusty
variables:
  rooms: "{{ state_attr('sensor.dusty_roomnumbers','rooms') }}"
  floor: "{{states('select.dusty_selected_map') }}"
  room: "{{ states('select.dusty_room') }}"
  segments: "{{ [rooms[floor][room]] | reject('eq', Undefined) | list }}"
sequence:
  - if:
      - condition: template
        value_template: "{{ segments | length == 0 }}"
    then:
      - action: vacuum.start
        metadata: {}
        data: {}
        target:
          entity_id: vacuum.dusty
    else:
      - action: vacuum.send_command
        data:
          command: app_segment_clean
          params:
            - segments: "{{ segments }}"
              repeat: 1
        target:
          entity_id: vacuum.dusty
mode: single
icon: mdi:robot-vacuum-variant
1 Like

Maybe sneaking in a trigger with homeassistant_started or the start event trigger might fix this?

I’m not sure it is restored, and the select entity is the only place I store it. If ever it goes unavailable it looses its state. for me that is irrelevant, I just felt it was worh mentioning. I could have used an input select and an automtion it it were important to me.

Something worse though: it seems the service returns wrong data sometimes when the floor is changed. I sometimes get the rooms of another floor in multiple places. A reload of the integration fixes it. I think it might be a bug in te integration. I also suspected timing, but triggering a new call does not always fix it.

Hmm. Personally, I would pre-emptively call an integration reload and set a small 5s delay at the top of the actions then. It’s more of a workaround than a solution, but at least it avoids incorrect data being returned.

Maybe the simple fix is not to ask the room config again after a floor change but only on reboot. I don’t restructure my house as much as I reboot :smile:

1 Like

Hi guys, this feature was added in the latest release of HA, and for every routine, a new button entity will be created that can start it. Enjoy

3 Likes

Hi, I have a simple routine to trigger a routine on my Roborock Qrevo Curv S5X.

alias: Clean kitchen button
description: ""
triggers:
  - device_id: bc668063cf9dda38695e3545bbbf5ea3
    domain: zha
    type: remote_button_short_press
    subtype: remote_button_short_press
    trigger: device
conditions: []
actions:
  - device_id: 1a7e2a426c330f26413113a163a91cac
    domain: button
    entity_id: c133d0d2d24bb2b6b18a89f898b089b8
    type: press
mode: single

The automation works fine and the event is dispatched but nothing happens on the Roborock side. I deleted and recreated the routine in both Roborock app and Home Assistant. Any way I can debug it?