Fehler in Template Sensor

Moin,
ich habe eine EcoWitt WS2910 Station mit einem WS69 7-in-1-Sensor in HA integriert. Die Werte kommen auch perfekt an.
Nun wollte ich die Anzeige der Windrichtung ein wenig aufhübschen, statt der Gradzahl soll dort eine Textangabe wie ‘N’ ‘SO’, etc. stehen.
Dazu habe ich in die configuration.yaml folgenden Code eingefügt, um einen template sensor zu definieren:

template:
  - sensor:
      - name: "Windrichtung"
        unit_of_measurement: ""
        state: >
          {% set direction = ['N', 'NNO','NO', 'ONO','O', 'OSO', 'SO', 'SSO', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'] %}
          {% set degree = states('sensor.ws2900_v2_02_06_wind_direction')|float %}
        
          {{ direction[ (( degree + 11.25 ) / 22.5 ) | int] }}

Wenn ich de den Sensor in einem neu angelegten Wetter-Dashboard einbinde, kommt nur die Meldung ‘Unavailable’ :see_no_evil_monkey:
Was habe ich falsch gemacht?

Anmerkung: Ich habe zwar diverse Jahrzehnte SW entwickelt, bin aber in Sachen YAML oder Python, etc. ein absoluter Neuling.
BTW: Gibt es irgendwo eine umfassende Syntax-Beschreibung von YAML im Zusammenhang mit HA?

Versuch es mal so

template:
  - sensor:
      - name: "Windrichtung"
        state: >-
          {% set direction = ['N','NNO','NO','ONO','O','OSO','SO','SSO','S','SSW','SW','WSW','W','WNW','NW','NNW','N'] %}
          {% set degree = states('sensor.ws2900_v2_02_06_wind_direction')|float(0) %}
          {{ direction[ ((degree + 11.25) / 22.5) | int ] }}

1 „Gefällt mir“

Das kannst du auch als Helfer in der GUI einrichten. Unter Geräte und Dienste einen template Helfer erstellen vom Typ Sensor.

Dort dann z.B.

{% set windrichtung2 = [
  'N',
  'NNO',
  'NO',
  'ONO',
  'O',
  'OSO',
  'SO',
  'SSO',
  'S',
  'SSW',
  'SW',
  'WSW',
  'W',
  'WNW',
  'NW',
  'NNW',
  'N'] %}
{% set winkel2 = states('sensor.gw1100a_wind_direction') | float(none) %}
{% if winkel2 is not none %}
  {{ windrichtung2[((winkel2 + 11.25) / 22.5) | int] }}
{% else %}
  {{ states('sensor.windrichtung2') if has_value('sensor.windrichtung2') else 'N/A' }}
{% endif %}

Du musst dann noch deinen Sensor einsetzen statt meinen.

In configuration.yaml musst du dafür nicht.

Ich habe auch mal getestet, funktioniert :smiley:

template:
  - sensor:
      - name: "Windrichtung"
        unit_of_measurement: ""
        state: >
          {% set direction = ['N', 'NNO', 'NO', 'ONO', 'O', 'OSO', 'SO', 'SSO', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'] %}
          {% set degree = states('sensor.gw1100a_wind_direction') | float(default=0) %}
          {{ direction[(((degree + 11.25) / 22.5) | int)] }}


1 „Gefällt mir“

Ich bedanke mich herzlich für die schnellen und kompetenten Antworten :smiling_face_with_sunglasses:
Mittlerweile tut der Sensor das, was er soll…

Was mir nicht klar ist:
In meiner Version ohne Defaultwert bei float() war die vom Außensensor gelieferte Windrichtung z.B. „80“, d.h. ein numerischer Wert — trotzdem schlug der Lookup im Direktion Array fehl.
Warum ändert sich das Verhalten des float Filters durch die Angabe des Defaults?

Warum der Default im float():

Der Sensor liefert womöglich nicht durchgehend Zahlen. (z. B. beim Neustart von Home Assistant, nach Updates, bei Verbindungsproblemen oder wenn der Sensor einfach aus Gründen kurzzeitig ausfällt) nimmt der Sensor-State den Wert unavailable oder unknown an.

  • Ohne Default-Wert in float() bricht die Template-Auswertung bei einem solchen Status-Wechsel ab oder wirft einen Fehler im Log.

  • Wenn das Template zu diesem Zeitpunkt fehlschlägt, liefert der gesamte Sensor oft temporär gar kein Ergebnis

Im else ist dann nur noch definiert wie sich die Ausgabe verhält wenn es sich nicht um eine Zahl handelt. Das Log wirft damit zumindest keine Fehler.

Warum dein Sensor unavailable war, kann ich dir nicht sagen. Sicher ist, das unavailable eben keine Zahl ist. Und damit könnte ich mir vorstellen das der Sensor abbricht. Ziemlich sicher findest du da auch Fehler im Log, die eventuell Aufschlussreich sind.

1 „Gefällt mir“

Danke, ich werde mir die Logs mal anschauen

Du kannst für den Fall den @Schlumperdix geschildert hat natürlich in Templates auch mit dem “availability” arbeiten z.B. prüfen mit “has_value” prüfen ob die Entität einen Wert hat.

z.B.

availability: "{{ has_value('sensor.ws2900_v2_02_06_wind_direction') }}"

Beide Lösungen sind gleich gut oder schlecht, oder anders formliert je nach Anwendungsfall ist das eine oder andere halt besser.
Wenn ich mir ne Lade- oder Entladeleistung anschauen und die Kurve als dutzenden Datenpunkten besteht die alle sagen wir ma so um die 1000-3000 pendeln, dann ist ne 0 (default) dazwischen natürlich blöd, oder zumindest blöder als einen Datenpunkt weniger.

Wenns nicht drauf ankommt also nur die Anzeige der Windrichtung ist’s vermutlich mit der 0 die praktikablere Lösung, denn wenn die Entität nur nach nem Neustand nicht da ist siehst du das ohnehin nicht in der Visualisierung.

Google einfach mal nach “home assistant availability”.

Speziell bei Templates in denen man numerische Divisionen macht hilfts halt wenig wenn man am Ende durch einen default 0 dividiert, denn auch das mündet natürlich in einem Fehlermeldung.
Beispiel für den TemplateEditor (Seit der akt. Version unter
Einstellungen>Werkzeuge>Template, früher uner Einstellungen>Entwicklerwerkzeuge>Template)

{% set sensorwert1 = 1 %}
{% set sensorwert2 = 0 | float(0) %}
{{ sensorwert1 / sensorwert2}}

endet nun mal ob mit oder ohne float(0) in einer division by zero :slight_smile:

2 „Gefällt mir“

Moin allerseits,

eure Unterstützung war wirklich toll und hat mir über einige Anfangshürden geholfen…

Trotzdem klappt es noch nicht (ganz) so, wie ich es mir vorgestellt hatte.
Unabhängig vom Stand der Windfahne liefert mein Template-Sensor immer nur den Wert “0” als Index in direction, es kommt daher immer “N” heraus.

Zum Debuggen habe ich einige Zwischenschritte eingefügt, um mir die Ergebnisse anzeigen zu lassen
Der aktuelle Code:

template:
  sensor:
    name: “Windrichtung”
    state: >-
      {% set direction = [ ‘N’, ‘NNO’, ‘NO’, ‘ONO’, ‘O’, ‘OSO’, ‘SO’, ‘SSO’, ‘S’, ‘SSW’, ‘SW’, ‘WSW’, ‘W’, ‘WNW’, ‘NW’, ‘NNW’, ‘N’ ] %}
      {% set degree = states ( ‘sensor.ws2900_v2_02_06_wind_direction’ ) | float(0) %}
      {% set sektor = ( degree + 11.25 ) / 22.5 | float(0) %}
      {% set sektorint = sektor | int(0) %}
      {{ degree  sektor  sektorint  direction [ sektorint ] }}

Nach dem Einfügen der letzten drei Zeilen erhalte ich beim Neustart von HA folgende Fehlermeldung:

Logger: homeassistant.config
Quelle: config.py:352
Erstmals aufgetreten: 13:07:02 (1 Vorkommnis)
Zuletzt protokolliert: 13:07:02

Invalid config for ‘template’ at configuration.yaml, line 18: invalid template (TemplateSyntaxError: expected token ‘end of print statement’, got ‘sektor’) for dictionary value ‘sensor->0->state’, got “{% set direction = [ ‘N’, ‘NNO’, ‘NO’, ‘ONO’, ‘O’, ‘OSO’, ‘SO’, ‘SSO’, ‘S’, ‘SSW’, ‘SW’, ‘WSW’, ‘W’, ‘WNW’, ‘NW’, ‘NNW’, ‘N’ ] %} {% set degree = states ( ‘sensor.ws2900_v2_02_06_wind_direction’ ) | float(0) %} {% set sektor = ( degree + 11.25 ) / 22.5 | float(0) %} {% set sektorint = sektor | int(0) %} {{ degree sektor sektorint direction [ sektorint ] }}”

Was genau will mir das sagen? Wo habe ich etwas falsch gemacht?

Eventuell so mal versuchen.

template:
  sensor:
    - name: "Windrichtung"
      state: >-
        {% set direction = [ 'N', 'NNO', 'NO', 'ONO', 'O', 'OSO', 'SO', 'SSO', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N' ] %}
        {% set degree = states('sensor.ws2900_v2_02_06_wind_direction') | float(0) %}
        {% set sektor = ((degree + 11.25) / 22.5) | int(0) %}
        {{ direction[sektor] }}

1 „Gefällt mir“

Tut mir leid, das funktioniert auch nicht… :pensive_face:

In der Variablen „sektor“ steht der korrekte Wert aber „direction [sektor]“ liefert immer „N“.

Kann ich die Elemente in der Liste nicht über die Position als Index, beginnend mit 0, ansprechen?

Teste mal meinen Sensor (der funktioniert bei mir hier), Deine Entität habe ich bereits eingetragen :wink:

- sensor:
    - name: "Windrichtung"
      unique_id: windrichtung
      state: >
        {% set src = states('sensor.ws2900_v2_02_06_wind_direction') %}
        {% if src in ['unavailable', 'unknown'] or not is_number(src) %}
          unknown
        {% else %}
          {% set directions = ['N', 'NNO', 'NO', 'ONO', 'O', 'OSO', 'SO', 'SSO', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'] %}
          {% set degree = src | float(0) %}
          {% set idx = (((degree + 11.25) / 22.5) | int) % 16 %}
          {{ directions[idx] }}
        {% endif %}
1 „Gefällt mir“

Besten Dank, so funktioniert es !

Da lernt ein alter Programmierer noch einiges über die syntaktischen Merkwürdigkeiten von YAML dazu…..

Bin auch kein Programmierer, lasse mir aber von AI/KI helfen :wink: