Matze's Snippet-Bereich (Templates & Frontend-Markdown)

Hallo zusammen, ich möchte euch in diesem Thread eine große Auswahl an Snippets, Templates für die configurator.yaml und einige optimierte Funktionen vorstellen, die ich ohne Addons/HACS erreicht habe. Ich arbeite nur mit der mitgelieferten Lösung und einigen Integrationen, die bereits enthalten und aktiviert sind.

Ich werde diesen ersten Beitrag nach und nach füllen und versuchen, die Skripte und Funktionen gut zu erklären.

Ich beginne mit einer schnellen und übersichtlichen Informationsebene im Frontend. Jeder von euch kennt das Problem im Frontend… Man verwendet Kacheln, man verwendet sicherlich viele Kacheln (Simon z.B. im Video mit So gehen Home Assistant Dashboards 2024 (Tile Card Style))… Aber bei so vielen Kacheln fehlt einfach eine kleine Infozentrale mit wichtigen Informationen kurz und knapp am Anfang. Zuerst habe ich mir überlegt welche Informationen mir und meiner Familie wichtig waren:

  • kleiner Gruß - nur ein Gimmick
  • Unwetterwarnungen des DWD (mit Warnstufen in verschiedenen Farben)
  • Läuft die Waschmaschine oder ein anderes Gerät und wie lange schon?
  • Wann kommt die Müllabfuhr? (relativ einfach ohne spezielle HACS-Integration)
  • Ist der Wasserstand in der Zisterne sehr niedrig? Kurzinformation bei weniger als 27
  • Wasserdruck der Gasheizung zu niedrig
  • Wasserzählerproblem beim Auslesen mit ESP32-CAM

Um all diese Informationen zusammenzufassen, habe ich mich intensiv mit der bereits vorhandenen Markdown-Card beschäftigt, die hier gut erklärt ist: Markdown card - Home Assistant - Sie bietet eine Vielzahl von Möglichkeiten, die auch spezielle Abfragen und Scripte direkt ausführen.

Somit beginnt meine erste Card mit:

type: markdown
content: >-

und alles andere, was man in die Karte eintragen kann, werde ich jetzt einzeln erläutern und darstellen:

Der Welcome-Snippet in Markdown:

{%- set hour = as_timestamp(now()) | timestamp_custom('%H') | int -%}{%- set greeting = 
"Gute Nacht" if hour >= 22 else "Guten Morgen" if hour < 10 else "Guten Vormittag" if hour < 12 else
"Guten Nachmittag" if hour < 18 else "Guten Abend" -%}{{ greeting }}, {{ user }}
---------

DWD-Mitteilung-Snippet in Markdown

Dazu benötigt man die Integration Deutscher Wetterdienst (DWD) Weather Warnings - Home Assistant - Man hat hier zwei Entitäten - Einmal die “kommenden Wetterwarnungen” und die “aktuellen Wetterwarnungen” - Da ich nur mit aktuellen Informationen bedient werden möchte, verwende ich nur die aktuellen Wetterwarnungen und habe die Entität umbenannt in sensor.dwd.

