Deebot in Home Assistant einbinden

Anmerkung: Diese Anleitung ist gültig bis HA2024.1 und ab HA2024.2. Hier wurden zwar die Komponenten in den Core überführt und mit der Ecovacs Core Integration zusammengeführt, jedoch hat sich dadurch nicht viel geändert. Die Migration sieht jedenfalls so aus: 1. Entfernen der Deebot Integration in Geräte & Dienste – 2. Deinstallation Deebot 4 Home Assistant in HACS – 3. Installation der Ecovacs Integration

Ich habe mir vor ein paar Wochen den Ecovas Deebot T10* zugelegt. Dabei handelt es sich um einen Saugroboter mit Wischfunktion. Als Deebot T10+* gibt es diesen auch mit Absaugstation. Bisher bin ich recht zufrieden mit dem Roboter und lasse ihn alle zwei Tage durch die Wohnung huschen. Mit zwei Kindern und einer Katze liegt immer etwas rum und ich war dazu genötigt noch mehr zu saugen, was ich aber nicht selber machen wollte. So musste eine Aushilfe her. Eventuell schreibe ich dazu noch ein ausführliches Review, hier soll es aber erst mal um die Integration in Home Assistant gehen. Danke Deebot 4 Home Assistant ist die Einbindung auch relativ einfach. Entgegen der Anleitung hatte ich ein paar kleinere Probleme, auf die ich hier eingehen werde. Unser Ziel ist es die Advanced UI in unser Dashboard zu integrieren.

Zuletzt aktualisiert am 3. Mai 2024 um 21:59 . Wir weisen darauf hin, dass sich hier angezeigte Preise inzwischen geändert haben können. Alle Angaben ohne Gewähr.

Installation Deebot 4 Home Assistant (bis HA 2024.1)

Ich gehe mal davon aus das ihr HACS bereits installiert habt. Unter Integration wählt ihr „Durchsuchen und Herunterladen von Repositories“ und suchtr dort nach Deebot 4 Home Assistant. Installiert dieses und startet Home Assistant neu.

Geht nun zu Einstellungen -> Geräte und Dienste -> Integration Hinzufügen. Sucht nach Deebot und wählt „Deebot 4 Home Assistant“. Wöhlt als Variante Cloud und gebt im nächsten Dialog eure Zugangsdaten an. Für Deusctland wählt ihr als Land de und Kontinent eu.

Anschließend könt ihr in die Integration gehen und alle Entitäten zu eurem Deebot aktivieren.

Somit habt ihr euren Deebot erst mal grundlegend in Home Assistant eingebunden. Damit ihr ihn aber auch ordentlich steuern könnt, benötigen wir ein paar Scripte.

Ecovacs Integration hinzufügen (ab HA 2024.2)

Ab Home Assistant 2024.2 wurde die Integration in den Core Überführt, das macht es etwas einfacher. Geht einfach auf Einstellungen -> Geräte & Dienste -> INTEGRATION HINZUFÜGEN. Dort sucht ihr nach Ecovacs und konfiguriert die Integration entsprechend. Anschließend könt ihr in die Integration gehen und alle Entitäten zu eurem Deebot aktivieren.

Notwendige Karte installieren.

Das Advanced UI Beispiel benötigt zwei weitere Karten für euer Dashboard, beide lassen sich über HACS installieren. Ihr benötigt zusätzlich noch die Vacuum Card und Button Card. Ihr findet beide im Frontedn Bereich von HACS.

Deebot Scripte einbinden

Wir fangen erst mal damit an, die Räume auszulesen. Euer Deebot muss dazu seine Kartierungsfahrt abgeschlossen haben und ihr solltet die Räume benannt und angepasst haben.

Wählt in der Deebot Integration euer Gerät aus, klickt in den Steuerelemente auf euren Roboter und klappt im folgenden Fenster die Attribute auf. Wichtig sind hier die Namen für die einzelnen Räume, denn diese müssen wir später in den Scripten eintragen.

Alle folgenden Scripte kommen in die configuration.yaml, außer ihr habt z.B. eine eigene Datei für Scripte oder Automations. XYZ müsst ihr durch den Namen eures Deebot ersetzen.

Script

script:
  deebot_clean:
    description: Start a deebot cleaning task
    variables:
      queue: input_text.deebot_XYZ_queue
      vacuum_bot: vacuum.XYZ
    sequence:
      - alias: Get room numbers
        variables:
          # See for appending to list
          # https://github.com/home-assistant/core/issues/33678#issuecomment-609424851
          rooms: >-
            {%- set queue_split = states(queue).split(",") -%}
            {%- set rooms = state_attr(vacuum_bot, "rooms")-%}
            {%- set data = namespace(rooms=[]) -%}
            {%- for room_name in queue_split -%}
              {%- set data.rooms = data.rooms + [rooms[room_name]] -%}
            {%- endfor -%}
            {{ data.rooms | join(",") }}
      - alias: Send cleaning job to vacuum
        service: vacuum.send_command
        data:
          entity_id: "{{ vacuum_bot }}"
          command: spot_area
          params:
            rooms: "{{ rooms }}"
            cleanings: 1

  deebot_room_queue:
    description: Add/Remove a room from the queue
    fields:
      queue:
        description: The queue variable
        example: input_text.deebot_XYZ_queue
      room:
        description: Room, which should be removed or added
        example: kitchen
    sequence:
      - service: input_text.set_value
        target:
          entity_id: "{{ queue }}"
        data:
          value: >-
            {%- set queue_state = states(queue) -%}
            {%- set queue_split = queue_state.split(",") -%}
            {%- if queue_state | length == 0 -%}
              {{ room }}
            {%- elif room in queue_split -%}
              {{ queue_split | reject("eq", room) | list | join(",")}}
            {%- else -%}
              {{ (queue_split + [room]) | join(",") }}
            {%- endif -%}

Automation

Da es immer wieder zu Problemen mit den Automations kommt, solltet ihr sie manuell anlegen. Erstellt einen neue Automatisierung und wechselt in den YAML Modus. Fügt nun deen Code-BLock ein und ändert XYZ in den Namen eures Robots. Anschließend speichern und es sollte passen.

alias: Staubsauger Zimmer resetieren
trigger:
  - platform: event
    event_type: deebot_cleaning_job
    event_data:
      status: finished
  - platform: state
    entity_id:
      - vacuum.XYZ
    to: docked
condition: []
action:
  - alias: Reset room queue
    service: input_text.set_value
    target:
      entity_id: input_text.deebot_XYZ_queue
    data:
      value: ""
mode: single

Hier nochmals der Block, wenn ihr die Automatisierung in die configurations.yaml einfügen wollt, ich würde aber obige Methode verwenden.

automation:
  - alias: Staubsauger Zimmer resetieren
    trigger:
      - platform: event
        event_type: deebot_cleaning_job
        event_data:
          status: finished
      - platform: state
        entity_id:
          - vacuum.XYZ
        to: docked
    condition: []
    action:
    - alias: Reset room queue
      service: input_text.set_value
      target:
        entity_id: input_text.deebot_XYZ_queue
      data:
        value: ""
    mode: single

Recorder

recorder:
  exclude:
    entities:
      - input_text.deebot_XYZ_queue
      - script.deebot_room_queue
    entity_globs:
      - sensor.deebot_*_queue_*

Input_Text

input_text:
  deebot_XYZ_queue:
    name: XYZ Raum Reihenfolge
    max: 255 # Current max limit. See https://www.home-assistant.io/integrations/input_text/#max

Template

Im Abschnitt Sensor des Templates müsst ihr einen Abschnitt für jeden Raum erzeugen, dabei verwendet ihr die Namen der Räume, welche wir unter Attribute ausgelesen haben.

# Room name comes from the integration to match attribute names
template:
  unique_id: deebot_XYZ_queue
  trigger:
    - platform: state
      entity_id: input_text.deebot_XYZ_queue
  sensor:
    # Add for each room the following. Change room_name accordingly
    - unique_id: deebot_XYZ_queue_living_room
      name: deebot_XYZ_queue_living_room
      # room_name must match the room name provided by the vacuum
      state: >
        {% set room_name = "living_room" %}
        {% set queue = trigger.to_state.state.split(",") %}
        {{ queue.index(room_name)+1 if room_name in queue else 0 }}

