Cannot return the correct state. Always defaults to false. What I'm doing wrong?

template:
  - sensor:
      - name: "Near Home"
        unique_id: "near_home_sensor"
        state: >
          {% set result = false %}
          {% set persons = states.person | selectattr('state', 'eq', 'home') | list %}

          {% for person in persons %}
            {% set device_tracker = state_attr(person.entity_id, 'source') | replace('device_tracker.', '') %}
            {% set connection_sensor = 'sensor.' ~ device_tracker ~ '_connection_type' %}
            {% set connection_type = states(connection_sensor) %}

            {% if connection_type != 'Wi-Fi' %}
              {% set result = true %}
            {% endif %}
          {% endfor %}

          {{ result }}

Look here, search for “Scoping Behavior”

TL;DR: using set creates a newly scoped variable result inside its closest block. You need to use an alternative method to get the value of result out (as explained in the documentation)

Here is my new code. But still doesn’t work.What I’m doing wrong? Please help.

  - sensor:
      - name: "Not Yet Home"
        unique_id: "not_yet_home_sensor"
        state: >
          {% set persons = states.person | selectattr('entity_id', 'defined') | list %}
          {% set non_wifi_count = 0 %}

          {% for person in persons %}
            {% set device_tracker = state_attr(person.entity_id, 'source') %}
            {% if device_tracker %}
              {% set device_name = device_tracker | replace('device_tracker.', '') %}
              {% set connection_sensor = 'sensor.' ~ device_name ~ '_connection_type' %}
              {% set connection_type = states(connection_sensor) %}
              
              {% if connection_type != 'Wi-Fi' %}
                {% set non_wifi_count = non_wifi_count + 1 %}
              {% endif %}
            {% endif %}
          {% endfor %}

          {% if non_wifi_count > 0 %}
            true
          {% else %}
            false
          {% endif %}

The documentation that I linked to provides an answer on how to define a “variable” outside of a block and set its value from within a block:

{% set ns = namespace(found=false) %}
{% for item in items %}
    {% if item.check_something() %}
        {% set ns.found = true %}
    {% endif %}
    * {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}
1 Like

Thanks for the fast answer. Can you please correct my code so I can see how it should be done the right way. I would really appreciate it.

Thanks. It worked!

1 Like