Importing a custom_template macro within a template sensor

Hi all,

Can I import a macro into a template sensor? I can’t see any documentation saying you can and I am aware that you can import directly into an automation.


TL;DR

I have a bunch of template sensors - one for each of my shades - that look a lot like this:

template:
  - sensor:
    - name: "Bedroom 1 shade"
      unit_of_measurement: "%"
      state: >
        {% set open = states('binary_sensor.bedroom_1_window_contact') %}
        {% set sun = states('binary_sensor.shades_south_has_sun') %}
        {% set light = states('sensor.light_level') %}
        {% set house = states('input_select.house_mode') %}
        {% set uv = states('sensor.weather_uv_index')|float(0) %}
        {% set t_in = states('sensor.hottest_temp')|float(15) %}
        {% set t_out = states('sensor.weather_temp')|float(15) %}
        {# window closed #}
        {% if open == 'off' %}
          {% if light == 'Night' or house == 'Asleep' %}    0 {# eve / asleep #}
          {% elif t_out >= 24 and uv >=6 and sun == 'on' %}
            {% if t_in >= 24 %}                             0 {# day, h UV, sun on, h temp #}
            {% elif t_in >= 22 %}                          50 {# day, h UV, sun on, m temp #}
            {% else %}                                    100 {# day, h UV, sun on, l temp #}
            {% endif %}
          {% else %}                                      100 {# day, l UV #}
          {% endif %}
        {# window open #}
        {% elif light == 'Night' or house == 'Asleep' %}   50 {# eve / asleep #}
        {% elif t_out >= 24 and uv >=6 and sun == 'on' %}
          {% if t_in >= 22 %}                              50 {# day, h UV, sun on >=m temp #}
          {% else %}                                      100 {# day, h UV, sun on, l temp #}
          {% endif %}
        {% else %}                                        100 {# day, l UV #}
        {% endif %}

It returns the position (0-100) to set my shade to based on temp, UV, whether the associated dr/window is open or not etc etc.

They are all almost exactly the same (except for the contact sensor). I would very must like to change those sensors to this:

    - name: "Bedroom 1 shade test"
      unit_of_measurement: "%"
      state: >
        {% from `shade.jinja` import south_shade_level %}
        {{ south_shade_level(binary_sensor.bedroom_1_window_contact) }}

and have a single macro looking something like this:

{% macro south_shade_level(contact) %}
{% set open = states(contact) %}
{% set sun = states('binary_sensor.shades_south_has_sun') %}
{% set light = states('sensor.light_level') %}
{% set house = states('input_select.house_mode') %}
{% set uv = states('sensor.weather_uv_index')|float(0) %}
{% set t_in = states('sensor.hottest_temp')|float(15) %}
{% set t_out = states('sensor.weather_temp')|float(15) %}
{# window closed #}
{% if open == 'off' %}
  {% if light == 'Night' or house == 'Asleep' %}    0 {# eve / asleep #}
  {% elif t_out >= 24 and uv >=6 and sun == 'on' %}
    {% if t_in >= 24 %}                             0 {# day, h UV, sun on, h temp #}
    {% elif t_in >= 22 %}                          50 {# day, h UV, sun on, m temp #}
    {% else %}                                    100 {# day, h UV, sun on, l temp #}
    {% endif %}
  {% else %}                                      100 {# day, l UV #}
  {% endif %}
{# window open #}
{% elif light == 'Night' or house == 'Asleep' %}   50 {# eve / asleep #}
{% elif t_out >= 24 and uv >=6 and sun == 'on' %}
  {% if t_in >= 22 %}                              50 {# day, h UV, sun on >=m temp #}
  {% else %}                                      100 {# day, h UV, sun on, l temp #}
  {% endif %}
{% else %}                                        100 {# day, l UV #}
{% endif %}
{% endmacro -%}

This would help me make global changes as there code only exists once. Does anyone know if this is even possible?

According to the documentation, it’s possible.

Templating - Reusing templates

Go ahead and try it.

1 Like

Yes, although you must use proper single quotes not backticks to call it, and the entity ID should be quoted as a string. Your version:

        {% from `shade.jinja` import south_shade_level %}
        {{ south_shade_level(binary_sensor.bedroom_1_window_contact) }}

should be

        {% from 'shade.jinja' import south_shade_level %}
        {{ south_shade_level('binary_sensor.bedroom_1_window_contact') }}

I’ve successfully done it here (see “Some template sensors…” expansion header):

1 Like

@123 thanks - I did try that and it didn’t work so assumed it was for automations only (because the release docs only mentioned automations).

I think @Troon has found my error - so will try that.

Thanks, both!

Like I said, it’s possible.

… with the exception of incorrect punctuation. :wink:

1 Like

so true! …it’s been a long day!