Geht nun auf die Entwicklerwerkzeuge (Hammer-Symbol), lasst die Konfiguration prüfen und startet Home Assistant neu, wenn alles ok ist.

Einfacher geht es mit Packages. Ihr erzeugt den neuen Eintrag packages innerhalb der Abschnittes homeassistant.

homeassistant:
  packages: !include_dir_named packages
configuration.yaml

Nun erzeugt ihr den neuen Ordner packeges in eurem config Verzeichnis. Ich verwende dazu das Advanced SSH & Web Terminal Add-on.

cd config
mkdir packages

Anschließend erzeugt ihr, z.B. mit dem File editor Add-on, eine neuen YAML-Datei, wir z.B. ecovacs.yaml, mit folgendem Inhalt. XYZ müsst ihr natürlich durch den Namen eures Roboters ergänzen und auch die Räume im Template Abschnitt anpassen.

script:
  deebot_clean:
    description: Start a deebot cleaning task
    variables:
      queue: input_text.deebot_XYZ_queue
      vacuum_bot: vacuum.XYZ
    sequence:
      - alias: Get room numbers
        variables:
          # See for appending to list
          # https://github.com/home-assistant/core/issues/33678#issuecomment-609424851
          rooms: >-
            {%- set queue_split = states(queue).split(",") -%}
            {%- set rooms = state_attr(vacuum_bot, "rooms")-%}
            {%- set data = namespace(rooms=[]) -%}
            {%- for room_name in queue_split -%}
              {%- set data.rooms = data.rooms + [rooms[room_name]] -%}
            {%- endfor -%}
            {{ data.rooms | join(",") }}
      - alias: Send cleaning job to vacuum
        service: vacuum.send_command
        data:
          entity_id: "{{ vacuum_bot }}"
          command: spot_area
          params:
            rooms: "{{ rooms }}"
            cleanings: 1
  deebot_room_queue:
    description: Add/Remove a room from the queue
    fields:
      queue:
        description: The queue variable
        example: input_text.deebot_XYZ_queue
      room:
        description: Room, which should be removed or added
        example: kitchen
    sequence:
      - service: input_text.set_value
        target:
          entity_id: "{{ queue }}"
        data:
          value: >-
            {%- set queue_state = states(queue) -%}
            {%- set queue_split = queue_state.split(",") -%}
            {%- if queue_state | length == 0 -%}
              {{ room }}
            {%- elif room in queue_split -%}
              {{ queue_split | reject("eq", room) | list | join(",")}}
            {%- else -%}
              {{ (queue_split + [room]) | join(",") }}
            {%- endif -%}
automation:
  - alias: Staubsauger Zimmer resetieren
    trigger:
      - platform: event
        event_type: deebot_cleaning_job
        event_data:
          status: finished
    - platform: state
      entity_id:
        - vacuum.XYZ
      to: docked
    condition: []
    action:
    - alias: Reset room queue
      service: input_text.set_value
      target:
        entity_id: input_text.deebot_XYZ_queue
      data:
        value: ""
    mode: single
recorder:
  exclude:
    entities:
      - input_text.deebot_XYZ_queue
      - script.deebot_room_queue
    entity_globs:
      - sensor.deebot_*_queue_*

input_text:
  deebot_XYZ_queue:
    name: XYZ Raum Reihenfolge
    max: 255 # Current max limit. See https://www.home-assistant.io/integrations/input_text/#max
# Room name comes from the integration to match attribute names		
template:
  unique_id: deebot_XYZ_queue
  trigger:
    - platform: state
      entity_id: input_text.deebot_XYZ_queue
  sensor:
    # Add for each room the following. Change room_name accordingly
    - unique_id: deebot_susi_queue_living_room
      name: deebot_XYZ_queue_living_room
      # room_name must match the room name provided by the vacuum
      state: >
        {% set room_name = "living_room" %}
        {% set queue = trigger.to_state.state.split(",") %}
        {{ queue.index(room_name)+1 if room_name in queue else 0 }}
    - unique_id: deebot_XYZ_queue_kitchen
      name: deebot_XYZ_queue_kitchen
      # room_name must match the room name provided by the vacuum
      state: >
        {% set room_name = "kitchen" %}
        {% set queue = trigger.to_state.state.split(",") %}
        {{ queue.index(room_name)+1 if room_name in queue else 0 }}
    - unique_id: deebot_XYZ_queue_corridor
      name: deebot_XYZ_queue_corridor
      # room_name must match the room name provided by the vacuum
      state: >
        {% set room_name = "corridor" %}
        {% set queue = trigger.to_state.state.split(",") %}
        {{ queue.index(room_name)+1 if room_name in queue else 0 }}
    - unique_id: deebot_XYZ_queue_bedroom
      name: deebot_XYZ_queue_bedroom
      # room_name must match the room name provided by the vacuum
      state: >
        {% set room_name = "bedroom" %}
        {% set queue = trigger.to_state.state.split(",") %}
        {{ queue.index(room_name)+1 if room_name in queue else 0 }}
    - unique_id: deebot_XYZ_queue_bathroom
      name: deebot_XYZ_queue_bathroom
      # room_name must match the room name provided by the vacuum
      state: >
        {% set room_name = "bathroom" %}
        {% set queue = trigger.to_state.state.split(",") %}
        {{ queue.index(room_name)+1 if room_name in queue else 0 }}
    - unique_id: deebot_XYZ_queue_storeroom
      name: deebot_XYZ_queue_storeroom
      # room_name must match the room name provided by the vacuum
      state: >
        {% set room_name = "storeroom" %}
        {% set queue = trigger.to_state.state.split(",") %}
        {{ queue.index(room_name)+1 if room_name in queue else 0 }}
    - unique_id: deebot_XYZ_queue_kids_room
      name: deebot_XYZ_queue_kids_room
      # room_name must match the room name provided by the vacuum
      state: >
        {% set room_name = "kids_room" %}
        {% set queue = trigger.to_state.state.split(",") %}
        {{ queue.index(room_name)+1 if room_name in queue else 0 }}
ecovacs.yaml

Anschließend über die Entwicklertools die Konfiguration prüfen und HA neu starten. Somit habt ihr einen Großteil der Konfiguration in einer Datei und überladet euch nicht eure configuration.yaml.

Deebot UI Konfiguration

Folgender Block kommt in eure RAW-Datei. Diese findet ihr, wenn ihr eure Dashbaord bearbeitet. Fügt den Block einfach ans Ende an, vergesst aber nicht den Namen eures Roboters zu ändern.

button_card_templates:
  vacuum_service:
    color: var(--text-color)
    entity: vacuum.XYZ 
    tap_action:
      action: call-service
      service_data:
        entity_id: vacuum.XYZ
    lock:
      enabled: |
        [[[ return variables.enabled ]]]
      exemptions: []
    styles:
      card:
        - height: 80px
      lock:
        - color: var(--primary-text-color)
    state:
      - operator: template
        value: |
          [[[ return variables.enabled ]]]
        styles:
          card:
            - color: var(--disabled-text-color)
  vacuum_room:
    color: var(--text-color)
    variables:
      # change me
      lock_enabled: >
        [[[ return ['cleaning', 'paused'].includes(states['vacuum.XYZ'].state)
        ]]]
    state:
      - operator: template
        value: |
          [[[ return variables.lock_enabled && entity.state == 0 ]]]
        styles:
          card:
            - color: var(--disabled-text-color)
      - styles:
          card:
            - background-color: var(--primary-color)
        operator: ">="
        value: 1
    styles:
      card:
        - font-size: 12px
      grid:
        - position: relative
      custom_fields:
        order:
          - display: |
              [[[
                if (entity.state == "0")
                  return "none";
                return "block";
              ]]]
          - position: absolute
          - left: 5%
          - top: 5%
          - height: 20px
          - width: 20px
          - font-size: 20px
          - font-weight: bold
          - line-height: 20px
    custom_fields:
      order: |
        [[[ return entity.state ]]]
    tap_action:
      action: call-service
      service: script.deebot_room_queue
      service_data:
        queue: input_text.deebot_XYZ_queue
    lock:
      enabled: |
        [[[ return variables.lock_enabled ]]]
      exemptions: []

