Jinja2 - no filter named 'merge' found

I found this template sensor in the GitHub Home Assistant configuration package of someone I know to be a competent user. It appears to be a template that weights 2 presence entities and produces a result based on that weighting.

{% set weight_values = {
            'sensor.xxxx_xxxx_xxxx_presence': 0.8,
            'sensor.xxxx_xxxx_xxxx_presence': 1.0
          } %}
          {% set presence = {} %}
          {% for entity_id, weight in weight_values.items() %}
            {% if states(entity_id) not in presence %}
              {% set presence = presence | merge({(states(entity_id)): weight}) %}
            {% else %}
              {% set presence = presence | merge({(states(entity_id)): presence[states(entity_id)] + weight}) %}
            {% endif %}
          {% endfor %}
          {% if presence|length > 0 %}
            {% set highest_presence = presence|max %}
            {% for room, value in presence.items() %}
              {% if value == highest_presence %}
                {{ room }}
              {% endif %}
            {% endfor %}
          {% else %}
            unknown
          {% endif %}

but when I enter it into the template editor I get a

TemplateRuntimeError: no filter named 'merge' found.

I checked the stock list of Jinja2 filters and sure enough there is no merge filter listed.

What’s going on here and why would someone use a filter that is not known? :man_shrugging:

Best to ask the creator then. You can probably create an issue on GitHub.
There is indeed no merge filter

1 Like

as thefes said, merge doesn’t exist. Here’s how you’d make that template without that merge function in the current version of HA:

          {% set weight_values = {
            'sensor.xxxx_xxxx_xxxx_presence': 0.8,
            'sensor.xxxx_xxxx_xxxx_presence': 1.0
          } %}
          {% set ns = namespace(presence=[]) %}
          {% for entity_id, weight in weight_values.items() %}
            {% set key = states(entity_id) %}
            {% set td = dict.from_keys(ns.presence) %}
            {% set new_weight = weight if key not in td.keys() else td[key] + weight %}
            {% set ns.presence = td.items() | rejectattr('0', 'eq', key) | list + [(key, new_weight)] %}
          {% endfor %}
          {% if ns.presence | length > 0 %}
            {{ (ns.presence | sort(attribute='1', reverse=True) | first) | first }}
          {% else %}
            unknown
          {% endif %}
1 Like

I see @petro also already tackled the scoping issue. Even if the merge filter would have existed, presence would always be {} after the for loop.

I’ll take your word for it :grin: Here was me thinking I was getting the hang of for loops :man_shrugging: