Geöffnete Fenster inkl. Öffnungszeiten / Makros und deren zentrale Wiederverwendbarkeit machen Templating effizienter

Ich hatte bisher wenig mit Makros probiert, sah auch hier im Forum kaum etwas, einmal ein Beispiel von @Osorkon. Heute las ich etwas Doku und stieß auf HA Update 2024.3.

Dort steht man kann Markos auch als Datei in /config/custom_templates/ ablegen, später laden und die darin enthaltenen Funktionen überall in jedem Jinja Code verwenden kann. Das geht in Richtung Helfer nur weiter. Ich übergebe einer zentral verfügbaren Funktion einen Wert, diese verarbeitet diese nach irgendeiner Logik und gibt mir den neuen Wert zurück. Will ich später die Logik anpassen, so muß ich das nur an einer Stelle (im Makro) tun.

Ich bin begeistert. :slight_smile:

Hier ein Beispiel an einem Fenster inklusive Öffnungszeit in min, h oder Tagen.

  1. Unter /config/custom_templates/ habe ich eine Datei mit dem Namen macros.jinja. Diese enthält folgenden Jinja Code.
{% macro macro_timediff_now_last_changed(entity_id) %}
{# 
Ermittelt den Zeitunterschied des Sensors zu now() und gibt diesen in Minuten, Stunden oder Tagen zurück
#}
  {%- set time_diff = (now() - states[entity_id].last_changed).total_seconds() %}
  {% if time_diff < 3600 -%}
    {% set time = (time_diff / 60) | round(0) ~ ' min' -%}
  {% elif time_diff < 86400 -%}
    {% set time = (time_diff / 3600) | round(0) ~ ' h' -%}
  {% else -%}
      {% set time = (time_diff / 86400) | round(0) ~ ' Tage' -%}
  {% endif -%}
{{ time }}
{% endmacro %}

{% macro answer_question(entity_id) %}
{# Test aus Doku: Ist die Lampe an oder nicht?#}
Is the {{ state_attr(entity_id, 'friendly_name') }} on?
{{ (states(entity_id) == 'on') | iif('Yes', 'No') }}!
{% endmacro %}

Das Makro “answer_question” aus der Doku führe ich hier nur auf, um zu zeigen, daß mehrere Makros in einer Datei gespeichert (und später abgerufen) werden können.

  1. Jetzt kann ich in jedem Template Sensor, jeder Markdown Karte bzw. überall wo Jinja ausgeführt wird, auf dieses Makro zugreifen.

Beispiel Fenster Gästezimmer und eine Lampe:
Jede Entity, die ein last_changed anbietet, ist möglich.

{%- from 'macros.jinja' import macro_timediff_now_last_changed as macro_get_time -%}
Gästezimmer: {{ macro_get_time('binary_sensor.aqara_fenstersensor_mitte_gaeste_contact') | trim }}
Licht: {{ macro_get_time('light.sternlampe') | trim }}

fenster

Man kann das auch in einem Template Sensor aufrufen. Ich habe einen, der mir die Namen der offenen Fenster ermittelt und dahinter in Klammern die Zeit. Letzteres wird über obiges Makro ermittelt.

fenster1

Viel Spaß beim Probieren

EDIT
Ein HA Neustart ist nötig nach jeder Makro Änderung.

6 „Gefällt mir“

Angeregt durch diesen schönen “Fenster auf/zu seit Code” in einer Mushroom-template-card wollte ich wissen, ob man hier auch über das obige Makro die Seit-Abfrage zentralisieren könnte und ja es geht.

Screenshot 2024-12-24 092144

Hier der Code der ersten Karte

type: custom:mushroom-template-card
primary: Kühlschrank ist seit
secondary: >-
  {% set fenster_entity = 'binary_sensor.aqara_unten_sensor_kuehlschrank_tuer_contact' %}
  {%- from 'macros.jinja' import macro_timediff_now_last_changed as macro_get_time -%}
  {% set status = states(fenster_entity) %}
  {# Setzt voraus, dass Makro wie oben hinterlegt wurde #}
  {% set seit = macro_get_time(fenster_entity) | trim %}
  {% if status == "on" %}
    {{ seit }} geöffnet
  {% elif status == "off" %}
    {{ seit }} geschlossen
  {% else %}
    Fenster Sensor nicht verfügbar
  {% endif %}
icon: >-
  {% set fenster_entity = 'binary_sensor.aqara_unten_sensor_kuehlschrank_tuer_contact' %}
  {% if states(fenster_entity) == "off" %}
    mdi:window-closed
  {% else %}
    mdi:window-open
  {% endif %}
icon_color: >-
  {% set fenster_entity = 'binary_sensor.aqara_unten_sensor_kuehlschrank_tuer_contact' %}
  {{ 'green' if states(fenster_entity) == 'off' else 'red' }}
entity: "{{ fenster_entity }}"

Alternativ könnte natürlich den Code des Autors in jede Fenster/Tür Karte packen und den Entity Namen anpassen und es wird funktionieren!
Alternativ kann man das Makro im Code übernehmen und bei irgendeiner späteren Änderung der Seit-Abfrage braucht man nur einmal das Makro ändern.

3 „Gefällt mir“

Witzig, das Thema “Funktionen” hat mich zu diesem Forum gebracht. War meine erste Frage. Finde es trotzdem, dass es funktioniert, immer noch ziemlich aufwändig.

Du warst einfach zu schnell mit Deiner 2023 Frage :grinning: Die Makros wurden erst 2024 eingeführt.

Kann so nicht stimmen, weil ich habe meine schon Ende 2023 geschrieben. Da waren es halt nur “macro”, sehe aber sonst keinen Unterschied

2025-02-24 13-29-33

Aufruf wie folgt…

{% from 'thermometer.jinja' import format_entity %} {{format_entity('sensor.bt_sauna_humidity',  'sensor.bt_sauna_batterie', true) }} 

Leider geht es nicht so einfach wie Meine_Funktion( ‘sensor.bt_sauna_humidity’, ‘sensor.bt_sauna_batterie’, true ) beim Aufrufen.

Hi,

sehr interessant. Nur wo find eich die /config/custom_templates/? Danke

2025-02-24 16-55-04

Die musst Du dann selber programmieren und als .JINJA ablegen. Dies war mein erster Versuch…

{% macro format_entity(entity_id) %}
{{ state_attr(entity_id, 'friendly_name') }} - {{ states(entity_id) }}
{% endmacro %}
1 „Gefällt mir“

Also über den File editor neue Ordner anlegen ist ja nicht das problem aber diese .jinja als datei anlegen verstehe ich irgendwie nicht. Dachte, man kopiert nur den Code rechts dann ein…

Du musst den Code selber schreiben, ist ja sehr individuell was jeder möchte. Natürlich kannst Du fertigen Code nehmen, wenn er für Dich passt. Einfach mit dem Editor Deiner Wahl die entsprechende Datei erstellen.

1 „Gefällt mir“

Ok also die Datei dann einfach da reinkopieren? Danke

Kann man eigentlich einem Macro diverse Variablen übergeben?
bzw. aus einem Macro mehr als eine Variable zurückerhalten?
Danke