Weitere Besonderheiten dieses Snippets:

  • Es werden maximal 3 Wetterwarnungen gleichzeitig angezeigt.
  • Die Farbe/Hervorhebung der Karte passt sich der Intensität der Wetterwarnung an:
  • Es zeigt an, wie lange die Warnung noch andauert. Es arbeitet korrekt mit Datum und Uhrzeit.
{% set dwdstate = states('sensor.dwd') %}{% if dwdstate == "unavailable" %}{% else
%}{% set dwdcount = state_attr('sensor.dwd', 'warning_count') | int %}{% if dwdcount >= 1 
%}<ha-alert alert-type="{% if dwdstate | int == 4 %}error{% elif dwdstate | int == 3 %}error{% elif dwdstate | int == 2 %}error{% elif dwdstate | int == 1 %}warning{% endif %}" title="Wetterwarnung (DWD)">{% 
if dwdcount >= 1 %}{% set dwdwarn1 = state_attr('sensor.dwd', 'warning_1_level') | int %}{% 
set dwdtime1 = state_attr('sensor.dwd', 'warning_1_end').timestamp() | timestamp_custom('%d') | int - now().timestamp() | timestamp_custom('%d') | int %}{{ {
0: 'Information vor', 
1: 'Warnung vor', 
2: 'Warnung vor markantem', 
3: 'Unwetterwarnung vor', 
4: 'Achtung! Extremem Unwetter -'}.get(dwdwarn1) }} {{ 
state_attr('sensor.dwd', 'warning_1_name') }} bis {% if dwdtime1 == 0 %}{% elif dwdtime1 == 1 %} morgen um {% elif dwdtime1 >= 2 %} {{ 
state_attr('sensor.dwd', 'warning_1_end').timestamp() | timestamp_custom('%d.%m') }} um {% endif %}{{ 
state_attr('sensor.dwd', 'warning_1_end').timestamp() | timestamp_custom('%H:%M&nbsp;Uhr') }}. {% endif %}{% 
if dwdcount >= 2 %}{% set dwdwarn2 = state_attr('sensor.dwd', 'warning_2_level') | int %}{% 
set dwdtime2 = state_attr('sensor.dwd', 'warning_2_end').timestamp() | timestamp_custom('%d') | int - now().timestamp() | timestamp_custom('%d') | int %}{{ {
0: 'Information vor', 
1: 'Warnung vor', 
2: 'Warnung vor markantem', 
3: 'Unwetterwarnung vor', 
4: 'Achtung! Extremem Unwetter -'}.get(dwdwarn2) }} {{ 
state_attr('sensor.dwd', 'warning_2_name') }} bis {% if dwdtime2 == 0 %}{% elif dwdtime2 == 1 %} morgen um {% elif dwdtime2 >= 2 %} {{ 
state_attr('sensor.dwd', 'warning_2_end').timestamp() | timestamp_custom('%d.%m') }} um {% endif %}{{ 
state_attr('sensor.dwd', 'warning_2_end').timestamp() | timestamp_custom('%H:%M&nbsp;Uhr') }}. {% endif %}{% 
if dwdcount >= 3 %}{% set dwdwarn3 = state_attr('sensor.dwd', 'warning_3_level') | int %}{% 
set dwdtime3 = state_attr('sensor.dwd', 'warning_3_end').timestamp() | timestamp_custom('%d') | int - now().timestamp() | timestamp_custom('%d') | int %}{{ {
0: ' Information vor', 
1: ' Warnung vor', 
2: ' Warnung vor markantem', 
3: ' Unwetterwarnung vor', 
4: ' Achtung! Extremem Unwetter -'}.get(dwdwarn3) }} {{ 
state_attr('sensor.dwd', 'warning_3_name') }} bis {% if dwdtime3 == 0 %}{% elif dwdtime3 == 1 %} morgen um {% elif dwdtime3 >= 2 %} {{ 
state_attr('sensor.dwd', 'warning_3_end').timestamp() | timestamp_custom('%d.%m') }} um {% endif %}{{ 
state_attr('sensor.dwd', 'warning_3_end').timestamp() | timestamp_custom('%H:%M&nbsp;Uhr') }}. {% endif %}<a href="https://www.dwd.de/DE/wetter/warnungen_gemeinden/warnWetter_node.html?ort=xxx">Weitere Informationen</a></ha-alert>{% endif %}{% endif %}

Abfalltonnen-Snippet in Markdown

Vorabinfo und Vorbereitungen zuvor:
Hier ist die Besonderheit, dass über die Konfiguration ein Kalender (caldav) eingebunden wird. Die Datenpflege mache ich selbst und trage die Daten am liebsten jedes Jahr selbst ein. Das dauert bei mir maximal eine halbe Stunde und geht relativ schnell. Ich habe den Anbieter Apple iCloud verwendet und die Kalendereinträge nach Restmülltonne, Papiertonne und Gelbe Tonne aufgeteilt (Biotonne für mich deaktiviert, da ich selber kompostiere).

In configuration.yaml einbinden: (Nur als Beispiel)

  - platform: caldav
    username: xxx
    password: xxx
    url: https://caldav.icloud.com
    days: 30
    custom_calendars:
      - name: "Abfuhrtage Restabfalltonne"
        calendar: Abfuhrtage BS
        search: "Restabfalltonne"
      - name: "Abfuhrtage Papiertonne"
        calendar: Abfuhrtage BS
        search: "Papiertonne"
#      - name: "Abfuhrtage Biotonne"
#        calendar: Abfuhrtage BS
#        search: "Biotonne"
      - name: "Abfuhrtage Gelbe Tonne"
        calendar: Abfuhrtage BS
        search: "Gelbe Tonne"

Somit haben wir 3 Entitäten, die jetzt für unsere Anzeige dienen:

  • calendar.abfuhrtage_bs_abfuhrtage_gelbe_tonne
  • calendar.abfuhrtage_bs_abfuhrtage_restabfalltonne
  • calendar.abfuhrtage_bs_abfuhrtage_papiertonne

Besonderheiten:

  • Zeigt Symbole an (farbige Tonnen - Tonne offen und geschlossen, für heute)
  • Anzeige nur für heute, morgen und übermorgen
  • Sehr gut optimierter Code

Jetzt zum Snippet für das Frontend:

{% set muellrest = state_attr('calendar.abfuhrtage_bs_abfuhrtage_restabfalltonne', 'start_time') | as_datetime | as_local - today_at() %}
{% set muellgelb = state_attr('calendar.abfuhrtage_bs_abfuhrtage_gelbe_tonne', 'start_time') | as_datetime | as_local - today_at() %}
{% set muellpapier = state_attr('calendar.abfuhrtage_bs_abfuhrtage_papiertonne', 'start_time') | as_datetime | as_local - today_at() %}
{% if muellrest.days <= 2 or muellgelb.days <= 2 or muellpapier.days <= 2 %}<ha-alert title="Abfalltonnen">{% if muellrest.days <= 2 %}{{ {
0: '<font color=#4D4D4D><ha-icon icon=mdi:delete-empty></ha-icon></font> Restabfalltonne wird heute geleert.<br>', 
1: '<font color=#4D4D4D><ha-icon icon=mdi:delete></ha-icon></font> Restabfalltonne wird morgen geleert.<br>', 
2: '<font color=#4D4D4D><ha-icon icon=mdi:delete></ha-icon></font> Restabfalltonne wird übermorgen geleert.<br>'}.get(muellrest.days, '') }}{% endif %}{% if muellgelb.days <= 2 %}{{ {
0: '<font color=#FFA500><ha-icon icon=mdi:delete-empty></ha-icon></font> Gelbe Tonne wird heute geleert.<br>', 
1: '<font color=#FFA500><ha-icon icon=mdi:delete></ha-icon></font> Gelbe Tonne wird morgen geleert.<br>', 
2: '<font color=#FFA500><ha-icon icon=mdi:delete></ha-icon></font> Gelbe Tonne wird übermorgen geleert.<br>'}.get(muellgelb.days, '') }}{% endif %}{% if muellpapier.days <= 2 %}{{ {
0: '<font color=#00008B><ha-icon icon=mdi:delete-empty></ha-icon></font> Papiertonne wird heute geleert.<br>', 
1: '<font color=#00008B><ha-icon icon=mdi:delete></ha-icon></font> Papiertonne wird morgen geleert.<br>', 
2: '<font color=#00008B><ha-icon icon=mdi:delete></ha-icon></font> Papiertonne wird übermorgen geleert.<br>'}.get(muellpapier.days, '') }}{% endif %}</ha-alert>{% endif %}

Entitäten-Status-Snippet in Markdown

Es gibt ja ein paar Infos, wie die Waschmaschine oder andere Werte, die einem wichtig sind. Hier poste ich mal ohne große Erklärung meine Snippets für die Entitätsabfrage über Attribute oder über State. Die Besonderheit ist immer die Dauer des zuletzt beibehaltenen Zustandes der Entität.

{% if is_state('binary_sensor.badventilator_status', 'on') %}<ha-alert>Der <b>Badventilator</b> läuft gerade {{ "seit " ~  relative_time(states.binary_sensor.badventilator_status.last_changed) | replace("seconds", "Sekunden")| replace("second", "Sekunde")| replace("minutes", "Minuten") | replace("minute", "Minute")| replace("hours", "Stunden")| replace("hour", "Stunde")| replace("days", "Tage") | replace("day", "Tag")}}.</ha-alert>{% endif 
%}{% if is_state('binary_sensor.dehydrator_status', 'on') %}<ha-alert>Der <b>Dehydrator</b> läuft gerade {{ "seit " ~  relative_time(states.binary_sensor.dehydrator_status.last_changed) | replace("seconds", "Sekunden")| replace("second", "Sekunde")| replace("minutes", "Minuten") | replace("minute", "Minute")| replace("hours", "Stunden")| replace("hour", "Stunde")| replace("days", "Tage") | replace("day", "Tag")}}.</ha-alert>{% endif 
%}{% if is_state('binary_sensor.wasserverbrauch_problem', 'on') %}<ha-alert alert-type="error">Die <b>Wasseruhrmessung</b> hat ein Problem. http://192.168.1.31/</ha-alert>{% endif 
%}{% if is_state('sensor.backofen_mit_mikrowelle_state', 'Run') %}<ha-alert>Der <b>Backofen</b> läuft gerade {{ "seit " ~  relative_time(states.sensor.backofen_mit_mikrowelle_state.last_changed) | replace("seconds", "Sekunden")| replace("second", "Sekunde")| replace("minutes", "Minuten") | replace("minute", "Minute")| replace("hours", "Stunden")| replace("hour", "Stunde")| replace("days", "Tage") | replace("day", "Tag")}}.</ha-alert>{% endif 
%}{% if is_state('sensor.geschirrspueler_state', 'Run') %}<ha-alert>Der <b>Geschirrspüler</b> läuft gerade {{ "seit " ~  relative_time(states.sensor.geschirrspueler_state.last_changed) | replace("seconds", "Sekunden")| replace("second", "Sekunde")| replace("minutes", "Minuten") | replace("minute", "Minute")| replace("hours", "Stunden")| replace("hour", "Stunde")| replace("days", "Tage") | replace("day", "Tag")}}.</ha-alert>{% endif 
%}{% if is_state('binary_sensor.waschmaschine_status', 'on') %}<ha-alert>Die <b>Waschmaschine</b> läuft gerade {{ "seit " ~  relative_time(states.binary_sensor.waschmaschine_status.last_changed) | replace("seconds", "Sekunden")| replace("second", "Sekunde")| replace("minutes", "Minuten") | replace("minute", "Minute")| replace("hours", "Stunden")| replace("hour", "Stunde")| replace("days", "Tage") | replace("day", "Tag")}}.</ha-alert>{% endif 
%}{% if is_state('binary_sensor.trockner_status', 'on') %}<ha-alert>Der <b>Trockner</b> läuft gerade {{ "seit " ~  relative_time(states.binary_sensor.trockner_status.last_changed) | replace("seconds", "Sekunden")| replace("second", "Sekunde")| replace("minutes", "Minuten") | replace("minute", "Minute")| replace("hours", "Stunden")| replace("hour", "Stunde")| replace("days", "Tage") | replace("day", "Tag")}}.</ha-alert>{% endif 
%}{% if states('sensor.zisterne_volume')|int < 27 %}<ha-alert alert-type="error">In der Zisterne sind noch {{ states('sensor.zisterne_water') }} l Wasser!</ha-alert>{% endif 
%}{% if states('sensor.vaillant_waterpressure')|int > 2.0 %}<ha-alert alert-type="error">Der Wasserdruck der Gastherme liegt bei {{ states('sensor.vaillant_waterpressure') }} bar!</ha-alert>{% endif %}

Batterie-Status-Snippet in Markdown

Für mich war es sehr wichtig, eine einfache und gute Darstellung von schwachen Batterien in meinem Smart Home zu haben. Die Herausforderung war jedoch, kein HACS-Frontend-Skript zu verwenden, das mir alle Entitäten mit Batterien herausfiltern kann, um dies darzustellen. Die neue Filterfunktion in Home Assistant erwartet jedoch eine Eingabe jeder einzelnen Entität, also habe ich einen guten Weg gefunden, alle Batterieentitäten automatisch herauszufiltern und korrekt darzustellen, wenn der Wert unter 30% oder “low” oder unerreichbar ist.

