Шаблонизация в Home Assistant: руководство по использованию Jinja2

ℹ️
Это перевод документации Home Assistant, выполненный средствами машинного перевода.

Шаблонизация — это продвинутая функция Home Assistant. Вам потребуется базовое понимание:

Шаблонизация — это мощная функция, которая позволяет вам управлять информацией, поступающей в систему и выходящей из нее. Она используется для:

Создание шаблонов

Шаблонизация в Home Assistant основана на движке шаблонов Jinja2. Это означает, что мы используем их синтаксис и делаем доступными некоторые пользовательские переменные Home Assistant для шаблонов во время их рендеринга. Jinja2 поддерживает широкий спектр операций:

Мы не будем рассматривать основы синтаксиса, так как Jinja2 отлично справляется с этим в своей документации по шаблонам.

Интерфейс Home Assistant имеет инструмент редактора шаблонов, который помогает разрабатывать и отлаживать шаблоны. Перейдите в Инструменты разработчика > Шаблоны, создайте шаблон в редакторе и проверьте результат справа.

Шаблоны могут быстро становиться большими. Чтобы сохранить ясность, рассмотрите использование многострочных строк YAML для определения ваших шаблонов:

script:
  msg_who_is_home:
    sequence:
      - action: notify.notify
        data:
          message: >
            {% if is_state('device_tracker.paulus', 'home') %}
              Ha, Paulus is home!
            {% else %}
              Paulus is at {{ states('device_tracker.paulus') }}.
            {% endif %}

Важные правила шаблонов

