Mova Z60 Ultra: Automatische Reinigung nur bei Abwesenheit mit Nachhol-Erinnerung

Ich wollte meinen Mova Z60 nicht mehr über die Hersteller-App bedienen, weil mir diese auf Dauer einfach zu umständlich war. Deshalb habe ich die wichtigsten Einstellungen in meine simon42-Strategie übernommen. Auch die Reinigung selbst sollte über Home Assistant laufen und ein paar einfache Regeln bekommen.

Mein Saugroboter reinigt normalerweise montags, mittwochs und freitags um 09:30 Uhr. Da ich gelegentlich im Homeoffice arbeite und dann keine Lust auf die Geräuschkulisse habe, startet er nur, wenn Home Assistant mich als abwesend erkennt. Dafür nutze ich den Standort meines Smartphones.

Wurde eine Reinigung verpasst oder abgebrochen, erhalte ich am Folgetag um 09:30 Uhr eine Benachrichtigung auf dem Handy. Direkt darüber kann ich die Reinigung in einer Stunde starten, eine bestimmte Uhrzeit wie 15:00 Uhr eingeben oder sie überspringen. So muss ich weder die App öffnen noch später selbst daran denken.

Samstags erscheint die Erinnerung nur, wenn die Reinigung am Freitag nicht erfolgreich abgeschlossen wurde. Sonntags gibt es keine Erinnerung und keine automatische Reinigung.

Unten findet ihr die passende YAML mit Platzhaltern für eure eigenen Entity-IDs. Ich habe sie als Package in Home Assistant angelegt.

Bei Interesse kann ich auch noch meine Dashboard-Ansicht teilen. Die Dreame-Vacuum-Integration deckt zwar schon vieles gut ab, ich habe die wichtigsten Funktionen aber zusätzlich als einzelne Buttons eingebaut, damit ich deren App-Oberfläche nicht verwenden muss.

input_boolean:
  vacuum_nachholen:
    name: Saugroboter-Reinigung nachholen
    icon: mdi:calendar-clock

input_datetime:
  vacuum_nachholzeit:
    name: Nachholzeit
    has_date: true
    has_time: true
    icon: mdi:clock-edit-outline

script:
  vacuum_komplettreinigung:
    alias: Saugroboter – Komplettreinigung
    mode: single
    sequence:
      # Diese beiden Aktionen sind optional und müssen
      # an das eigene Modell angepasst werden.
      - action: select.select_option
        target:
          entity_id: select.DEIN_REINIGUNGSPROGRAMM
        data:
          option: routine_cleaning

      - action: select.select_option
        target:
          entity_id: select.DEIN_REINIGUNGSMODUS
        data:
          option: vacuum_and_mop

      - action: vacuum.start
        target:
          entity_id: vacuum.DEIN_SAUGROBOTER

