Namespace in templates no longer seems to work

This template (and others very similar) was working perfectly but now they give an error:

Error rendering template: UndefinedError: 'count_pir' is undefined

Can anyone help?

            {% set ns = namespace(count_pir) %}
            {%- set ns.count = 0 %}
            {%- for pir in states.binary_sensor -%}
              {% set type =' ') | first -%}
                {% if type == 'PIR' and
                              pir.state == 'on' %}
                  {%- set ns.count = ns.count + 1 -%}

                  - {{[4:] }}
              {% endif -%}  
            {% endfor %}
            {%- if ns.count == 0 -%}

              - None detected -
            {%- endif %}

As background, most of these templates are used to generate the message part of a Telegram notifications but that isn’t really relevant. All my sensors have standard names and in this case they are of the form:

name: PIR room_name

EDIT: Ok, yes it does work, but only if I put {% set ns = namespace(count_pir = 0) %}

Now, I’m still a beginner with Python so clearly I don’t fully understand what is going on here but whatever the case, it doesn’t explain why it suddenly stopped working.

When you call the method namespace with count_pir=0 inside it, it creates the namespace with count_pir=0. Then you add count to it later on. You can just skip all that and create it with count.

{% set ns = namespace(count=0) %}

You can get the same outcome with this code (which you essentially had

{% set ns = namespace() %}
{% set ns.count = 0 %}

So that should have worked for you with the count_pir not set to anything because the method just ignores that input.

EDIT: I just noticed this line in your post. That’s basically saying that count_pir isn’t defined in the scope. Meaning that there is no variable count_pir to pull from. So when you change it to count_pir=0, you’re giving the function a keyword argument, count_pir.

This is a timely post! I recently tried to create the same functionality (a counter within a for-loop) but was thwarted by tighter scoping rules in Jinja2 version 2.10.

The suggested solution was to create the counter variable using a namespace (as shown above). However, when I tried it in the Template Editor, it failed. I concluded Home Assistant’s implementation of Jinja2 does not support namespaces. The following post seemed to confirm my conclusion (it’s an old post, so it’s an old version of Home Assistant):

However, this thread shows it does work. Therefore it must be due to the fact I’m using version 0.80. I loaded a docker instance of 0.86.4, tried the same experiment, and the Template Editor correctly evaluated my for-loop example containing a namespace.

Yeah, it must have been added at some point because I know it never worked in the past. namespace that is. But now it’s working for me in the template editor. On 87.

Thanks. From a bit of reading and the reply from @petro I think I might have got my head around how namespace works now…

@123 I have been using this (in the form from my original post) for some time now, several months I’d guess form about Oct/Nov 2018 and it worked perfectly until (I noticed in) 0.88.1.

I can only assume that as you say, something underlying was upgraded and so stopped it working.

I’d like to know though, should I have known this from reading the upgrade notes and breaking changes? Because it seems to me that whilst I have no complaints with the underlying software being upgraded it would be nice to be told that it might have an impact.

I mean, we’d need to look through the changes for a Jinja update.