Just sharing my setup as I could find little documentation when I set out.
I have a Roborock Q5 Pro.
It has a vacuum and a mop but the mop does not lift. As such I was worried about it wetting carpeted areas. The in-app configuration did not seem to have a way to prevent this so I created two ‘floors’ one for vacuuming with all the areas and one for mopping with carpeted rooms blocked by “invisible walls” in the app and rugs blocked by “no go zones” defined by estimation and refined by trial and error.
I then had this script to call to start a clean, crucially rooms were named identically in the roborock app and HA. Note that in the logic I convert “Kitchen” into “Living Room” as in HA i make a distinction but in roborock I treat them as one room.
If you specify a room or rooms, the script will query the roborock to get the room ID, no matter which map is selected (as room IDs can vary between maps).
If the waterbox is connected then it will default to the mop map. There is an issue currently where the waterbox always shows as ‘connected’.
alias: Run Vacuum cleaner if appropriate
description: >-
This script will perform a number of checks and choosing the appropriate
cleaning mode (vacuuming with or without mopping) before then starting the
clean.
Checks include ensuring the hour is sociable and that guests are not staying
and that a clean is not already in progress.
fields:
rooms:
selector:
area:
multiple: true
name: Rooms to clean
description: >-
Select the room or rooms to be cleaned. If no rooms are specified all
rooms will be cleaned.
example: "[\"Kitchen\", \"Bedroom\"]"
sequence:
- condition: state
entity_id: input_boolean.manual_mode
state: "off"
- condition: device
device_id: eb2e40c6ea8b4dcfc0c4c2adfe7c00a9
domain: vacuum
entity_id: 685dc4ca0c5dfe98cf53914ef195f498
type: is_docked
- condition: state
entity_id: binary_sensor.everyone_sleeping
state: "off"
- condition: time
after: "08:00:00"
before: "21:40:00"
- if:
- condition: state
entity_id: input_boolean.guest_mode
state: "on"
then:
- action: notify.mobile_app_pixel_8
metadata: {}
data:
title: Cleaning not done because of guests
message: The Robovac did not clean because guest mode was on
- action: notify.mobile_app_pixel_9a
metadata: {}
data:
title: Cleaning not done because of guests
message: The Robovac did not clean because guest mode was on
- stop: Guests mode is on
alias: Notify and cancel is guest mode is on
- alias: Choose Mop or Vac map based on water box
if:
- condition: state
entity_id: binary_sensor.q5_pro_water_box_attached
state: "on"
then:
- device_id: eb2e40c6ea8b4dcfc0c4c2adfe7c00a9
domain: select
entity_id: 8851ed04979630991023c9eb217211cd
type: select_option
option: Home Mop
- wait_for_trigger:
- trigger: state
entity_id:
- select.q5_pro_selected_map
to: Home Mop
continue_on_timeout: true
timeout:
hours: 0
minutes: 0
seconds: 2
milliseconds: 0
- condition: state
entity_id: select.q5_pro_selected_map
state: Home Mop
else:
- device_id: eb2e40c6ea8b4dcfc0c4c2adfe7c00a9
domain: select
entity_id: 8851ed04979630991023c9eb217211cd
type: select_option
option: Home Vacuum
- alias: Perform targeted room cleaning if rooms specified
if:
- condition: template
value_template: |
{{ rooms is defined and rooms is not none and rooms | length > 0 }}
alias: If at least 1 room specified
then:
- alias: Cleaned & normalised room list
variables:
cleaned_rooms: |
{% set room_map = {
'Kitchen': 'Living Room',
'Living Room': 'Living Room',
'Bathroom': 'Bathroom',
'Bedroom': 'Bedroom',
'Hallway': 'Hallway',
'Snug': 'Snug',
'Study': 'Study'
} %}
{% set input_rooms = rooms | map('title') | list %}
{{ input_rooms
| reject('equalto', 'Garden')
| map('replace', 'Kitchen', 'Living Room')
| select('in', room_map.values() | list)
| list }}
- alias: Get current map name
variables:
selected_map: "{{ states('select.q5_pro_selected_map') }}"
- alias: Fetch maps from Roborock
target:
entity_id: vacuum.q5_pro
response_variable: roborock_maps_response
action: roborock.get_maps
data: {}
- alias: Extract segment IDs from map
variables:
segments: >
{% set maps = roborock_maps_response['vacuum.q5_pro']['maps'] %} {%
set current_map = maps | selectattr('name', 'equalto', selected_map)
| list | first %} {% set room_lookup = current_map.rooms %} {% set
matched = namespace(ids=[]) %} {% for id, name in
room_lookup.items() %} {% if name in cleaned_rooms %}
{% set matched.ids = matched.ids + [id | int] %}
{% endif %} {% endfor %} {{ matched.ids }}
- alias: Send targeted clean command
choose:
- conditions:
- condition: template
value_template: "{{ segments | length > 0 }}"
alias: If at least 1 segment
sequence:
- data:
command: app_segment_clean
params:
- segments: "{{ segments }}"
repeat: 1
action: vacuum.send_command
target:
device_id: eb2e40c6ea8b4dcfc0c4c2adfe7c00a9
else:
- condition:
- condition: template
value_template: >
{{ (as_timestamp(now()) -
as_timestamp(states('sensor.q5_pro_last_clean_end'))) > 28800 }}
alias: More than 8 hours since last clean
enabled: false
- action: vacuum.start
metadata: {}
data: {}
target:
device_id: eb2e40c6ea8b4dcfc0c4c2adfe7c00a9
- wait_for_trigger:
- type: not_running
device_id: eb2e40c6ea8b4dcfc0c4c2adfe7c00a9
entity_id: 3ffbcc2611e8fd93d3141a037ab7755d
domain: binary_sensor
trigger: device
continue_on_timeout: true
timeout:
hours: 1
minutes: 0
seconds: 0
milliseconds: 0
- action: notify.mobile_app_pixel_8
metadata: {}
data:
title: Roborock stopped cleaning
message: Roborock is showing as {{states('vacuum.q5_pro')}}