Есть несколько очень важных правил, которые нужно помнить при добавлении шаблонов в YAML:

  1. Вы должны заключать однострочные шаблоны в двойные (") или одинарные (') кавычки.
  2. Рекомендуется подготовиться к неопределенным переменным, используя if ... is not none или фильтр default, или оба.
  3. Рекомендуется при сравнении чисел преобразовывать число(а) в float или int с помощью соответствующего фильтра.
  4. Хотя фильтры float и int позволяют использовать значение по умолчанию, если преобразование не удалось, они не предоставляют возможности обработать неопределенные переменные.

Помните эти простые правила, чтобы избежать головной боли и бесконечных часов разочарования при использовании шаблонов автоматизации.

Включенные расширения Jinja

Jinja поддерживает набор языковых расширений, которые добавляют новые функции в язык. Чтобы улучшить опыт написания шаблонов Jinja, мы включили следующие расширения:

Повторное использование шаблонов

Вы можете создавать повторно используемые шаблоны Jinja, добавляя их в папку custom_templates в вашем каталоге конфигурации. Все файлы шаблонов должны иметь расширение .jinja и быть меньше 5 МБ. Шаблоны в этой папке будут загружены при запуске. Чтобы перезагрузить шаблоны без перезапуска Home Assistant, вызовите действие homeassistant.reload_custom_templates.

После загрузки шаблонов Jinja включает и импортирует будут работать, используя config/custom_templates в качестве базового каталога.

Например, вы можете определить макрос в шаблоне в config/custom_templates/formatter.jinja:

{% macro format_entity(entity_id) %}
{{ state_attr(entity_id, 'friendly_name') }} - {{ states(entity_id) }}
{% endmacro %}

В ваших автоматизациях вы можете повторно использовать этот макрос, импортировав его:

{% from 'formatter.jinja' import format_entity %}
{{ format_entity('sensor.temperature') }}

Расширения шаблонов Home Assistant

Расширения позволяют шаблонам получать доступ ко всем состояниям, специфичным для Home Assistant, и добавляют другие удобные функции и фильтры.

Ограниченные шаблоны

Шаблоны для некоторых триггеров, а также trigger_variables поддерживают только подмножество расширений шаблонов Home Assistant. Это подмножество называется "Ограниченные шаблоны".

This

Сущности, основанные на состоянии и триггерах, имеют специальную переменную шаблона this, доступную в их шаблонах и действиях. Подробнее и примеры см. в документации по интеграции шаблонов.

Состояния

Не поддерживается в ограниченных шаблонах.

  • Итерация по states будет возвращать каждый объект состояния.
  • Итерация по states.domain будет возвращать каждый объект состояния этого домена.
  • states.sensor.temperature возвращает объект состояния для sensor.temperature (избегайте этого, см. примечание ниже).
  • states также может использоваться как функция, states(entity_id, rounded=False, with_unit=False), которая возвращает строку состояния (не объект состояния) для данного объекта, unknown, если он не существует, и unavailable, если объект существует, но недоступен.
    • Необязательные аргументы rounded и with_unit управляют форматированием строк состояния датчиков, см. примеры ниже.
  • states.sensor.temperature.state_with_unit форматирует строку состояния так же, как если бы вызывалась states('sensor.temperature', rounded=True, with_unit=True).
  • is_state сравнивает состояние объекта с указанным состоянием или списком состояний и возвращает True или False. is_state('device_tracker.paulus', 'home') проверит, находится ли данный объект в указанном состоянии. is_state('device_tracker.paulus', ['home', 'work']) проверит, находится ли данный объект в любом из состояний в списке.
  • state_attr('device_tracker.paulus', 'battery') вернет значение атрибута или None, если он не существует.
  • is_state_attr('device_tracker.paulus', 'battery', 40) проверит, соответствует ли атрибут объекта указанному значению (в данном случае числовому). Обратите внимание, что атрибут может быть None, и если вы хотите проверить, является ли он None, вам нужно использовать state_attr('sensor.my_sensor', 'attr') is none или state_attr('sensor.my_sensor', 'attr') == None (обратите внимание на разницу в написании none в обоих вариантах).
  • has_value('sensor.my_sensor') проверит, не является ли объект неизвестным или недоступным. Может использоваться как фильтр или тест.

Предупреждение: Избегайте использования states.sensor.temperature.state, вместо этого используйте states('sensor.temperature'). Настоятельно рекомендуется использовать states(), is_state(), state_attr() и is_state_attr() как можно чаще, чтобы избежать ошибок и сообщений об ошибках, когда объект еще не готов (например, во время запуска Home Assistant).

Примеры состояний

Следующие два выражения дают одинаковый результат, если состояние существует. Второе выражение вызовет ошибку, если состояние не существует.

{{ states('device_tracker.paulus') }}
{{ states.device_tracker.paulus.state }}

Вывести список всех состояний датчиков:

{% for state in states.sensor %}
  {{ state.entity_id }}={{ state.state }},
{% endfor %}

Вывести список всех состояний датчиков, отсортированных по entity_id:

{% for state in states.sensor | sort(attribute='entity_id') %}
  {{ state.entity_id }}={{ state.state }},
{% endfor %}

Объекты, которые включены:

{{ ['light.kitchen', 'light.dining_room'] | select('is_state', 'on') | list }}

Другие примеры состояний:

{% if is_state('device_tracker.paulus', 'home') %}
  Ha, Paulus is home!
{% else %}
  Paulus is at {{ states('device_tracker.paulus') }}.
{% endif %}

# Проверка состояния датчика train_departure_time
{% if states('sensor.train_departure_time') in ("unavailable", "unknown") %}
  {{ ... }}

{% if has_value('sensor.train_departure_time') %}
  {{ ... }}

{% set state = states('sensor.temperature') %}{{ state | float + 1 if is_number(state) else "invalid temperature" }}

{% set state = states('sensor.temperature') %}{{ (state | float * 10) | round(2) if is_number(state)}}

{% set state = states('sensor.temperature') %}
{% if is_number(state) and state | float > 20 %}
  It is warm!
{% endif %}

{{ as_timestamp(states.binary_sensor.garage_door.last_changed) }}

{{ as_local(states.binary_sensor.garage_door.last_changed) }}

{{ as_timestamp(now()) - as_timestamp(states.binary_sensor.garage_door.last_changed) }}

{{ as_local(states.sensor.time.last_changed) }}

{{ states('sensor.expires') | as_datetime }}

# Создание списка состояний
{{ ['light.kitchen', 'light.dining_room'] | map('states') | list }}

Форматирование состояний датчиков

Примеры ниже показывают вывод датчика температуры с состоянием 20.001, единицей измерения °C и пользовательским округлением до 1 знака после запятой.

Следующий пример возвращает число 20.001:

{{ states('sensor.temperature') }}

Следующий пример возвращает строку "20.0 °C":

{{ states('sensor.temperature', with_unit=True) }}

Следующий пример возвращает строку "20.001 °C":

{{ states('sensor.temperature', with_unit=True, rounded=False) }}

Следующий пример возвращает число 20.0:

{{ states('sensor.temperature', rounded=True) }}

Следующий пример возвращает число 20.001:

{{ states.sensor.temperature.state }}

Следующий пример возвращает строку "20.0 °C":

{{ states.sensor.temperature.state_with_unit }}

Атрибуты

Не поддерживается в ограниченных шаблонах.

Вы можете вывести атрибут с помощью state_attr, если состояние определено.

Примеры атрибутов

{% if states.device_tracker.paulus %}
  {{ state_attr('device_tracker.paulus', 'battery') }}
{% else %}
  ??
{% endif %}

Строки:

{% set tracker_name = "paulus"%}

{% if states("device_tracker." + tracker_name) != "unknown" %}
  {{ state_attr("device_tracker." + tracker_name, "battery")}}
{% else %}
  ??
{% endif %}

Список дружественных имен:

{{ ['binary_sensor.garage_door', 'binary_sensor.front_door'] | map('state_attr', 'friendly_name') | list }}

Список светильников, которые включены с яркостью 255:

{{ ['light.kitchen', 'light.dining_room'] | select('is_state', 'on') | select('is_state_attr', 'brightness', 255) | list }}

Перевод состояния

Не поддерживается в ограниченных шаблонах.

Функция state_translated возвращает переведенное состояние объекта с использованием языка, настроенного в общих настройках.

Примеры перевода состояния

{{ states("sun.sun") }}             # below_horizon
{{ state_translated("sun.sun") }}   # Below horizon
{{ "sun.sun" | state_translated }}  # Below horizon
{{ states("binary_sensor.movement_backyard") }}             # on
{{ state_translated("binary_sensor.movement_backyard") }}   # Detected
{{ "binary_sensor.movement_backyard" | state_translated }}  # Detected

Работа с группами

Не поддерживается в ограниченных шаблонах.

Функция и фильтр expand могут использоваться для сортировки объектов и расширения групп. Она возвращает отсортированный массив объектов без дубликатов.

Примеры расширения

{% for tracker in expand('device_tracker.paulus', 'group.child_trackers') %}
  {{ state_attr(tracker.entity_id, 'battery') }}
  {%- if not loop.last %}, {% endif -%}
{% endfor %}

То же самое можно выразить как фильтр:

{{ expand(['device_tracker.paulus', 'group.child_trackers'])
  | selectattr("attributes.battery", 'defined')
  | join(', ', attribute="attributes.battery") }}
{% for energy in expand('group.energy_sensors') if is_number(energy.state) %}
  {{ energy.state }}
  {%- if not loop.last %}, {% endif -%}
{% endfor %}

То же самое можно выразить как тест:

{{ expand('group.energy_sensors')
  | selectattr("state", 'is_number') | join(', ') }}

Объекты

  • is_hidden_entity(entity_id) возвращает, скрыт ли объект. Также может использоваться как тест.

Примеры объектов

{{ area_entities('kitchen') | reject('is_hidden_entity') }} # Получает список видимых объектов в зоне кухни

Устройства

  • device_entities(device_id) возвращает список объектов, связанных с данным ID устройства. Также может использоваться как фильтр.
  • device_attr(device_or_entity_id, attr_name) возвращает значение attr_name для данного устройства или ID объекта. Также может использоваться как фильтр. Не поддерживается в ограниченных шаблонах.
  • is_device_attr(device_or_entity_id, attr_name, attr_value) возвращает, соответствует ли значение attr_name для данного устройства или ID объекта значению attr_value. Также может использоваться как тест. Не поддерживается в ограниченных шаблонах.
  • device_id(entity_id) возвращает ID устройства для данного ID объекта или имени устройства. Также может использоваться как фильтр.

Примеры устройств

{{ device_attr('deadbeefdeadbeefdeadbeefdeadbeef', 'manufacturer') }}  # Sony
{{ is_device_attr('deadbeefdeadbeefdeadbeefdeadbeef', 'manufacturer', 'Sony') }}  # true
{{ device_id('sensor.sony') }}  # deadbeefdeadbeefdeadbeefdeadbeef

Конфигурационные записи

  • config_entry_id(entity_id) возвращает ID конфигурационной записи для данного ID объекта. Также может использоваться как фильтр.
  • config_entry_attr(config_entry_id, attr) возвращает значение attr для конфигурационной записи данного ID объекта. Также может использоваться как фильтр. Допустимые атрибуты: domain, title, state, source, disabled_by. Не поддерживается в ограниченных шаблонах.

Примеры конфигурационных записей

{{ config_entry_id('sensor.sony') }}  # deadbeefdeadbeefdeadbeefdeadbeef
{{ config_entry_attr(config_entry_id('sensor.sony'), 'title') }}  # Sony Bravia TV

Этажи

  • floors() возвращает полный список ID этажей.
  • floor_id(lookup_value) возвращает ID этажа для данного ID устройства, ID объекта, ID зоны или имени зоны. Также может использоваться как фильтр.
  • floor_name(lookup_value) возвращает имя этажа для данного ID устройства, ID объекта, ID зоны или ID этажа. Также может использоваться как фильтр.
  • floor_areas(floor_name_or_id) возвращает список ID зон, связанных с данным ID этажа или именем этажа. Также может использоваться как фильтр.

Примеры этажей

{{ floors() }}  # ['floor_id']
{{ floor_id('First floor') }}  # 'first_floor'
{{ floor_id('my_device_id') }}  # 'second_floor'
{{ floor_id('sensor.sony') }}  # 'first_floor'
{{ floor_name('first_floor') }}  # 'First floor'
{{ floor_name('my_device_id') }}  # 'Second floor'
{{ floor_name('sensor.sony') }}  # 'First floor'
{{ floor_areas('first_floor') }}  # ['living_room', 'kitchen']

Зоны

  • areas() возвращает полный список ID зон.
  • area_id(lookup_value) возвращает ID зоны для данного ID устройства, ID объекта или имени зоны. Также может использоваться как фильтр.
  • area_name(lookup_value) возвращает имя зоны для данного ID устройства, ID объекта или ID зоны. Также может использоваться как фильтр.
  • area_entities(area_name_or_id) возвращает список ID объектов, связанных с данным ID зоны или именем зоны. Также может использоваться как фильтр.
  • area_devices(area_name_or_id) возвращает список ID устройств, связанных с данным ID зоны или именем зоны. Также может использоваться как фильтр.

Примеры зон

{{ areas() }}  # ['area_id']
{{ area_id('Living Room') }}  # 'deadbeefdeadbeefdeadbeefdeadbeef'
{{ area_id('my_device_id') }}  # 'deadbeefdeadbeefdeadbeefdeadbeef'
{{ area_id('sensor.sony') }}  # 'deadbeefdeadbeefdeadbeefdeadbeef'
{{ area_name('deadbeefdeadbeefdeadbeefdeadbeef') }}  # 'Living Room'
{{ area_name('my_device_id') }}  # 'Living Room'
{{ area_name('sensor.sony') }}  # 'Living Room'
{{ area_entities('deadbeefdeadbeefdeadbeefdeadbeef') }}  # ['sensor.sony']
{{ area_devices('Living Room') }}  # ['my_device_id']

Объекты для интеграции

  • integration_entities(integration) возвращает список объектов, связанных с данной интеграцией, например, hue или zwave_js.
  • integration_entities(config_entry_title) если у вас настроено несколько записей для интеграции, вы также можете использовать название, которое вы задали для интеграции, если хотите нацелиться на конкретную запись.

Если есть несколько записей с одинаковым названием, будут возвращены объекты для всех соответствующих записей, даже если записи относятся к разным интеграциям. Невозможно искать объекты для интеграции без названия.

Примеры интеграций

{{ integration_entities('hue') }}  # ['light.hue_light_upstairs', 'light.hue_light_downstairs']
{{ integration_entities('Hue bridge downstairs') }}  # ['light.hue_light_downstairs']

Метки

  • labels() возвращает полный список ID меток или те, которые относятся к данной ID зоны, ID устройства или ID объекта.
  • label_id(lookup_value) возвращает ID метки для данного имени метки.
  • label_name(lookup_value) возвращает имя метки для данного ID метки.
  • label_areas(label_name_or_id) возвращает список ID зон, связанных с данным ID метки или именем метки.
  • label_devices(label_name_or_id) возвращает список ID устройств, связанных с данным ID метки или именем метки.
  • label_entities(label_name_or_id) возвращает список ID объектов, связанных с данным ID метки или именем метки.

Каждая из функций меток также может использоваться как фильтр.

Примеры меток

{{ labels() }}  # ['christmas_decorations', 'energy_saver', 'security']
{{ labels("living_room") }}  # ['christmas_decorations', 'energy_saver']
{{ labels("my_device_id") }}  # ['security']
{{ labels("light.christmas_tree") }}  # ['christmas_decorations']
{{ label_id('Energy saver') }}  # 'energy_saver'
{{ label_name('energy_saver') }}  # 'Energy saver'
{{ label_areas('security') }}  # ['driveway', 'garden', 'porch']
{{ label_devices('energy_saver') }}  # ['deadbeefdeadbeefdeadbeefdeadbeef']
{{ label_entities('security') }}  # ['camera.driveway', 'binary_sensor.motion_garden', 'camera.porch']

Проблемы

  • issues() возвращает все открытые проблемы в виде отображения кортежей (домен, issue_id) на объект проблемы.
  • issue(domain, issue_id) возвращает конкретную проблему для указанного домена и issue_id.

Примеры проблем

{{ issues() }}  # { ("homeassistant", "deprecated_yaml_ping"): {...}, ("cloud", "legacy_subscription"): {...} }
{{ issue('homeassistant', 'python_version') }}  # {"breaks_in_ha_version": "2024.4", "domain": "homeassistant", "issue_id": "python_version", "is_persistent": False, ...}

Немедленное условие (iif)

Часто возникает необходимость условно вернуть значение на основе другого значения. Например, вернуть "Да" или "Нет", когда свет включен или выключен.

Это можно записать как:

{% if is_state('light.kitchen', 'on') %}
  Yes
{% else %}
  No
{% endif %}

Или используя более короткий синтаксис:

{{ 'Yes' if is_state('light.kitchen', 'on') else 'No' }}

Кроме того, вы можете использовать функцию/фильтр iif, который является немедленным условием.

Синтаксис: iif(condition, if_true, if_false, if_none)

iif возвращает значение if_true, если условие истинно, значение if_false, если оно ложно, и значение if_none, если оно None. Пустая строка, пустое отображение или пустой список считаются ложными, см. документацию Python для подробного объяснения.

if_true необязателен, если он опущен, возвращается True, если условие истинно. if_false необязателен, если он опущен, возвращается False, если условие ложно. if_none необязателен, если он опущен, возвращается значение if_false, если условие None.

Примеры использования iif:

{{ iif(is_state('light.kitchen', 'on'), 'Yes', 'No') }}

{{ is_state('light.kitchen', 'on') | iif('Yes', 'No') }}

{{ (states('light.kitchen') == 'on') | iif('Yes', 'No') }}

Предупреждение: Фильтр немедленного условия не выполняет короткое замыкание, как можно было бы ожидать от типичного условного оператора. Выражения if_true, if_false и if_none будут все вычислены, и фильтр просто вернет одно из результирующих значений. Это означает, что вы не можете использовать этот фильтр для предотвращения выполнения выражения, которое может привести к ошибке.

Например, если вы хотите выбрать поле из trigger в автоматизации на основе платформы, вы можете попробовать сделать такой шаблон: trigger.platform == 'event' | iif(trigger.event.data.message, trigger.to_state.state). Это не сработает, потому что оба выражения будут вычислены, и одно из них завершится ошибкой, так как поле не существует. Вместо этого вам нужно сделать так: trigger.event.data.message if trigger.platform == 'event' else trigger.to_state.state. Эта форма выражения выполняет короткое замыкание, поэтому если платформа event, выражение trigger.to_state.state никогда не будет вычислено и не вызовет ошибку.

Время

now(), time_since(), time_until(), today_at() и utcnow() не поддерживаются в ограниченных шаблонах.

  • now() возвращает объект datetime, представляющий текущее время в вашем часовом поясе.
    • Вы также можете использовать: now().second, now().minute, now().hour, now().day, now().month, now().year, now().weekday() и now().isoweekday() и другие атрибуты и функции datetime.
    • Использование now() приведет к обновлению шаблонов в начале каждой новой минуты.
  • utcnow() возвращает объект datetime текущего времени в часовом поясе UTC.
    • Для конкретных значений: utcnow().second, utcnow().minute, utcnow().hour, utcnow().day, utcnow().month, utcnow().year, utcnow().weekday() и utcnow().isoweekday().
    • Использование utcnow() приведет к обновлению шаблонов в начале каждой новой минуты.
  • today_at(value) преобразует строку, содержащую время в военном формате, в объект datetime с сегодняшней датой в вашем часовом поясе. По умолчанию используется полночь (00:00).
    • Использование today_at() приведет к обновлению шаблонов в начале каждой новой минуты.
# Текущее время после 10:15?
{{ now() > today_at("10:15") }}
  • as_datetime(value, default) преобразует строку, содержащую временную метку, или допустимую временную метку UNIX в объект datetime. Если это не удается, возвращает значение default или, если оно опущено, вызывает ошибку. Если входные данные уже являются объектом datetime, он будет возвращен как есть. Если входные данные являются объектом datetime.date, будет добавлено время полночи. Эта функция также может использоваться как фильтр.
  • as_timestamp(value, default) преобразует объект datetime или строку в временную метку UNIX. Если это не удается, возвращает значение default или, если оно опущено, вызывает ошибку. Эта функция также может использоваться как фильтр.
  • as_local() преобразует объект datetime в локальное время. Эта функция также может использоваться как фильтр.
  • strptime(string, format, default) разбирает строку на основе формата и возвращает объект datetime. Если это не удается, возвращает значение default или, если оно опущено, вызывает ошибку.
  • time_since(datetime, precision) преобразует объект datetime в читаемую строку времени. Строка времени может быть в секундах, минутах, часах, днях, месяцах и годах. precision принимает целое число (полное число) и указывает количество возвращаемых единиц. Последняя единица округляется. Например: precision = 1 может вернуть "2 года", а precision = 2 может вернуть "1 год 11 месяцев". Эта функция также может использоваться как фильтр. Если datetime в будущем, возвращает 0 секунд. Точность 0 возвращает все доступные единицы, по умолчанию 1.
  • time_until(datetime, precision) преобразует объект datetime в читаемую строку времени. Строка времени может быть в секундах, минутах, часах, днях, месяцах и годах. precision принимает целое число (полное число) и указывает количество возвращаемых единиц. Последняя единица округляется. Например: precision = 1 может вернуть "2 года", а precision = 2 может вернуть "1 год 11 месяцев". Эта функция также может использоваться как фильтр. Если datetime в прошлом, возвращает 0 секунд. Точность 0 возвращает все доступные единицы, по умолчанию 1.
  • timedelta возвращает объект timedelta, который представляет продолжительность (количество времени между двумя датами). Он принимает те же аргументы, что и функция Python datetime.timedelta — дни, секунды, микросекунды, миллисекунды, минуты, часы, недели.
# 77 минут до текущего времени.
{{ now() - timedelta( hours = 1, minutes = 17 ) }}
  • as_timedelta(string) преобразует строку в объект timedelta, который представляет продолжительность (количество времени между двумя датами). Ожидает данные в формате DD HH:MM:SS.uuuuuu, DD HH:MM:SS,uuuuuu или как указано в ISO 8601 (например, P4DT1H15M20S, что эквивалентно 4 1:15:20) или в формате интервала день-время PostgreSQL (например, 3 days 04:05:06). Эта функция также может использоваться как фильтр.
# Преобразуется в "00:10:00"
{{ as_timedelta("PT10M") }}
  • Фильтр timestamp_local(default) преобразует временную метку UNIX в строковое представление в формате ISO как дату/время в вашем локальном часовом поясе. Если это не удается, возвращает значение default или, если оно опущено, вызывает ошибку. Если требуется пользовательский формат строки, используйте timestamp_custom вместо этого.
  • Фильтр timestamp_utc(default) преобразует временную метку UNIX в строковое представление в формате ISO как дату/время в часовом поясе UTC. Если это не удается, возвращает значение default или, если оно опущено, вызывает ошибку. Если требуется пользовательский формат строки, используйте timestamp_custom вместо этого.
  • Фильтр timestamp_custom(format_string, local=True, default) преобразует временную метку UNIX в строковое представление на основе пользовательского формата, по умолчанию используется локальный часовой пояс. Если это не удается, возвращает значение default или, если оно опущено, вызывает ошибку. Поддерживает стандартные опции форматирования времени Python.

Совет: Временная метка UNIX — это количество секунд, прошедших с 00:00:00 UTC 1 января 1970 года. Поэтому, если она используется как аргумент функции, она может быть заменена числовым значением (int или float).

Важно: Если ваш шаблон возвращает временную метку, которая должна отображаться в интерфейсе (например, как объект датчика с device_class: timestamp), вы должны убедиться, что она в формате ISO 8601 (то есть содержит разделитель "T" между датой и временем). В противном случае отображение на устройствах macOS и iOS покажет ошибку. Следующий шаблон значения приведет к такой ошибке:

{{ states.sun.sun.last_changed }} => 2023-07-30 20:03:49.253717+00:00 (отсутствует разделитель "T")

Чтобы исправить это, принудительно преобразуйте в формат ISO с помощью isoformat():

{{ states.sun.sun.last_changed.isoformat() }} => 2023-07-30T20:03:49.253717+00:00 (содержит разделитель "T")
{{ 120 | timestamp_local }}

В JSON/Из JSON

Фильтр to_json сериализует объект в строку JSON. В некоторых случаях может потребоваться форматировать строку JSON для использования с вебхуком, как параметр для утилит командной строки или для множества других приложений. Это может быть сложно в шаблоне, особенно при работе с экранированием специальных символов. Используя фильтр to_json, это обрабатывается автоматически.

to_json также принимает логические аргументы для pretty_print, который будет красиво форматировать JSON с отступом в 2 пробела для удобства чтения, и sort_keys, который будет сортировать ключи JSON-объекта, обеспечивая согласованность результирующей строки для одного и того же ввода.

Если вам нужно сгенерировать JSON, который будет использоваться парсером, не поддерживающим символы Unicode, вы можете добавить ensure_ascii=True, чтобы to_json генерировал escape-последовательности Unicode в строках.

Фильтр from_json работает аналогично, но в обратном направлении, десериализуя строку JSON обратно в объект.

Примеры JSON

Шаблон
{% set temp = {'temperature': 25, 'unit': '°C'} %}
stringified object: {{ temp }}
object|to_json: {{ temp|to_json(sort_keys=True) }}
Вывод
stringified object: {'temperature': 25, 'unit': '°C'}
object|to_json: {"temperature": 25, "unit": "°C"}

Обратно, from_json может использоваться для десериализации строки JSON обратно в объект, чтобы легко извлечь полезные данные.

Шаблон
{% set temp = '{"temperature": 25, "unit": "°C"}'|from_json %}
The temperature is {{ temp.temperature }}{{ temp.unit }}
Вывод
The temperature is 25°C

is_defined

Иногда шаблон должен возвращать значение только в том случае, если оно определено, если нет, должно возвращаться значение по умолчанию. Это может быть полезно для проверки полезной нагрузки JSON. Фильтр is_defined позволяет выбросить ошибку, если значение или объект не определены.

Пример использования is_defined для разбора полезной нагрузки JSON:

{{ value_json.val | is_defined }}

Это вызовет ошибку UndefinedError: 'value_json' is undefined, если полезная нагрузка JSON не имеет атрибута val.

Версия

  • version() возвращает объект AwesomeVersion для значения, указанного в скобках.
    • Это также доступно как фильтр (| version).

Примеры:

  • {{ version("2099.9.9") > "2000.0.0" }} вернет True
  • {{ version("2099.9.9") < "2099.10" }} вернет True
  • {{ "2099.9.9" | version < "2099.10" }} вернет True
  • {{ (version("2099.9.9") - "2100.9.10").major }} вернет True
  • {{ (version("2099.9.9") - "2099.10.9").minor }} вернет True
  • {{ (version("2099.9.9") - "2099.9.10").patch }} вернет True

Расстояние

Не поддерживается в ограниченных шаблонах.

  • distance() измеряет расстояние между домом, объектом или координатами. Единица измерения (километры или мили) зависит от настроек системы.
  • closest() найдет ближайший объект.

Примеры расстояния

Если передано только одно местоположение, Home Assistant измерит расстояние от дома.

Использование координат Lat Lng: {{ distance(123.45, 123.45) }}

Использование состояния: {{ distance(states.device_tracker.paulus) }}

Эти варианты также можно комбинировать в любом сочетании:
{{ distance(123.45, 123.45, 'device_tracker.paulus') }}
{{ distance('device_tracker.anne_therese', 'device_tracker.paulus') }}

Примеры ближайшего объекта

Функция и фильтр closest найдут ближайший объект к местоположению Home Assistant:

Запрос всех объектов: {{ closest(states) }}
Запрос всех объектов определенного домена: {{ closest(states.device_tracker) }}
Запрос всех объектов в group.children: {{ closest('group.children') }}
Запрос всех объектов в group.children: {{ closest(states.group.children) }}

Найти объекты, ближайшие к координате или другому объекту. Все предыдущие аргументы все еще применяются для второго аргумента.

Ближайший к координате: {{ closest(23.456, 23.456, 'group.children') }}
Ближайший к объекту: {{ closest('zone.school', 'group.children') }}
Ближайший к объекту: {{ closest(states.zone.school, 'group.children') }}

Поскольку closest возвращает состояние, мы можем комбинировать его с distance.

{{ closest(states).name }} находится на расстоянии {{ distance(closest(states)) }} километров.

Последний аргумент функции closest имеет неявный expand и может принимать любую итерируемую последовательность состояний или ID объектов, а также будет расширять группы:

Ближайший из заданных объектов:
    {{ closest(['group.children', states.device_tracker]) }}
Ближайший к координате:
    {{ closest(23.456, 23.456, ['group.children', states.device_tracker]) }}
Ближайший к некоторому объекту:
    {{ closest(states.zone.school, ['group.children', states.device_tracker]) }}

Он также будет работать как фильтр над итерируемой группой объектов или групп:

Ближайший из заданных объектов:
    {{ ['group.children', states.device_tracker] | closest }}
Ближайший к координате:
    {{ ['group.children', states.device_tracker] | closest(23.456, 23.456) }}
Ближайший к некоторому объекту:
    {{ ['group.children', states.device_tracker] | closest(states.zone.school) }}

Содержит

Jinja по умолчанию предоставляет оператор in, который возвращает True, когда элемент находится в предоставленном списке. Тест и фильтр contains позволяют вам сделать обратное и проверить, содержит ли список элемент. Это особенно полезно в фильтрах select или selectattr, а также для проверки, имеет ли устройство определенный атрибут, supported_color_modes, определенный эффект света.

Некоторые примеры:

  • {{ state_attr('light.dining_room', 'effect_list') | contains('rainbow') }} вернет true, если свет имеет эффект rainbow.
  • {{ expand('light.office') | selectattr("attributes.supported_color_modes", 'contains', 'color_temp') | list }} вернет все светильники, которые поддерживают color_temp в группе office.
  • Этот более сложный пример использует фильтр contains для сопоставления текущего месяца с списком. В данном случае он используется для генерации списка тем освещения для передачи в действие Input select: Set options.

Числовые функции и фильтры

Некоторые из этих функций также могут использоваться в фильтре. Это означает, что они могут действовать как обычная функция, например, sqrt(2), или как часть фильтра, например, 2|sqrt.

Примечание: Числовые функции и фильтры вызывают ошибку, если входные данные не являются допустимым числом, опционально можно указать значение по умолчанию, которое будет возвращено вместо этого. Функция и фильтр is_number могут использоваться для проверки, является ли значение допустимым числом. Ошибки могут быть перехвачены фильтром default.

  • {{ float("not_a_number") }} — шаблон не будет отрендерен.

  • {{ "not_a_number" | sin }} — шаблон не будет отрендерен.

  • {{ float("not_a_number", default="Invalid number!") }} — отрендерится как "Invalid number!".

  • {{ "not_a_number" | sin(default="Invalid number!") }} — отрендерится как "Invalid number!".

  • float(value, default) попытается преобразовать входные данные в float. Если это не удается, возвращает значение default или, если оно опущено, вызывает ошибку.

  • float(default) фильтр попытается преобразовать входные данные в float. Если это не удается, возвращает значение default или, если оно опущено, вызывает ошибку.

  • is_number вернет True, если входные данные могут быть разобраны функцией Python float и разобранные входные данные не являются inf или nan, во всех остальных случаях возвращает False. Обратите внимание, что Python bool вернет True, но строки "True" и "False" обе вернут False. Может использоваться как фильтр.

  • int(value, default) аналогичен float, но преобразует в int. Как и float, он имеет форму фильтра, и ошибка возникает, если значение default опущено. Дробная часть отбрасывается: int("1.5") равно 1.

  • bool(value, default) преобразует значение в true или false. Следующие значения считаются true: логическое true, не нулевые int и float, и строки "true", "yes", "on", "enable", и "1" (без учета регистра). false возвращается для противоположных значений: логическое false, целое или с плавающей точкой 0, и строки "false", "no", "off", "disable", и "0" (также без учета регистра). Если значение не указано здесь, функция возвращает значение default или, если оно опущено, вызывает ошибку. Эта функция предназначена для использования на состояниях бинарных датчиков, переключателей или подобных объектов, поэтому ее поведение отличается от встроенного преобразования Python bool, которое считает, например, "on", "off", и "unknown" все true, но ""false; если это желательно, используйте not not value или аналогичную конструкцию. Как и float и int, bool имеет форму фильтра. Использование none в качестве значения по умолчанию особенно полезно в сочетании с фильтром немедленного условия: он может обрабатывать все три возможных случая в одной строке.

  • log(value, base, default) возьмет логарифм входных данных. Если база опущена, по умолчанию используется e — натуральный логарифм. Если value или base не могут быть преобразованы в float, возвращает значение default или, если оно опущено, вызывает ошибку. Также может использоваться как фильтр.

  • sin(value, default) вернет синус входных данных. Если value не может быть преобразован в float, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • cos(value, default) вернет косинус входных данных. Если value не может быть преобразован в float, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • tan(value, default) вернет тангенс входных данных. Если value не может быть преобразован в float, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • asin(value, default) вернет арксинус входных данных. Если value не может быть преобразован в float, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • acos(value, default) вернет арккосинус входных данных. Если value не может быть преобразован в float, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • atan(value, default) вернет арктангенс входных данных. Если value не может быть преобразован в float, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • atan2(y, x, default) вернет четырехквадрантный арктангенс y / x. Если y или x не могут быть преобразованы в float, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • sqrt(value, default) вернет квадратный корень входных данных. Если value не может быть преобразован в float, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • max([x, y, ...]) получит наибольший элемент в последовательности. Использует те же параметры, что и встроенный фильтр max.

  • min([x, y, ...]) получит наименьший элемент в последовательности. Использует те же параметры, что и встроенный фильтр min.

  • average([x, y, ...], default) вернет среднее значение последовательности. Если список пуст или содержит нечисловое значение, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • median([x, y, ...], default) вернет медианное значение последовательности. Если список пуст или содержит нечисловое значение, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • statistical_mode([x, y, ...], default) вернет статистическую моду (наиболее часто встречающееся значение) последовательности. Если список пуст, возвращает значение default или, если оно опущено, вызывает ошибку. Может использоваться как фильтр.

  • e математическая константа, приблизительно 2.71828.

  • pi математическая константа, приблизительно 3.14159.

  • tau математическая константа, приблизительно 6.28318.

  • Фильтр round(precision, method, default) преобразует входные данные в число и округляет его до precision знаков после запятой. Round имеет четыре режима, и режим по умолчанию (без указания режима) будет округлять до четного. Если входное значение не может быть преобразовано в float, возвращает значение default или, если оно опущено, вызывает ошибку.

    • round(precision, "floor", default) всегда округляет вниз до precision знаков после запятой.
    • round(precision, "ceil", default) всегда округляет вверх до precision знаков после запятой.
    • round(1, "half", default) всегда округляет до ближайшего значения .5. precision должен быть 1 для этого режима.
  • Фильтр value_one|bitwise_and(value_two) выполняет побитовую операцию AND(&) с двумя значениями.

  • Фильтр value_one|bitwise_or(value_two) выполняет побитовую операцию OR(|) с двумя значениями.

  • Фильтр value_one|bitwise_xor(value_two) выполняет побитовую операцию XOR(^) с двумя значениями.

  • Фильтр ord вернет для строки длиной один целое число, представляющее код Unicode символа, если аргумент является объектом Unicode, или значение байта, если аргумент является 8-битной строкой.

  • Фильтр multiply(arg) преобразует входные данные в число и умножает его на arg. Полезно в операциях со списками в сочетании с map.

  • Фильтр add(arg) преобразует входные данные в число и добавляет его к arg. Полезно в операциях со списками в сочетании с map.

Проверка сложных типов

В дополнение к строкам и числам, Python (и Jinja) поддерживает списки, множества и словари. Чтобы помочь вам с тестированием этих типов, вы можете использовать следующие тесты:

  • x is list вернет, является ли x списком или нет (например, [1, 2] is list вернет True).
  • x is set вернет, является ли x множеством или нет (например, {1, 2} is set вернет True).
  • x is tuple вернет, является ли x кортежем или нет (например, (1, 2) is tuple вернет True).
  • x is datetime вернет, является ли x объектом datetime или нет (например, datetime(2020, 1, 1, 0, 0, 0) is datetime вернет True).
  • x is string_like вернет, является ли x строкой, байтами или объектом bytearray.

Обратите внимание, что в Home Assistant Jinja имеет встроенные тесты для boolean (True/False), callable (любая функция), float (число с десятичной точкой), integer (число без десятичной точки), iterable (значение, которое можно итерировать, например, list, set, string или генератор), mapping (в основном dict, но также поддерживает другие словарные типы), number (float или int), sequence (значение, которое можно итерировать и индексировать, например, list и string), и string.

Преобразование типов

Хотя Jinja изначально поддерживает преобразование итерируемого объекта в list, он не поддерживает преобразование в tuple или set. Чтобы помочь вам с использованием этих типов, вы можете использовать следующие функции:

  • set(x) преобразует любой итерируемый объект x в set (например, set([1, 2]) == {1, 2}).
  • tuple(x) преобразует любой итерируемый объект x в tuple (например, tuple("abc") == ("a", "b", "c")).

Обратите внимание, что в Home Assistant для преобразования значения в list, string, int или float, Jinja имеет встроенные функции с именами, соответствующими каждому типу.

Итерация по нескольким объектам

Функция zip() может использоваться для итерации по нескольким коллекциям за одну операцию.

{% set names = ['Living Room', 'Dining Room'] %}
{% set entities = ['sensor.living_room_temperature', 'sensor.dining_room_temperature'] %}
{% for name, entity in zip(names, entities) %}
  The {{ name }} temperature is {{ states(entity) }}
{% endfor %}

zip() также может распаковывать списки.

{% set information = [
  ('Living Room', 'sensor.living_room_temperature'),
  ('Dining Room', 'sensor.dining_room_temperature')
] %}
{% set names, entities = zip(*information) %}
The names are {{ names | join(', ') }}
The entities are {{ entities | join(', ') }}

Функции и фильтры для обработки сырых данных

Эти функции используются для обработки сырых значений в формате bytes в значения в родных типах Python или наоборот. Функции pack и unpack также могут использоваться как фильтры. Они используют библиотеку Python 3 struct. См.: Документация библиотеки Python struct.

  • Фильтр value | pack(format_string) преобразует родной тип в объект типа bytes. Это вызовет функцию struct.pack(format_string, value). Возвращает None, если происходит ошибка или если format_string недействителен.
  • Функция pack(value, format_string) преобразует родной тип в объект типа bytes. Это вызовет функцию struct.pack(format_string, value). Возвращает None, если происходит ошибка или если format_string недействителен.
  • Фильтр value | unpack(format_string, offset=0) попытается преобразовать объект bytes в родной объект Python. Параметр offset определяет позицию смещения в байтах от начала входного буфера на основе bytes. Это вызовет функцию struct.unpack_from(format_string, value, offset=offset). Возвращает None, если происходит ошибка или если format_string недействителен. Обратите внимание, что фильтр unpack вернет только первый объект bytes, несмотря на то, что функция struct.unpack_from поддерживает возврат нескольких объектов (например, с format_string в виде ">hh").
  • Функция unpack(value, format_string, offset=0) попытается преобразовать объект bytes в родной объект Python. Параметр offset определяет позицию смещения в байтах от начала входного буфера на основе bytes. Это вызовет функцию struct.unpack_from(format_string, value, offset=offset). Возвращает None, если происходит ошибка или если format_string недействителен. Обратите внимание, что функция unpack вернет только первый объект bytes, несмотря на то, что функция struct.unpack_from поддерживает возврат нескольких объектов (например, с format_string в виде ">hh").

Примечание: Некоторые примеры:

  • {{ 0xDEADBEEF | pack(">I") }} — отрендерится как b"\xde\xad\xbe\xef".
  • {{ pack(0xDEADBEEF, ">I") }} — отрендерится как b"\xde\xad\xbe\xef".
  • {{ "0x%X" % 0xDEADBEEF | pack(">I") | unpack(">I") }} — отрендерится как 0xDEADBEEF.
  • {{ "0x%X" % 0xDEADBEEF | pack(">I") | unpack(">H", offset=2) }} — отрендерится как 0xBEEF.

Фильтры строк

  • Фильтр urlencode преобразует объект в строку ASCII с процентным кодированием (например, для HTTP-запросов с использованием application/x-www-form-urlencoded).
  • Фильтр slugify(separator="_") преобразует данную строку в "слаг".
  • Фильтр ordinal преобразует целое число в число, определяющее позицию в серии (например, 1st, 2nd, 3rd, 4th и т.д.).
  • Фильтр value | base64_decode декодирует строку base 64 в строку, по умолчанию используется кодировка utf-8.
  • Фильтр value | base64_decode("ascii") декодирует строку base 64 в строку, используя кодировку ascii.
  • Фильтр value | base64_decode(None) декодирует строку base 64 в сырые байты.

Примечание: Некоторые примеры:

  • {{ "aG9tZWFzc2lzdGFudA==" | base64_decode }} — отрендерится как homeassistant.
  • {{ "aG9tZWFzc2lzdGFudA==" | base64_decode(None) }} — отрендерится как b'homeassistant'.

Регулярные выражения

Для получения дополнительной информации о регулярных выражениях см.: Операции с регулярными выражениями в Python.

  • Тест string is match(find, ignorecase=False) сопоставит выражение find в начале строки с использованием регулярного выражения.
  • Тест string is search(find, ignorecase=False) сопоставит выражение find в любом месте строки с использованием регулярного выражения.
  • Фильтр string|regex_replace(find='', replace='', ignorecase=False) заменит выражение find на строку replace с использованием регулярного выражения. Доступ к сопоставленным группам в replace возможен с помощью '\\1', '\\2' и т.д.
  • Фильтр value | regex_findall(find='', ignorecase=False) найдет все совпадения регулярного выражения find в value и вернет массив совпадений.
  • Фильтр value | regex_findall_index(find='', index=0, ignorecase=False) сделает то же, что и regex_findall, и вернет совпадение по индексу.

Объединение ответов на действия

Используя ответы на действия, мы можем собирать информацию из различных объектов одновременно. Используя шаблон merge_response, мы можем объединить несколько ответов в один список.

Переменная Описание
value Входящее значение (должно быть ответом на действие).

Ключ entity_id добавляется к каждому словарю в списке выходных данных шаблона как ссылка на источник. Если входной словарь уже содержит ключ entity_id, шаблон завершится ошибкой.

Ключ value_key добавляется к каждому словарю в списке выходных данных шаблона как ссылка на источник, если исходный вызов сервиса предоставлял список словарей, например, calendar.get_events или weather.get_forecasts.

Примеры этих двух ключей можно увидеть в примере объединения ответа на действие календаря.

Пример

{% set combined_forecast = merge_response(response) %}
{{ combined_forecast[0].precipitation | float(0) | round(1) }}

Пример сортировки

Сортировка словарей в списке по определенному ключу может быть выполнена непосредственно с использованием фильтра sort Jinja.

{{ merge_response(calendar_response) | sort(attribute='start') | ... }}

Пример объединения ответа на действие календаря

{
  "calendar.sports": {
    "events": [
      {
        "start": "2024-02-27T17:00:00-06:00",
        "end": "2024-02-27T18:00:00-06:00",
        "summary": "Basketball vs. Rockets",
        "description": "",
      }
    ]
  },
  "calendar.local_furry_events": {"events": []},
  "calendar.yap_house_schedules": {
    "events": [
      {
        "start": "2024-02-26T08:00:00-06:00",
        "end": "2024-02-26T09:00:00-06:00",
        "summary": "Dr. Appt",
        "description": "",
      },
      {
        "start": "2024-02-28T20:00:00-06:00",
        "end": "2024-02-28T21:00:00-06:00",
        "summary": "Bake a cake",
        "description": "something good",
      }
    ]
  },
}
{{ merge_response(response_variable) }}
[
  {
    "description": "",
    "end": "2024-02-27T18:00:00-06:00",
    "entity_id": "calendar.sports",
    "start": "2024-02-27T17:00:00-06:00",
    "summary": "Basketball vs. Rockets",
    "value_key": "events"
  },
  {
    "description": "",
    "end": "2024-02-26T09:00:00-06:00",
    "entity_id": "calendar.yap_house_schedules",
    "start": "2024-02-26T08:00:00-06:00",
    "summary": "Dr. Appt",
    "value_key": "events"
  },
  {
    "description": "something good",
    "end": "2024-02-28T21:00:00-06:00",
    "entity_id": "calendar.yap_house_schedules",
    "start": "2024-02-28T20:00:00-06:00",
    "summary": "Bake a cake",
    "value_key": "events"
  }
]

Пример ответов на действия, не являющихся списками

{
  "vacuum.deebot_n8_plus_1": {
    "header": {
      "ver": "0.0.1",
    },
    "payloadType": "j",
    "resp": {
      "body": {
        "msg": "ok",
      },
    },
  },
  "vacuum.deebot_n8_plus_2": {
    "header": {
      "ver": "0.0.1",
    },
    "payloadType": "j",
    "resp": {
      "body": {
        "msg": "ok",
      },
    },
  },
}
{{ merge_response(response_variable) }}
[
  {
    "entity_id": "vacuum.deebot_n8_plus_1",
    "header": {
      "ver": "0.0.1",
    },
    "payloadType": "j",
    "resp": {
      "body": {
        "msg": "ok",
      },
    },
  },
  {
    "entity_id": "vacuum.deebot_n8_plus_2",
    "header": {
      "ver": "0.0.1",
    },
    "payloadType": "j",
    "resp": {
      "body": {
        "msg": "ok",
      },
    },
  },
]

Обработка входящих данных

Другая часть шаблонизации — это обработка входящих данных. Она позволяет вам изменять входящие данные и извлекать только те данные, которые вам нужны. Это будет работать только для платформ и интеграций, которые упоминают поддержку этого в своей документации.

Это зависит от интеграции или платформы, но обычно можно определить шаблон, используя ключ конфигурации value_template. Когда поступает новое значение, ваш шаблон будет отрендерен с доступом к следующим значениям в дополнение к обычным расширениям Home Assistant:

Переменная Описание
value Входящее значение.
value_json Входящее значение, разобранное как JSON.

Это означает, что если входящие значения выглядят как в примере ниже:

{
  "on": "true",
  "temp": 21
}

Шаблон для on будет:

"{{value_json.on}}"

Вложенный JSON в ответе также поддерживается:

{
  "sensor": {
    "type": "air",
    "id": "12345"
  },
  "values": {
    "temp": 26.09,
    "hum": 56.73
  }
}

Просто используйте "квадратные скобки" для получения значения.

"{{ value_json['values']['temp'] }}"

Следующий обзор содержит несколько вариантов получения нужных значений:

# Входящее значение:
{"primes": [2, 3, 5, 7, 11, 13]}

# Извлечь первое простое число
{{ value_json.primes[0] }}

# Форматировать вывод
{{ "%+.1f" | value_json }}

# Математика
{{ value_json | float * 1024 if is_number(value_json) }}
{{ float(value_json) * (2**10) if is_number(value_json) }}
{{ value_json | log if is_number(value_json) }}
{{ log(1000, 10) }}
{{ sin(pi / 2) }}
{{ cos(tau) }}
{{ tan(pi) }}
{{ sqrt(e) }}

# Временные метки
{{ value_json.tst | timestamp_local }}
{{ value_json.tst | timestamp_utc }}
{{ value_json.tst | timestamp_custom('%Y', True) }}

Чтобы оценить ответ, перейдите в Инструменты разработчика > Шаблоны, создайте ваш вывод в "Редакторе шаблонов" и проверьте результат.

{% set value_json=
    {"name":"Outside",
     "device":"weather-ha",
     "data":
        {"temp":"24C",
         "hum":"35%"
         } } %}

{{value_json.data.hum[:-1]}}

Использование шаблонов с интеграцией MQTT

Интеграция MQTT сильно зависит от шаблонов. Шаблоны используются для преобразования входящих полезных нагрузок (шаблоны значений) в обновления состояний или входящих действий (шаблоны команд) в полезные нагрузки, которые настраивают устройство MQTT.

Использование шаблонов значений с MQTT

Шаблоны значений преобразуют полученную полезную нагрузку MQTT в допустимое состояние или атрибут. Полученная полезная нагрузка MQTT доступна в переменной шаблона value, а также в переменной шаблона value_json, если полученная полезная нагрузка MQTT является допустимым JSON.

Кроме того, переменные шаблона entity_id, name и this доступны для шаблонов значений MQTT. Атрибут this ссылается на состояние объекта элемента MQTT.

Примечание: Пример шаблона значения:

С данной полезной нагрузкой:

{ "state": "ON", "temperature": 21.902 }

Шаблон {{ value_json.temperature | round(1) }} отрендерится как 21.9.

Использование шаблонов команд с MQTT

Для действий шаблоны команд определяются для форматирования исходящей полезной нагрузки MQTT в формат, поддерживаемый удаленным устройством. Когда действие выполняется, переменная шаблона value содержит данные действия в большинстве случаев, если не указано иное в документации.

Кроме того, переменные шаблона entity_id, name и this доступны для шаблонов команд MQTT. Атрибут this ссылается на состояние объекта элемента MQTT.

Примечание: Пример шаблона команды с данными JSON:

С данным значением 21.9 шаблон {"temperature": {{ value }} } отрендерится как:

{
  "temperature": 21.9
}

Пример шаблона команды с сырыми данными:

Когда шаблон команды отрендерится в допустимый литерал bytes, MQTT опубликует эти данные как сырые данные. В других случаях будет опубликовано строковое представление. Таким образом:

  • Шаблон {{ "16" }} отрендерится как строка "16".
  • Шаблон {{ 16 }} отрендерится как строка "16".
  • Шаблон {{ pack(0x10, ">B") }} отрендерится как сырая полезная нагрузка из 1 байта 0x10.

Некоторые дополнительные моменты, которые следует учитывать

entity_id, начинающийся с числа

Если ваш шаблон использует entity_id, который начинается с числа (например, states.device_tracker.2008_gmc), вы должны использовать синтаксис квадратных скобок, чтобы избежать ошибок, вызванных неправильным рендерингом entity_id. В данном примере правильный синтаксис для устройства будет: states.device_tracker['2008_gmc'].

Приоритет операторов

Приоритет операторов по умолчанию таков, что фильтр (|) имеет приоритет над всем, кроме скобок. Это означает, что:

{{ states('sensor.temperature') | float / 10 | round(2) }}

Округлит 10 до 2 знаков после запятой, затем разделит states('sensor.temperature') на 10 (округленное до 2 знаков после запятой, то есть 10.00). Это поведение может быть неожиданным, но правила приоритета подразумевают это.