# Aktivierung von Home Assistant Szenen verfolgen - Part 2

> Teil 2 geht tiefer: mit dem trigger-basierten Template-Sensor auch das Deaktivieren von Szenen verfolgen und komplexere Szenarien in Home Assistant abbilden.

_Quelle: https://tbsch.de/post/2024-09-25-aktivierung-von-home-assistant-szenen-verfolgen-part-2/ · Stand: 2024-09-25_


Im [vorherigen Part](/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/) habe ich die Lichtszenen und deren Aktivierung beschrieben. Diesmal möchte ich tiefer in das Konzept des Trigger-basierten Template Sensors eintauchen und zeigen, wie dieser verwendet werden kann, um komplexere Szenarien in *Home Assistant* zu handhaben.

## Stand der Dinge

Rufen wir uns doch noch einmal eine verkürzte Version meines Sensors in Erinnerung:

```yaml
- trigger:
  - platform: homeassistant
    event: start
  - platform: event
    event_type: call_service
    event_data:
      domain: scene
      service: turn_on
  action:
    - variables:
        history: >
          {{ ... }}
  sensor:
    - name: scene_history_wohnzimmer
      unique_id: sensor_scene_history_wohnzimmer
      state: >
        {{ state_attr(history.wohnzimmer[0], "name") }}
      attributes:
        current: "{{ history.wohnzimmer[0] }}"
        history: "{{ history.wohnzimmer[1:] }}"
    # ... weitere Räume einfügen
```

Bei jedem Start von *Home Assistant* sowie jeder Aktivierung einer Szene wird die Aktualisierung des Trigger-basierten Template Sensors ausgelöst. Zuerst werden die **Actions** abgearbeitet, die in meinem Fall die Variable `history` mit Daten für alle Räume füllen. Danach werden die **Sensor**-Konfigurationen nacheinander ausgeführt.

<pre class="mermaid">
graph LR
A[/Trigger/] --&gt; B(Actions ausführen) --&gt; C[Sensoren aktualisieren]
</pre>


Während also der `scene_history_wohnzimmer` Sensor aktualisiert wird, steht die `history` Variable bereits mit allen Werten für das Wohnzimmer zur Verfügung. Diese Tatsache müssen wir im Kopf behalten, wenn wir solche Sensoren bauen. Das gilt natürlich auch für die Sensoren aller weiteren Räume, die wir an unseren Trigger anheften.

Und hier liegt ein kleines Detail versteckt: sobald die `history` Variable nach Auslösen des Triggers für alle Räume befüllt wird, kann sie nämlich die Sensordaten aller Räume aktualisieren - quasi in einem Durchlauf. Ja, so werden auch die Sensoren der Räume aktualisiert, in denen gerade keine Szene aktiviert wurde. Das werden wir aber später noch brauchen :grin:.

## Herausforderung

Wir haben es im [ersten Part](/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/) erfolgreich geschafft, dass der Name der zuletzt aktivierten Szene im *Scene-History*-Sensor gespeichert wird. Konkret stand der Sensor auf `Essen` und verhinderte somit, dass während des Essens die Wohnzimmer-Beleuchtung gedimmt wird, wenn jemand den Fernseher einschaltet.

Doch was passiert nun, wenn das Licht zwischenzeitlich ausgeschaltet wird? Du ahnst es vermutlich schon: Nichts. Die letzte Szene `Essen` wird so lange beibehalten, bis eine andere Szene im Wohnzimmer aktiviert wird. Und hier endet die Geschichte auch schon. Dies wird in anderen Situationen dafür sorgen, dass Automatisierungen eine Szene vermuten und entsprechend reagieren, obwohl sie mittlerweile gar nicht mehr aktiv sein könnte.

Um dieses Problem zu lösen, erweitern wir nun unseren *Scene-History*-Sensor um weitere Trigger und Attribute.

## Erweiterung des Sensors

Wir fügen einen weiteren **Trigger**, ein neues **Attribut** und ein **Makro**[^1] hinzu.

[^1]: Seit der Version **2023.4** unterstützt *Home Assistant* die Erstellung und Wiederverwendung eigener Makros, [siehe hier](https://www.home-assistant.io/blog/2023/04/05/release-20234/).

### Trigger

Ich teile den Triggern nun auch *Trigger-IDs* zu, um innerhalb des Trigger-basierten Template Sensors prüfen zu können, durch welches Ereignis er eigentlich aktualisiert wird. Entitäten wie `light.wohnzimmer_lights` gibt es bei mir für jeden Raum, sie gruppieren sämtliche Lampen innerhalb eines Raumes. Das ermöglicht mir die extrem bequeme Abfrage des Beleuchtungsstatus, oder eben alle Lichter gleichzeitig auszuschalten.

```yaml
- trigger:
  - platform: homeassistant
    event: start
  - platform: event
    event_type: call_service
    event_data:
      domain: scene
      service: turn_on
    id: scene_activated # das ist neu
  # und ein neuer Trigger
  - platform: state
    entity_id:
      - light.wohnzimmer_lights
    from: "on"
    to: "off"
    id: off_again
# ...
```

### Attribut

Statten wir den *Scene-History*-Sensor im Wohnzimmer nun mit dem Attribut aus, welches in Zukunft die Information vorhält, ob das Licht nach dem Aktivieren einer Szene wieder ausgeschaltet wurde.

```yaml
# ...
- name: scene_history_wohnzimmer
  unique_id: sensor_scene_history_wohnzimmer
  state: >
    {{ state_attr(history.wohnzimmer[0], "name") }}
  attributes:
    current: "{{ history.wohnzimmer[0] }}"
    history: "{{ history.wohnzimmer[1:] }}"
    # das kommt dazu
    off_again: >
      {% from "scenes.jinja" import get_off_again %}
      {{ get_off_again("wohnzimmer", trigger) }}
```

Ich habe mich für den Namen `off_again` entschieden. Das Template des Attributs importiert ein **Makro** und führt es dann aus. Damit ich das Template der Funktion `get_off_again` auch für andere Räume benutzen kann, ohne es immer wieder kopieren zu müssen, habe ich es in eben jenem Makro ausgelagert. Das ist übrigens der übliche Use-Case für Makros, falls du dich schon mal gefragt hast, wozu die eigentlich gut sein sollen :grin:.

An das **Makro** übergebe ich den gewünschten Raum und das gesamte `trigger` Objekt, welches von *Home Assistant* zur Verfügung gestellt wird. In diesem Objekt enthalten ist auch die Information, welcher Trigger ausgelöst wurde.

> [!tip]
> An dieser Stelle machen wir uns die Tatsache zu Nutze, dass beim Auslösen eines Triggers immer **State** und **Attribute** des Trigger-basierten Template Sensors aktualisiert werden. Das musst du dir stets im Hinterkopf behalten, denn auch unser **Makro** ist darauf ausgelegt.

### Makro

Um eigene **Makros** zu verwenden, erstelle im `config`-Ordner deiner *Home Assistant* Installation den Unterordner `custom_templates`. Hier legst du deine *.jinja*-Dateien ab. Ich habe mich für den Dateinamen `scenes.jinja` entschieden, einfach weil ich es vorteilhaft finde, Informationen thematisch zu strukturieren.

**Die Datei hat folgenden Inhalt:**

```jinja
{% macro get_off_again(area, trigger) %}
    {# eine Szene wurde aktiviert #}
    {% if trigger.id == "scene_activated" %}
        {% set areas = trigger.event.data.service_data.entity_id
                | map("area_id")
                | list %}
        {% if area in areas %}
            {% set return = "no" %}
        {% endif %}
    {# Lampen wurden ausgeschaltet #}
    {% elif trigger.id == "off_again" %}
        {% set areas = [area_id(trigger.entity_id)] %}
        {% if area in areas %}
            {% set return = "yes" %}
        {% endif %}
    {% endif %}

    {# Nichts von beidem #}
    {% if return is not defined %}
        {% set return = state_attr("sensor.scene_history_" + area, "off_again") %}
    {% endif %}

    {{ return }}
{% endmacro %}
```

#### Erläuterungen

Das **Makro** wird mit zwei Parametern aufgerufen. Dies ist einerseits `area`, die in meinem Beispiel ja auf `wohnzimmer` gesetzt ist. Andererseits das `trigger` Objekt von *Home Assistant*.

Wird **eine Szene aktiviert**, soll überprüft werden, ob die ausgelöste Szene im `wohnzimmer` ist. Falls ja, wird `off_again` auf *no* gesetzt. Dieselbe Logik wende ich an, wenn **Lampen ausgeschaltet** werden. Es wird überprüft, ob es sich um den gewünschten Raum handelt und falls ja, `off_again` auf *yes* gesetzt. Du hast richtig gemerkt: wir haben einen Schalter im klassischen Sinne gebaut, der entweder *an* oder *aus* ist. Macht bis hierher Sinn, oder?

Für den Fall, dass weder die aktivierte Szene, noch die ausgeschaltete Lampe aus dem `wohnzimmer` sind, wird einfach der aktuell eingestellte Wert übernommen. Warum das notwendig ist? Ich habe dir weiter oben einen brennenden Tipp dazu gegeben :sunglasses:.

Im letzten Schritt wird der Wert der Variable `return` nun zurückgegeben und in der Folge als `off_again` Attribut festgelegt.

## Abschlussarbeiten

Der *Scene-History*-Sensor kann nun nicht nur erfolgreich die zuletzt aktivierte Szene anzeigen, sondern stellt darüber hinaus auch ein Attribut bereit mit der Information, ob das Licht seit Aktivierung einer Szene wieder abgeschaltet wurde. Damit kann die in [Part 1](/post/2024-09-16-aktivierung-von-home-assistant-szenen-verfolgen-part-1/) aufgebaute Automatisierung nicht nur feststellen, ob die Szene `Essen` im Wohnzimmer zuletzt aktiviert wurde, sondern auch, ob das Licht seither wieder ausgeschaltet worden ist.

Sobald der Fernseher im Wohnzimmer eingeschaltet wird, überprüft die für das Dimmen verantwortliche Automatisierung in Zukunft nicht nur, ob der *Scene-History*-Sensor auf `Essen` steht, sondern auch, ob das Licht seither wieder abgeschaltet wurde.

```yaml
  - condition: not
    conditions:
      - condition: state
        entity_id: sensor.scene_history_wohnzimmer
        state: Essen
      - condition: state
        entity_id: sensor.scene_history_wohnzimmer
        attribute: off_again
        state: "yes"
```

Jetzt wird die Automatisierung wirklich zuverlässig laufen und das Licht nur im vorgesehenen Moment dimmen :grin:. Wenn du bessere Ideen zu einer möglichen Umsetzung hast, schreib mir gern. Mein Ziel war die Vermeidung der Erstellung von unzähligen *Helfern*.

> [!note]
> Der Trigger-basierte Template Sensor ist von mir so designt, dass einfach weitere Räume hinzugefügt werden können, ohne den ganzen Code immer wieder schreiben zu müssen. Das war auch notwendig, da ich die *Scene-History* in sechs verschiedenen Räumen verwende.

In einem der nächsten Beiträge zu *Home Assistant* werde ich darüber berichten, wie ich mit Hilfe der [Local calendar](https://www.home-assistant.io/integrations/local_calendar/), [To-do list](https://www.home-assistant.io/integrations/todo/) und [Roborock](https://www.home-assistant.io/integrations/roborock/) Integrations einen [interaktiven Reinigungsplan](/post/2026-05-31-interaktiver-reinigungsplan-mit-home-assistant/) erstellt habe.

---

Das Titel-/Hintergrundbild stammt von [Bilal Mansuri](https://unsplash.com/de/@itsbilalmn?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash) auf [Unsplash](https://unsplash.com/de/fotos/ein-zimmer-mit-einer-couch-und-einem-tv-EE0DOgXztcY?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash).