In configuration.yaml einbinden:

template:
  - sensor:
    - name: "Batteryalert"
      unique_id: "battery_alert"
      state: >
        {% set ns = namespace(below=[]) %}{% for s in states.sensor if 'battery' in s.entity_id and s.attributes.device_class == 'battery' %}
          {% if s.state == "unavailable" or s.state == "unknown" or s.state == "off" or s.state|int < 30 %}{% set ns.below = ns.below + [ s ] %}{% endif %}
        {% endfor %}
        {{ ns.below | count }} 
      attributes:
        battery_low: >
          {% set ns = namespace(below=[]) %}{% for s in states.sensor if 'battery' in s.entity_id and s.attributes.device_class == 'battery' %}
            {% if s.state == "unavailable" or s.state == "unknown" or s.state == "off" or s.state|int < 30 %}{% set ns.below = ns.below + [ s.name ~ ' (' ~ (s.state|int if s.state | regex_match('^[0-9]+$') else s.state) ~ ('%' if s.state | regex_match('^[0-9]+$') else '') ~ ')'] %}{% endif %}
          {% endfor %}
          {{ ns.below | join(', ') }}

Es wird eine neue Entität (sensor.battery_alert) erzeugt, der die Menge an unter 30% oder low oder nicht erreichbar als Zahl ausgibt und unter Attribute den Entitätsname und den Status anzeigt.

type: conditional
conditions:
  - condition: numeric_state
    entity: sensor.battery_alert
    above: 0
card:
  type: markdown
  content: |-
    <ha-alert alert-type="info" title="Batteriestatus">
    {{ 
    state_attr('sensor.battery_alert', 'battery_low') }}
    </ha-alert>

Richtig lüfen & Schimmelbildung - Snippet in Markdown

Simon hat hier Mit Home Assistant richtig lüften und Schimmelbildung vorbeugen einen super Beitrag geleistet, wie man mit bestimmte Werte den absolute Luftfeuchtigkeit berechnen kann. Mit diesem Tutorial habe ich folgende Entitäten erzeugt:

  • sensor.kueche_absolute_humidity
  • sensor.duschzimmer_absolute_humidity
  • sensor.kellerflur_absolute_humidity
  • sensor.kinderzimmer_absolute_humidity
  • sensor.schlafzimmer_absolute_humidity
  • sensor.wohnzimmer_absolute_humidity

Somit habe ich mir folgendes Snippet erstellt:

type: conditional
conditions:
  - condition: or
    conditions:
      - condition: numeric_state
        entity: sensor.kueche_absolute_humidity
        above: 4.5
      - condition: numeric_state
        entity: sensor.duschzimmer_absolute_humidity
        above: 4.5
      - condition: numeric_state
        entity: sensor.kellerflur_absolute_humidity
        above: 4.5
      - condition: numeric_state
        entity: sensor.kinderzimmer_absolute_humidity
        above: 4.5
      - condition: numeric_state
        entity: sensor.schlafzimmer_absolute_humidity
        above: 4.5
      - condition: numeric_state
        entity: sensor.wohnzimmer_absolute_humidity
        above: 4.5
card:
  type: markdown
  content: >-
    {% set humidity = {

    'sensor.kueche_absolute_humidity': 'Küche',

    'sensor.duschzimmer_absolute_humidity': 'Duschzimmer',

    'sensor.kellerflur_absolute_humidity': 'Kellerflur',

    'sensor.kinderzimmer_absolute_humidity': 'Kinderzimmer',

    'sensor.schlafzimmer_absolute_humidity': 'Schlafzimmer',

    'sensor.wohnzimmer_absolute_humidity': 'Wohnzimmer'

    } %}<ha-alert alert-type="info" title="Zu starke Luftfeuchtigkeit">

    {% for entity, description in humidity.items() %}{% set humidity =
    states(entity) %}{% if 

    humidity | float >= 4.5 %}{{ description }} <small>{{ humidity }}
    g/m³</small>. {% endif %}{% endfor %}</ha-alert>

Türen und/oder Fenster offen - Markdown

