My hacky addition of my roborock s7 to HomeKit

Hi!
Have just started using home assistant, mainly so I can expose and integrate all my devices to HomeKit. I have been looking online for a solution to exposing my roborock s7 to HomeKit, however all the results I found were using Homebridge to expose it as a fan and I don’t want to set up homebridge just for this use. I also couldn’t find any updated topics on home assistant about this (taking advantage of preset modes particularly) so here’s my hacky code i made for this. I know it’s very possible to make this more efficient, however this is my first time making a template. (Also first post here).

Also, I haven’t included speed at all in this as I have configured custom speeds and suction for each room using the mi home app.

#configuration.yaml

#for tracking preset mode
input_select:
  roborock_s7_preset_mode:
    name: "Roborock preset mode"
    options:
      - "no bedroom clean"
      - "full clean"
      - "cleaning kitchen"
      - "cleaning x room"

fan:
  -platform: template
  fans:
      roborock_s7:
        friendly_name: "Ron Sweepsley"
        value_template: "{%if states('vacuum.robovac') == 'cleaning' %}on{%elif states('vacuum.robovac') == 'paused' %}on{%else %}off{% endif %}"
        preset_mode_template: "{{ states('input_select.roborock_s7_preset_mode') }}"
        # turn_on and turn_off both dock vacuum as turn_on would activate when disabling a preset.
        turn_on:
          service: vacuum.return_to_base
          data: {}
          target:
            device_id: device id
        turn_off:
          service: vacuum.return_to_base
          data: {}
          target:
            device_id: device id
        # calls a script to process a different cleaning command depending on preset mode
        set_preset_mode:
          service: script.roborock_clean
          data:
            preset_mode: "{{ preset_mode }}"
        preset_modes:
          - "no bedroom clean"
          - "full clean"
          - "cleaning kitchen"
          - "cleaning x bedroom"

And then below is the scipt.roborock_clean that is called when activating a preset mode. This was made in visual editor, probably can also be more efficient.

sequence:
  - service: input_select.select_option
    target:
      entity_id: input_select.roborock_s7_preset_mode
    data:
      option: '{{ preset_mode }}'
  - choose:
      - conditions:
          - condition: state
            entity_id: input_select.roborock_s7_preset_mode
            state: no bedroom clean
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            target:
              device_id: deviceid
            data:
              segments:
                - 16
                - 21
                - 23
                - 24
                - 25
      - conditions:
          - condition: state
            entity_id: input_select.roborock_s7_preset_mode
            state: full clean
        sequence:
          - service: vacuum.start
            target:
              device_id: deviceid
            data: {}
      - conditions:
          - condition: state
            entity_id: input_select.roborock_s7_preset_mode
            state: cleaning kitchen
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            data:
              segments: 24
            target:
              device_id: deviceid
      #  below is for a specific bedroom
      - conditions:
          - condition: state
            entity_id: input_select.roborock_s7_preset_mode
            state: cleaning x bedroom
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            data:
              segments: 17
            target:
              device_id: deviceid
    default: []
  - service: fan.set_preset_mode
    data: 'null'
    target:
      entity_id: fan.roborock_s7
mode: queued
alias: Roborock Clean
max: 10

Anyway, I hope this helps someone who’s trying to do what i did. Any suggestions to improve this are welcome :slight_smile:.

Thought I would come back to this, with two main updates:

  1. remove the reliance on an input select list.
  2. added ability to queue 1 room once cleaning has started.

First is the config.yaml part. The preset_mode_template does what I want it to do, however it doesn’t actually do it the way it’s written in code. I would like it do be indicative of the room it’s currently cleaning or queued to clean, but then reset to none or null when finished cleaning.

Somehow tho the error from this preset_mode_template means that preset mode is never changed, however can still be set, and therefore passed to the following script

#config
fan:
  - platform: template
    fans:
      roborock_s7:
        friendly_name: "Ron Sweepsley"
        #value_template: shows status of vacuum
        value_template: "{%if states('vacuum.robovac') == 'cleaning' %}on{%elif states('vacuum.robovac') == 'paused' %}on{%else %}off{% endif %}"
        #prese_mode_template: this is the code I thought would make preset modes turn off when docked,
        # however, it only works as is makes a specifically good error that resets the preset mode.. not quite sure how
        preset_mode_template: "{%if states('vacuum.robovac') == 'docked' %}null{% else %}{{ this.preset_modes.roborock_s7 }}{% endif %}"
        #return vacuum to base on turn on/off
        turn_on:
          service: vacuum.return_to_base
          data: {}
          target:
            device_id: ____
        turn_off:
          service: vacuum.return_to_base
          data: {}
          target:
            device_id: _____
        # when preset mode set, calls script to start cleanings
        set_preset_mode:
          service: script.roborock_clean
          data:
            preset_mode: "{{ preset_mode }}"
        # different preset modes for different rooms/zones
        preset_modes:
          - "room 1"
          - "room 2"
          - "room 3"
          - "room 4"
          - "room group 1"
          - "room group 2"
          - "room group 3"
          - "full clean"
          - "zone clean"

Here is the updated script as well, it is now run parallel, and can queue a room once cleaning has actually started. Also I have used template conditions here instead of the previous state conditions to remove reliance on the input_select.

#script
sequence:
  - service: fan.set_preset_mode
    data:
      preset_mode: "{{ preset_mode }}"
    target:
      entity_id: fan.roborock_s7
  - if:
      - condition: state
        entity_id: vacuum.robovac
        state: cleaning
    then:
      - wait_for_trigger:
          - platform: state
            entity_id:
              - vacuum.robovac
            to: returning
          - platform: state
            entity_id:
              - vacuum.robovac
            to: docked
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'room group 1' }}"
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            target:
              device_id: ____
            data:
              segments:
                - 22
                - 23
                - 24
                - 25
                - 26
                - 27
                - 30
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'full clean' }}"
        sequence:
          - service: vacuum.start
            target:
              device_id: ____
            data: {}
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'room 2' }}"
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            data:
              segments: 25
            target:
              device_id: ____
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'room 3' }}"
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            data:
              segments: 18
            target:
              device_id: ____
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'room 4' }}"
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            data:
              segments: 17
            target:
              device_id: ____
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'room 5' }}"
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            data:
              segments: 29
            target:
              device_id: ____
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'room group 2' }}"
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            data:
              segments:
                - 23
                - 24
                - 25
                - 26
            target:
              device_id: ____
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'room group 3' }}"
        sequence:
          - service: xiaomi_miio.vacuum_clean_segment
            data:
              segments:
                - 24
                - 26
            target:
              device_id: ____
      - conditions:
          - condition: template
            value_template: "{{ preset_mode == 'zone clean' }}"
        sequence:
          - service: xiaomi_miio.vacuum_clean_zone
            data:
              zone:
                - - 24900
                  - 24400
                  - 26000
                  - 25500
              repeats: 1
            target:
              device_id: ____
    default: []
mode: parallel
alias: Roborock Clean
max: 10
icon: mdi:robot-vacuum

Anyway as before if there are any templating geniuses who could get this running properly that would be awesome, I just haven’t found anything else that integrates a roborock into HomeKit with room control like this anywhere, so this is my wacky solution

1 Like

:slight_smile: I been looking for this.