Jetzt kommt die Konfiguration der eigentlichen Karte. Den markierten Bereich müsst ihr an eure Gegebenheiten, also an eurem Räume, anpassen. In entity und room müsst ihr die Namen aus eurem Deebot übernehmen. Je nach Integration (HACS oder Core) müsst ihr auch die Namen der Entity-IDs in der Vacuum-Card anpassen (hauptburste, lebensdauer_der_hauptburste)

type: vertical-stack
cards:
  - type: custom:vacuum-card
    entity: vacuum.XYZ
    stats:
      default:
        - entity_id: sensor.XYZ_lebensdauer_der_hauptburste
          unit: '%'
          subtitle: Hauptbürste
        - entity_id: sensor.XYZ_lebensdauer_der_seitenbursten
          unit: '%'
          subtitle: Seitenbürsten
        - entity_id: sensor.XYZ_lebensdauer_des_filters
          unit: '%'
          subtitle: Filter
      cleaning:
        - entity_id: sensor.XYZ_flache_gereinigt
          unit: 
          subtitle: Geputzte Fläche
        - entity_id: sensor.XYZ_reinigungsdauer
          unit: Minuten
          subtitle: Reinigungsdauer
    show_status: true
    show_toolbar: false
    compact_view: false
  - type: custom:button-card
    color: auto-no-temperature
    name: Räume zum Putzen auswählen
    styles:
      card:
        - font-size: 18px
        - height: 30px
      name:
        - color: var(--primary-color)
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        template: vacuum_room
        entity: sensor.deebot_XYZ_queue_living_room
        icon: mdi:sofa
        name: Wohnzimmer
        tap_action:
          service_data:
            room: living_room
      - type: custom:button-card
        template: vacuum_room
        entity: sensor.deebot_XYZ_queue_kitchen
        icon: mdi:stove
        name: Küche
        tap_action:
          service_data:
            room: kitchen
      - type: custom:button-card
        template: vacuum_room
        entity: sensor.deebot_XYZ_queue_corridor
        icon: mdi:shoe-print
        name: Flur
        tap_action:
          service_data:
            room: corridor
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        template: vacuum_room
        entity: sensor.deebot_XYZ_queue_bedroom
        icon: mdi:bed-king
        name: Schlafzimmer
        tap_action:
          service_data:
            room: bedroom
      - type: custom:button-card
        template: vacuum_room
        entity: sensor.deebot_XYZ_queue_bathroom
        icon: mdi:shower
        name: Badezimmer
        tap_action:
          service_data:
            room: bathroom
      - type: custom:button-card
        template: vacuum_room
        entity: sensor.deebot_XYZ_queue_storeroom
        icon: mdi:locker-multiple
        name: Abstellkammer
        tap_action:
          service_data:
            room: storeroom
      - type: custom:button-card
        template: vacuum_room
        entity: sensor.deebot_XYZ_queue_kids_room
        icon: mdi:teddy-bear
        name: Kinderzimmer
        tap_action:
          service_data:
            room: kids_room
  - type: horizontal-stack
    cards:
      - type: conditional
        conditions:
          - entity: vacuum.XYZ
            state_not: cleaning
          - entity: vacuum.XYZ
            state_not: paused
        card:
          type: custom:button-card
          template: vacuum_service
          icon: mdi:play
          name: Start
          tap_action:
            action: call-service
            service: script.deebot_clean
          variables:
            enabled: |
              [[[ 
                return ((!states['input_text.deebot_XYZ_queue'].state || 
                    states['input_text.deebot_XYZ_queue'].state.length === 0)
                    && ['docked', 'idle', 'error', 'returning'].includes(entity.state))
              ]]]
      - type: conditional
        conditions:
          - entity: vacuum.XYZ
            state: cleaning
        card:
          type: custom:button-card
          color: auto
          icon: mdi:pause
          name: Pause
          tap_action:
            action: call-service
            service: vacuum.pause
            service_data:
              entity_id: vacuum.XYZ
          styles:
            card:
              - height: 80px
              - background-color: var(-color)
      - type: conditional
        conditions:
          - entity: vacuum.XYZ
            state: paused
        card:
          type: custom:button-card
          color: auto
          icon: mdi:play-pause
          name: Weiter
          tap_action:
            action: call-service
            service: vacuum.start
            service_data:
              entity_id: vacuum.XYZ
          styles:
            card:
              - height: 80px
              - background-color: var(-color)
      - type: custom:button-card
        template: vacuum_service
        icon: mdi:stop
        name: Stop
        tap_action:
          service: vacuum.stop
        variables:
          enabled: |
            [[[ 
              return !(['cleaning', 'paused', 'returning'].includes(entity.state))
            ]]]
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        template: vacuum_service
        icon: mdi:home-map-marker
        name: Zurück zur Ladestation
        tap_action:
          service: vacuum.return_to_base
        variables:
          enabled: |
            [[[ 
              return ['docked', 'returning'].includes(entity.state)
            ]]]
      - type: custom:button-card
        color: auto
        icon: mdi:map-marker
        name: Lokalisieren
        tap_action:
          action: call-service
          service: vacuum.locate
          service_data:
            entity_id: vacuum.XYZ
        styles:
          card:
            - height: 80px
            - background-color: var(-color)
  - show_state: false
    show_name: false
    camera_view: auto
    type: picture-entity
    tap_action:
      action: none
    hold_action:
      action: none
    entity: image.XYZ_karte

Anschließend erhaltet ihr eine schöne Karte, mit der ihr euren Robot steuern könnt.

Nun habt ihr die Möglichkeit nacheinander die Räume auszuwählen und somit eine Reinigungs-Plan festzulegen.

Wie immer seid ihr aber in eurer eigenen Gestaltung frei und könnt euren Bot nun ganz nach eurem Geschmack in eure Dashbaords integrieren.

Die Anzeige der Produkte wurde mit dem affiliate-toolkit WordPress Plugin umgesetzt.

13 Gedanken zu „Deebot in Home Assistant einbinden“

  1. Hallo,

    erstaml, vielen Dank für die tolle Anleitung. Ich bin relativ neu in der HA-Welt. Habe deine Aneleitung umgesetzt. Aber irgendwie zeigt er bei der Card-Erstellung bei den Raumsymbolen im Hintergund der Symbole ein „un“ an. Die Buttons funktionieren auch nicht. Wo könnte der Fehler liegen?

    Vielen Dank

    Antworten
      • Ahh!!
        Genau da lieht wohl der Fehler. Die Automation ist rot. Folgender Fehler beim Anklicken der Automation:

        Auslöser: expected dict for dictionary value @ data[‚event_data‘]
        Aktionen: extra keys not allowed @ data[0][‚target‘][‚data‘

        Ist das ein EInrückfehler?

        Antworten
        • Vermutlich.

          So sieht es in meiner automations.yaml aus:

          - id: 8ccaa637746c4d5f89f84e6ac73ffdab
          alias: Staubsauger Zimmer resetieren
          trigger:
          - platform: event
          event_type: deebot_cleaning_job
          event_data:
          status: finished
          - platform: device
          device_id: 6f63acd89301096af4a754dfe232fed1
          domain: vacuum
          entity_id: 0db40db6e4c1c22df5f5e15ff2a9a756
          type: docked
          condition: []
          action:
          - alias: Reset room queue
          service: input_text.set_value
          target:
          entity_id: input_text.deebot_uschi_queue
          data:
          value: ''
          mode: single

          Leider ist das mit der FOrmatierung ein Krampf, hat dir das auch per Mail geschickt.

          Antworten
  2. Moin Björn,

    sehr schön erklärt, funktioniert auch super auf meinem Dashboard. Vielen Dank.

    Ich habe vor Wochen mal mit Dwain’s Dashboard herumgespielt, und hier scheint der Karten Code nicht zu funktionieren. Entweder meckert er über die button-card oder über vacuum-room im Code. Ich habe im github ein Issue dazu erstellt, doch leider befriedigt mich Dwains antwort nicht wirklich, da es ja nur ein button-card template zu installieren gibt.
    https://github.com/dwainscheeren/dwains-lovelace-dashboard/issues/786

    Hast du einen flotten Tipp wie man das Problem umgehen könnte? Screenshot findest du im github issue.

    Vielen Dank und Gruß

    Sebastian

    Antworten

Schreibe einen Kommentar