Auch für Türen und Fenster habe ich die Informationen in einem Markdown abgelegt, da dies Platz spart und die Darstellung verschwindet, wenn keine Tür oder kein Fenster geöffnet ist.

type: conditional
conditions:
  - condition: or
    conditions:
      - condition: state
        entity: binary_sensor.heizraumfenster
        state: 'on'
      - condition: state
        entity: binary_sensor.duschzimmerfenster
        state: 'on'
      - condition: state
        entity: binary_sensor.gasestezimmerfenster
        state: 'on'
      - condition: state
        entity: binary_sensor.kizifenster_links
        state: 'on'
      - condition: state
        entity: binary_sensor.kizifenster_rechts
        state: 'on'
      - condition: state
        entity: binary_sensor.schlafzimmerfenster
        state: 'on'
      - condition: state
        entity: binary_sensor.arbeitszimmerfenster
        state: 'on'
      - condition: state
        entity: binary_sensor.kellertuer
        state: 'on'
      - condition: state
        entity: binary_sensor.terrassentuer
        state: 'on'
      - condition: state
        entity: binary_sensor.eingangstuer
        state: 'on'
      - condition: state
        entity: binary_sensor.heizraumtuer
        state: 'on'
card:
  type: markdown
  content: >-
    <ha-alert alert-type="info" title="Türen oder Fenster offen">{% 

    set windows = {

    'binary_sensor.heizraumfenster': 'Fenster im Heizungsraum',

    'binary_sensor.duschzimmerfenster': 'Fenster im Duschzimmer',

    'binary_sensor.gasestezimmerfenster': 'Fenster im Gästezimmer',

    'binary_sensor.kizifenster_links': 'Fenster im Kinderzimmer Links',

    'binary_sensor.kizifenster_rechts': 'Fenster im Kinderzimmer Rechts',

    'binary_sensor.schlafzimmerfenster': 'Fenster im Schlafzimmer',

    'binary_sensor.arbeitszimmerfenster': 'Fenster im Arbeitszimmer'} %}{% 

    set doors = {

    'binary_sensor.kellertuer': 'Kellertür',

    'binary_sensor.terrassentuer': 'Terrassentür',

    'binary_sensor.eingangstuer': 'Eingangstür',

    'binary_sensor.heizraumtuer': 'Tür im Heizungsraum'} %}{% for entity,
    description in windows.items() %}{% if 

    states(entity) == 'on' %}<ha-icon icon=mdi:window-open></ha-icon>{{
    description }}{% endif %}   {% endfor %}{% for entity, description in
    doors.items() %}{% if 

    states(entity) == 'on' %}<ha-icon icon=mdi:door-open></ha-icon>{{
    description }}{% endif %}   {% endfor %}

    </ha-alert>

Ein transparentes Hintergrundbild einbinden

Ansicht im Tagmodus


Ansicht im Nachtmodus

Ich mag es, wenn ich einen dezenten Hintergrund verwenden kann. Da ich auch Hell und Dunkel verwende, war das eine kleine Herausforderung - aber ich habe eine tolle Idee. Gestalte einen Hintergrund als Vektorgrafik mit nur 90% Transparenz über die gesamte Fläche. Das Ergebnis kann sich sehen lassen:

Ich habe meinen Hintergrund auf dieser genialen Seite generiert und als 200x200 SVG-Grafik erstellt. Wichtig ist, dass viel Transparenz verwendet wird.

Mit dem Datei-Editor legt ihr eure erzeugte “pattern.svg” im Ordner www/ ab.
Dann müsst ihr nur noch im RAW-Konfigurationseditor im Frontend eurer Home Assistant Seite einbinden: (vor “views:” einbinden)

background: center / cover no-repeat url("/local/pattern.svg") fixed

Über konstruktive Rückmeldungen oder Verbesserungen würde ich mich sehr freuen. Wenn ich mit Erweiterungen oder Korrekturen beginne, werde ich das auch hier in der Antwort korrigieren. Möglicherweise habe ich noch ein Problem mit dem Battery-Markdown.

11 „Gefällt mir“

Jaaaaaaaaaa … Danke, bin schon sehr gespannt

1 „Gefällt mir“