automation:
  - id: vacuum_reinigung_bei_abwesenheit
    alias: Saugroboter – Reinigung bei Abwesenheit
    description: Reinigung am Montag, Mittwoch und Freitag, wenn niemand zu Hause ist.
    mode: single
    triggers:
      - trigger: time
        at: "09:30:00"

    conditions:
      - condition: time
        weekday:
          - mon
          - wed
          - fri

      - condition: state
        entity_id: person.DEINE_PERSON
        state: not_home

    actions:
      - action: script.vacuum_komplettreinigung

  - id: vacuum_erledigte_reinigung
    alias: Saugroboter – Nachholen nach erfolgreicher Reinigung beenden
    description: Entfernt eine geplante Nachholreinigung nach erfolgreicher Reinigung.
    mode: queued
    max: 5

    triggers:
      - trigger: state
        entity_id: sensor.DEIN_REINIGUNGSVERLAUF

    conditions:
      - condition: template
        value_template: >-
          {% set ns = namespace(timestamp=0, completed=false) %}
          {% for record in states.sensor.DEIN_REINIGUNGSVERLAUF.attributes.values() %}
            {% if record is mapping %}
              {% set ts = record.get('timestamp', 0) | int(0) %}
              {% if ts > ns.timestamp %}
                {% set ns.timestamp = ts %}
                {% set ns.completed = record.get('completed', false) %}
              {% endif %}
            {% endif %}
          {% endfor %}
          {{ ns.completed }}

    actions:
      - action: input_boolean.turn_off
        target:
          entity_id: input_boolean.vacuum_nachholen

      - action: notify.mobile_app_DEIN_HANDY
        data:
          message: clear_notification
          data:
            tag: vacuum_nachholen

  - id: vacuum_erinnerung
    alias: Saugroboter – Erinnerung an verpasste Reinigung
    description: Prüft am Folgetag, ob die geplante Reinigung durchgeführt wurde.
    mode: single

    triggers:
      - trigger: time
        at: "09:30:00"

    conditions:
      - condition: time
        weekday:
          - tue
          - thu
          - sat

      - condition: template
        value_template: >-
          {% set ns = namespace(last_completed=0) %}
          {% for record in states.sensor.DEIN_REINIGUNGSVERLAUF.attributes.values() %}
            {% if record is mapping and record.get('completed', false) %}
              {% set ns.last_completed = [
                ns.last_completed,
                record.get('timestamp', 0) | int(0)
              ] | max %}
            {% endif %}
          {% endfor %}
          {{ ns.last_completed == 0
             or ns.last_completed < as_timestamp(now() - timedelta(days=2)) }}

    actions:
      - action: notify.mobile_app_DEIN_HANDY
        data:
          title: Reinigung verpasst
          message: >-
            Der Saugroboter hat seit mindestens zwei Tagen nicht gereinigt.
            Wann soll die Reinigung nachgeholt werden?
          data:
            tag: vacuum_nachholen
            persistent: true
            actions:
              - action: VACUUM_IN_EINER_STUNDE
                title: In 1 Stunde

              - action: VACUUM_ZUR_UHRZEIT
                title: Uhrzeit eingeben
                behavior: textInput
                textInputButtonTitle: Planen
                textInputPlaceholder: "HH:MM, zum Beispiel 15:00"

              - action: VACUUM_UEBERSPRINGEN
                title: Überspringen

  - id: vacuum_benachrichtigung_verarbeiten
    alias: Saugroboter – Auswahl aus Benachrichtigung verarbeiten
    description: Plant oder verwirft die ausgewählte Nachholreinigung.
    mode: queued
    max: 5

    triggers:
      - trigger: event
        event_type: mobile_app_notification_action
        event_data:
          action: VACUUM_IN_EINER_STUNDE
        id: eine_stunde

      - trigger: event
        event_type: mobile_app_notification_action
        event_data:
          action: VACUUM_ZUR_UHRZEIT
        id: uhrzeit

      - trigger: event
        event_type: mobile_app_notification_action
        event_data:
          action: VACUUM_UEBERSPRINGEN
        id: ueberspringen

    actions:
      - choose:
          - conditions: "{{ trigger.id == 'eine_stunde' }}"
            sequence:
              - action: input_datetime.set_datetime
                target:
                  entity_id: input_datetime.vacuum_nachholzeit
                data:
                  timestamp: "{{ (now() + timedelta(hours=1)).timestamp() }}"

              - action: input_boolean.turn_on
                target:
                  entity_id: input_boolean.vacuum_nachholen

              - action: notify.mobile_app_DEIN_HANDY
                data:
                  title: Reinigung geplant
                  message: >-
                    Die Reinigung startet um
                    {{ (now() + timedelta(hours=1)).strftime('%H:%M') }} Uhr.
                  data:
                    tag: vacuum_nachholen

          - conditions: "{{ trigger.id == 'uhrzeit' }}"
            sequence:
              - variables:
                  eingabe: >-
                    {{ trigger.event.data.reply_text
                       | default('', true) | trim }}

              - choose:
                  - conditions: >-
                      {{ eingabe
                         | regex_match('^([01][0-9]|2[0-3]):[0-5][0-9]$') }}
                    sequence:
                      - variables:
                          zeitpunkt: >-
                            {% set zeit = as_timestamp(today_at(eingabe)) %}
                            {{ zeit if zeit > as_timestamp(now())
                               else zeit + 86400 }}

                      - action: input_datetime.set_datetime
                        target:
                          entity_id: input_datetime.vacuum_nachholzeit
                        data:
                          timestamp: "{{ zeitpunkt | float }}"

                      - action: input_boolean.turn_on
                        target:
                          entity_id: input_boolean.vacuum_nachholen

                      - action: notify.mobile_app_DEIN_HANDY
                        data:
                          title: Reinigung geplant
                          message: >-
                            Die Reinigung startet um
                            {{ zeitpunkt | float
                               | timestamp_custom('%H:%M', true) }} Uhr.
                          data:
                            tag: vacuum_nachholen

                default:
                  - action: notify.mobile_app_DEIN_HANDY
                    data:
                      title: Uhrzeit nicht erkannt
                      message: >-
                        Bitte die Uhrzeit im Format HH:MM eingeben,
                        zum Beispiel 15:00.
                      data:
                        tag: vacuum_nachholen
                        persistent: true
                        actions:
                          - action: VACUUM_IN_EINER_STUNDE
                            title: In 1 Stunde

                          - action: VACUUM_ZUR_UHRZEIT
                            title: Uhrzeit eingeben
                            behavior: textInput
                            textInputButtonTitle: Planen
                            textInputPlaceholder: "HH:MM, zum Beispiel 15:00"

                          - action: VACUUM_UEBERSPRINGEN
                            title: Überspringen

          - conditions: "{{ trigger.id == 'ueberspringen' }}"
            sequence:
              - action: input_boolean.turn_off
                target:
                  entity_id: input_boolean.vacuum_nachholen

              - action: notify.mobile_app_DEIN_HANDY
                data:
                  message: clear_notification
                  data:
                    tag: vacuum_nachholen

  - id: vacuum_nachholreinigung_starten
    alias: Saugroboter – Nachholreinigung starten
    description: Startet die Reinigung zur ausgewählten Zeit.
    mode: single

    triggers:
      - trigger: time
        at: input_datetime.vacuum_nachholzeit

    conditions:
      - condition: state
        entity_id: input_boolean.vacuum_nachholen
        state: "on"

    actions:
      - action: input_boolean.turn_off
        target:
          entity_id: input_boolean.vacuum_nachholen

      - action: script.vacuum_komplettreinigung

Ersetzt werden müssen:

  • vacuum.DEIN_SAUGROBOTER

  • person.DEINE_PERSON

  • sensor.DEIN_REINIGUNGSVERLAUF

  • notify.mobile_app_DEIN_HANDY

  • select.DEIN_REINIGUNGSPROGRAMM

  • select.DEIN_REINIGUNGSMODUS

Die beiden select-Aktionen sind gerätespezifisch. Falls euer Saugroboter diese Funktionen nicht anbietet, könnt ihr sie anpassen oder entfernen.

Ich habe noch einmal die conditions überarbeitet, da das wohl nicht so ganz durchdacht war. Ich hatte die die Reinigung grundsätzlich daran gebunden, dass mein Status “not_home" ist, jedoch ist das nicht der Status, den HA wirklich ausgibt - bei mir war zwischenzeitlich der Status auf work, unavailable oder unknown. Entsprechend habe ich dies noch einmal komplett umgedreht und gehe nun davon aus, dass der Staubsauger immer reinigt wenn irgendein Status außer “home" angezeigt wird.

Dafür einfach Zeile 48 in der ersten automation aus der obenstehenden yaml anpassen zu:

  - condition: not
    conditions:
      - condition: state
        entity_id: person.seolite
        state: home