[Howto] Buttons for Room Cleaning (with Queuing) for [Xiaomi Miio] (Robot Vacuum)

For some reason writing the same room number twice in params not working for me on segment cleaning, not sure why… The robot only clean the room once

Your cards are looking awesome. Would you mind shaering the code?

1 Like

Thanks, it’s by this great guy:

Just wanted to say thank you Michelle! I’ve been looking for a way to call individual scripts for months, your “vacuum back of house” script works perfectly. I just tested calling 7 scripts sequentially.

The only question I have (and I may figure this out before you reply), is if my vacuum hits 20% battery, and let’s it on Script #4, it attempts to “return home” to charge, however the logic of this automation tells it to go to the next area. What I think needs to be added is a battery level condition to each script call in this automation - if battery is 20%, then return home.

Edit: Here’s how to set that up. I’m actually using a different automation now even though yours works. https://smarthomepursuits.com/roborock-sequentially-vacuum-multiple-rooms/

1 Like

Not sure exactly if my issue is related to my room cleaning script, but it’s worth asking.

Here is my script:

mode: queued
icon: mdi:robot-vacuum
alias: Vacuum Queued Cleaning
max: 10
sequence:
  - choose:
      - alias: >-
          Vacuum working or in error --> wait until returning to dock or docked
          before starting job (or give up after 1,5h)
        conditions:
          - condition: or
            conditions:
              - alias: Vacuum cleaning
                condition: state
                entity_id: vacuum.aspirador
                state: cleaning
              - alias: Vacuum reporting error
                condition: state
                entity_id: vacuum.aspirador
                state: error
        sequence:
          - wait_for_trigger:
              - platform: template
                value_template: >-
                  {{ states('vacuum.aspirador') in ['returning', 'docked',
                  'idle'] and is_state('input_select.area_to_clean', 'Choose
                  area') }}
            continue_on_timeout: false
            timeout: '01:30:00'
          - service: input_select.select_option
            target:
              entity_id: input_select.area_to_clean
            data:
              option: '{{ area_to_clean }}'
      - alias: Vacuum returning, docked or idle --> start job immediately
        conditions:
          - condition: or
            conditions:
              - alias: Vacuum returning to dock
                condition: state
                entity_id: vacuum.aspirador
                state: returning
              - alias: Vacuum docked
                condition: state
                entity_id: vacuum.aspirador
                state: docked
              - alias: Vacuum stopped outside dock
                condition: state
                entity_id: vacuum.aspirador
                state: idle
          - alias: No cleaning area chosen
            condition: state
            entity_id: input_select.area_to_clean
            state: Choose area
        sequence:
          - service: input_select.select_option
            target:
              entity_id: input_select.area_to_clean
            data:
              option: '{{ area_to_clean }}'

Basically this script is called with a parameter area_to_clean, which is set to an input_select whose state change then triggers an automation which actually runs the cleaning tasks.

My issue is that when I call this script it simply doesn’t start, it seems it is queued even when no instance is running (unless a cleaning is already on-going).

This is the looks of the script entity when I run it:

image

Looking at the trace, nothing relevant seems to appear:

And this is the Trace Timeline after cancelling it manually:

Although for sure this script is not running, it seems that HA is queuing the first script execution, even though it is not running yet at all.

Not sure if there is something wrong with my script or if there is any misunderstanding on the way the queued mode is supposed to work, but I’m really at a loss here.

Can anyone try to help me out?

Just out of curiosity (since I just set up queued cleaning successfully this weekend), did you see my link above?

Also, I read over your notes a few times but I’m not sure I understand why you are calling an input_select instead of a script directly. Is it because you set a room to clean from Lovelace, and then the automation triggers at a certain time for that room?

Yes I did, thanks for that

Input_Select is basically the room/area selector for cleaning, for me to know exactly what is being cleaned (room/area). Each input_select option has a corresponding cleaning script which is triggered when the input_select option is chosen.

Regardless of that, what I really don’t get it is why my script is not being started immediately rather than queued immediately.
As the debug trace does not seem to bring anything useful in this specific case, I am now trying to figure it out using log writes before anything else, to try to find out if I have any error in the choose conditions/wait_template (although it doesn’t look like).

Thanks anyway for your inputs.

Quick question on this script: any specific reason why do you have a wait_for_trigger after each vacuum.send_command? Wouldn’t it be enough to check these before?

Thanks for your help.

This is awesome, thank you!

Hi,

if I try to paste the main script in the ui, I get the following error:

Message malformed: extra keys not allowed @ data['fields']

Ruben,
Are you still using this script?

many thanks for the guide, I successfully added the script and input.numbers to determine the rooms. works like a charm :wink: I also created input.booleans to toggle a switch and clean the desired room, this is how the dashboard looks like:

UPDATE: found the solution: Xiaomi vacuum restore/select backup map (multi floor support) . works like a charm!

I live in a multi-story house, the floors look as following:

main-floor

second-floor

the issue
I have to open the Mi-home app and select on which floor the vacuum is in order that he can clean the rooms accordingly. shouldnt it auto-detect where he is when I send the command to lets say clean Raum1 / Bad in the dashboard on the second-floor? of course the vacuum is then already in the second-floor.

1 Like

Hi there,

i got a Problem and cannot solve it by myself.

I copy/pasted the scripts from the first Postings, i changed my entity_id and device_id and i was able to retrieve all the room numbers by testing it out by the given way in this first posting.

btw: i’m using a Roborock S5.

now i changed the list of rooms to my need, so the main script looks like this:

mode: queued
alias: Roborock Room Cleaning
max: 30
fields:
  room:
    name: Room
    required: true
    example: wohnzimmer
    selector:
      select:
        options:
          - bad
          - badezimmer
          - bastelzimmer
          - esszimmer
          - flur
          - herrenzimmer
          - kueche
          - schlafzimmer
          - wohnzimmer
sequence:
  - choose:
      - conditions:
          - condition: or
            conditions:
              - condition: state
                entity_id: vacuum.r2d2
                state: cleaning
              - condition: state
                entity_id: vacuum.r2d2
                state: error
        sequence:
          - wait_for_trigger:
              - platform: state
                entity_id: vacuum.r2d2
                to: returning
              - platform: state
                entity_id: vacuum.r2d2
                to: docked
            continue_on_timeout: false
            timeout: "01:30:00"
          - service: vacuum.send_command
            target:
              device_id: 123youdontneedtosee
            data_template:
              command: app_segment_clean
              params: >
                {% set room_id = states("input_number.roborock_room_enum_" +
                room) | int %} {{ room_id }}
          - wait_for_trigger:
              - platform: state
                entity_id: vacuum.r2d2
                to: returning
              - platform: state
                entity_id: vacuum.r2d2
                to: docked
            continue_on_timeout: false
            timeout: "01:30:00"
      - conditions:
          - condition: or
            conditions:
              - condition: state
                entity_id: vacuum.r2d2
                state: returning
              - condition: state
                entity_id: vacuum.r2d2
                state: docked
              - condition: state
                entity_id: vacuum.r2d2
                state: idle
        sequence:
          - service: vacuum.send_command
            target:
              device_id: 123youdontneedtosee
            data_template:
              command: app_segment_clean
              params: >
                {% set room_id = states("input_number.roborock_room_enum_" +
                room) | int %} {{ room_id }}
          - wait_for_trigger:
              - platform: state
                entity_id: vacuum.r2d2
                to: returning
              - platform: state
                entity_id: vacuum.r2d2
                to: docked
            continue_on_timeout: false
            timeout: "01:30:00"
    default: []

i made the helpers with th roomid’s for each room, by example wohnzimmer

      {
        "id": "roborock_room_enum_wohnzimmer",
        "min": 1.0,
        "max": 22.0,
        "name": "roborock_room_enum_wohnzimmer",
        "icon": "mdi:sofa",
        "mode": "box",
        "step": 1.0
      },

and now i implemented the button into my lovelace:

show_name: true
show_icon: true
type: entity-button
tap_action:
  action: call-service
  service: script.roborock_room_cleaning
  service_data:
    room: wohnzimmer
entity: script.roborock_room_cleaning
icon_height: 60px
icon: hass:robot-vacuum
name: Wohnzimmer saugen

But when i now click the Button it says:

Fehler beim Aufrufen des Diensts script/roborock_room_cleaning. Service not found.

I don’t know what i’ve done to make it fail, maybe someone her can help me?

Thanks and best regards
Bjoern

This is what i found in the Log:

2023-01-07 00:07:52.834 ERROR (MainThread) [frontend.js.latest.202301040] https://hass.nomster.de/frontend_latest/app.c7254a29.js:850:114174 Error: Failed to execute 'define' on 'CustomElementRegistry': the name "xiaomi-vacuum-map-card-editor" has already been used with this registry

Unfortunately i don‘t know what to do with this Info :smirk:

Anybody, please?

I have this error also, looking for a fix?

I fixed it by myself.
i deleted the script, made a restart of home assistant, created the script new and after an addditional restart it is now working.

found this in the forum to gave me the idea: How to create custom service and call from button - #12 by sheminasalam

I have the same error

Hey there, would you mind explaining (to a newbie) how you created these switches? What I’m essentially trying to achieve is to have a switch for each room which I can then use in Homekit.

sure. first you have to create input-booleans (its like a virtual switch), here is how to do it: Input Boolean - Home Assistant you have to create the boolean as a switch.

this switch is used to trigger the room-cleaning itself. You can expose the input.booleans to Homekit via the Homekit-integration: HomeKit - Home Assistant

then please follow the instructions from the thread-creator. it is important to follow it precisely in order to make it work.

my script looks as following. you have to replace the vacuum-entity and device-id with yours, as well as the room-names.

mode: queued
alias: Roborock Room Cleaning
max: 30
fields:
  room:
    name: Room
    required: true
    example: wohnzimmer
    selector:
      select:
        options:
          - wohnzimmer
          - kitchen
          - 1ogbad
          - 1ogofficeandreas
          - 1ogroomandreas
          - 1oggang
          - 1ogofficemarco
          - 2ogroommarco
          - ugeingang
sequence:
  - choose:
      - conditions:
          - condition: or
            conditions:
              - condition: state
                state: cleaning
                entity_id: vacuum.roborock_s7
              - condition: state
                state: error
                entity_id: vacuum.roborock_s7
        sequence:
          - wait_for_trigger:
              - platform: state
                entity_id:
                  - vacuum.roborock_s7
                to: idle
            continue_on_timeout: false
            timeout: "01:30:00"
          - service: vacuum.send_command
            target:
              device_id: XXX
            data_template:
              command: app_segment_clean
              params: >
                {% set room_id = states("input_number.roborock_room_enum_" +
                room) | int %} {{ room_id }}
          - wait_for_trigger:
              - platform: state
                entity_id:
                  - vacuum.roborock_s7
                to: idle
              - platform: state
                entity_id:
                  - vacuum.roborock_s7
                to: docked
              - platform: state
                entity_id:
                  - vacuum.roborock_s7
                to: returning
                enabled: false
            continue_on_timeout: false
            timeout: "01:30:00"
      - conditions:
          - condition: or
            conditions:
              - condition: state
                entity_id: vacuum.roborock_s7
                state: idle
              - condition: state
                entity_id: vacuum.roborock_s7
                state: docked
              - condition: state
                entity_id: vacuum.roborock_s7
                state: returning
        sequence:
          - service: vacuum.send_command
            target:
              device_id: XXX
            data_template:
              command: app_segment_clean
              params: >
                {% set room_id = states("input_number.roborock_room_enum_" +
                room) | int %} {{ room_id }}
          - wait_for_trigger:
              - platform: state
                entity_id:
                  - vacuum.roborock_s7
                to: idle
              - platform: state
                entity_id:
                  - vacuum.roborock_s7
                to: docked
                enabled: true
              - platform: state
                entity_id:
                  - vacuum.roborock_s7
                to: returning
                enabled: true
            continue_on_timeout: false
            timeout: "01:30:00"
    default: []