Du willst in einem Template die Temperatur deines Thermostats auslesen, nimmst states() und bekommst als Ergebnis: heat. Keine Zahl, kein Grad. Hängst du noch ein float dran, gibt es eine Fehlermeldung.
Das Thermostat ist nicht kaputt. Der Wert steckt nur an einer anderen Stelle, nämlich in einem Attribut. In diesem Beitrag zeige ich dir, wie du Attribute findest, sicher ausliest und welche Stolperfallen dabei lauern.
Alles aus diesem Beitrag zeige ich auch im Video:
Das ist der dritte Teil meiner Reihe zu Stolpersteinen bei Templates in Home Assistant. Die ersten beiden Teile drehen sich um typische Template-Fehler und um das Glätten von Sensordaten. Du brauchst sie für diesen Beitrag nicht, an zwei Stellen verweise ich aber darauf.
State oder Attribut?
Jede Entität in Home Assistant hat genau einen State. Das ist ihr Hauptwert. Bei einem Temperatursensor ist das die Temperatur. Bei einem Thermostat ist es der Modus, also zum Beispiel heat, auto oder off.
Alles andere steckt in den Attributen: die aktuelle Raumtemperatur, die Zieltemperatur oder die Information, ob gerade geheizt wird.
Welche Attribute eine Entität hat, siehst du in den Werkzeugen im Reiter Zustände. Dort suchst du die Entität und findest daneben alle Attribute mit ihren aktuellen Werten.
Achte genau auf die Schreibweise. current_temperature wird klein und mit Unterstrich geschrieben. Ein falscher Buchstabe, und Home Assistant findet nichts.
Im Template-Editor (Werkzeuge, Reiter Template) sieht der Unterschied so aus:
{{ states('climate.thermostat_esstisch') }}
{# Ergebnis: heat #}
{{ states('climate.thermostat_esstisch') | float }}
{# Ergebnis: Fehlermeldung, float hat keinen Standardwert #}
{{ state_attr('climate.thermostat_esstisch', 'current_temperature') }}
{# Ergebnis: 21 #}
state_attr() bekommt zwei Angaben: zuerst die Entität, dann den Namen des Attributs.
Die Entitäten in den Beispielen stammen aus meinem System. Für deine Instanz musst du sie anpassen. Die Beispiele sind bewusst einfach gehalten, es geht ums Prinzip.
state_attr() richtig absichern
Auch state_attr() kann ins Leere greifen. Gibt es die Entität oder das Attribut nicht, kommt None zurück. Es gibt keine Fehlermeldung und keinen Hinweis, sondern einfach nichts.
{{ state_attr('climate.thermostat_esstisch', 'current_temperatur') }}
{# Ergebnis: None (Tippfehler im Attributnamen) #}
{{ state_attr('climate.thermostat_esstisch', 'current_temperatur') | float(0) }}
{# Ergebnis: 0.0 #}
Rechnest du mit None weiter, landest du bei genau den Fehlern aus dem ersten Teil der Reihe. Die Lösung ist dieselbe: float mit einem Standardwert fängt das ab.
Vorsicht beim Filter default
Viele greifen hier zum Filter default. Der hat aber einen Haken. Er greift normalerweise nur, wenn ein Wert gar nicht definiert ist. None gilt aber als definiert. Erst mit true als zweitem Parameter ersetzt default auch None.
{{ state_attr('climate.thermostat_esstisch', 'current_temperatur') | default(0) }}
{# Ergebnis: None, default greift hier nicht #}
{{ state_attr('climate.thermostat_esstisch', 'current_temperatur') | default(0, true) }}
{# Ergebnis: 0 #}
Text oder Zahl?
Noch ein Unterschied, der gern übersehen wird: states() liefert immer Text, auch wenn eine Zahl dasteht. state_attr() liefert den Wert so, wie er gespeichert ist. Bei der Temperatur ist das bereits eine echte Zahl.
{{ states('sensor.gw1100a_outdoor_temperature') is string }}
{# Ergebnis: True #}
{{ state_attr('climate.thermostat_esstisch', 'current_temperature') is number }}
{# Ergebnis: True #}
Wenn ein Attribut leer ist
Ein Attribut kann vorhanden und trotzdem leer sein. Ein gutes Beispiel ist die Helligkeit einer Lampe. Bei eingeschaltetem Licht steht brightness bei meinem Deckenfluter auf 153. Das ist ein Wert zwischen 0 und 255, mit dem kaum jemand etwas anfangen kann. Mit remap aus dem zweiten Teil der Reihe rechnest du ihn in Prozent um:
{{ state_attr('light.deckenfluter_wohnzimmer', 'brightness') }}
{# Ergebnis: 153 (an) bzw. None (aus) #}
{{ state_attr('light.deckenfluter_wohnzimmer', 'brightness')
| float(0) | remap(0, 255, 0, 100) | round(0) | int }}
{# Ergebnis: 60 (an) bzw. 0 (aus) #}
Schaltest du die Lampe aus, steht brightness weiterhin in der Attributliste. Dahinter steht aber null, und state_attr() liefert None.
Bei einer ausgeschalteten Lampe denkt man schnell an 0 Prozent. Das klingt logisch, ist aber falsch. Null Prozent wäre eine Zahl. Die Lampe sagt nicht null, sie sagt gar nichts. Deshalb steht im Template wieder float mit Standardwert. So wird aus nichts eine 0, und die Rechnung läuft weiter.
Listen in Attributen
Manche Attribute enthalten nicht einen Wert, sondern mehrere. rgb_color besteht zum Beispiel aus drei Zahlen für Rot, Grün und Blau. Einen einzelnen Wert holst du mit eckigen Klammern und der Position. Gezählt wird ab 0: Position 0 ist Rot, 1 ist Grün und 2 ist Blau.
{{ state_attr('light.deckenfluter_wohnzimmer', 'rgb_color') }}
{# Ergebnis: drei Werte für Rot, Grün und Blau bzw. None #}
{{ state_attr('light.deckenfluter_wohnzimmer', 'rgb_color')[0] }}
{# Ergebnis: 255 (an), bei ausgeschalteter Lampe kein brauchbares Ergebnis #}
Eine Randnotiz: Mein Deckenfluter läuft im Modus für Farbtemperatur und liefert trotzdem einen RGB-Wert. Home Assistant rechnet ihn einfach mit aus. Verlass dich also nicht darauf, dass rgb_color nur bei farbigem Licht gefüllt ist.
Ist die Lampe aus, ist auch rgb_color wieder None. Und aus nichts kannst du keine Position herausziehen. Deshalb prüfst du vorher, ob überhaupt ein Wert da ist:
{% set farbe = state_attr('light.deckenfluter_wohnzimmer', 'rgb_color') %}
{{ farbe[0] if farbe is not none else 'Licht aus' }}
{# Ergebnis: 255 bzw. Licht aus #}
Ein eigener Sensor für die Helligkeit
Soll die Helligkeit in Prozent dauerhaft verfügbar sein, etwa für Dashboards, Automationen oder den Verlauf, legst du einen Template-Sensor an. In der configuration.yaml sieht das so aus:
template:
- sensor:
- name: "Deckenfluter Wohnzimmer Helligkeit"
unique_id: deckenfluter_wohnzimmer_helligkeit_prozent
unit_of_measurement: "%"
state: >
{{ state_attr('light.deckenfluter_wohnzimmer', 'brightness')
| float(0) | remap(0, 255, 0, 100) | round(0) | int }}
Danach startest du Home Assistant neu. Gibt es in deiner Konfiguration schon einen Abschnitt template:, reicht es, die Template-Entitäten in den Entwicklerwerkzeugen neu zu laden.
Ohne YAML geht es auch: Unter Einstellungen → Geräte & Dienste → Helfer erstellst du einen neuen Helfer, wählst Template und dann Sensor. Das Template kommt in das Feld für den Zustand.
is_state_attr(): Prüfen statt auslesen
Oft willst du gar keinen Wert auslesen, sondern nur wissen, ob etwas stimmt. Heizt das Thermostat gerade? Dafür gibt es is_state_attr(). Du gibst die Entität, das Attribut und den erwarteten Wert an und bekommst true oder false zurück.
{{ is_state_attr('climate.thermostat_esstisch', 'hvac_action', 'heating') }}
{# Ergebnis: False (idle) bzw. True (heating) #}
Fehlt das Attribut, liefert is_state_attr() einfach false. Es gibt kein None und keinen Fehler. Genau deshalb eignet sich die Funktion gut als Bedingung in einer Automation:
conditions:
- condition: template
value_template: >
{{ is_state_attr('climate.thermostat_esstisch', 'hvac_action', 'heating') }}
Die Automation läuft dann nur weiter, wenn das Thermostat tatsächlich heizt.
Kurz zusammengefasst
states()liefert den Hauptwert einer Entität, und zwar immer als Text.- Weitere Werte stecken in Attributen. Du findest sie in den Entwicklerwerkzeugen unter Zustände.
state_attr()liefert den Wert in seinem echten Typ oderNone, wenn nichts da ist.- Sichere
Nonemitfloat(0)oderdefault(0, true)ab.default(0)allein reicht nicht. - Attribute können vorhanden und trotzdem leer sein, zum Beispiel bei einer ausgeschalteten Lampe.
- Bei Listen wie
rgb_colorerst prüfen, dann per Position zugreifen. is_state_attr()liefert immertrueoderfalseund eignet sich daher gut für Bedingungen.



