Reload templates keeps triggering this automation based on state binary_sensor

which is kind of nasty.
Think I tried all available options to add conditions to prevent accidental triggering, unfortunately this is triggered each an every reload:

  - alias:  Alert when batteries are below alert level
    trigger:
      platform: state
      entity_id: binary_sensor.battery_alert
#      from: 'off'
      to: 'on'
    condition:
      >
        {{trigger.to_state is not none and
          trigger.from_state is not none and
          trigger.from_state not in ['unknown','unavailable','None'] and
          trigger.to_state.state != trigger.from_state.state}}
    action:
      service: notify.system
      data:
        title: Battery alert
        message: >
          {{state_attr('binary_sensor.battery_alert','List')}}

is this something the new templating engine has brought on, or caused by the new reloading of the templates… When reloading automations, this doesnt get triggered, so that a relief…

please help me find a solution?

have 1 more, which is also triggering each and every time.

the binary_sensor itself is based on a template sensor:

binary_sensor:
  - platform: template
    sensors:
      battery_alert:
        friendly_name: Battery alert
        device_class: problem
        value_template: >
          {{states('sensor.low_level_batteries')|int > 0}}

which of course also is reloaded.

Your syntax is basically telling the system that when states(‘sensor.low_level_batteries’) is unavailable, the value of that sensor is false. 'unknown' | int equals 0. 0 is not greater than zero. So your template is false at startup.

As stated in a prior engagement, you should be using availability_template.

availability_template: >
  {{ states('sensor.low_level_batteries') not in ['unknown','unavailable','None'] }}
1 Like

thanks Petro, will test that.
edit

this doesn’t help unfortunately:

binary_sensor:
  - platform: template
    sensors:
      battery_alert:
        friendly_name: Battery alert
        device_class: problem
        availability_template: >
          {{ states('sensor.low_level_batteries') not in ['unknown','unavailable','None'] }}
        value_template: >
          {{states('sensor.low_level_batteries')|int > 0}}
        attribute_templates:
          Count: >
           {{states('sensor.low_level_batteries')|int}}
          List: >
           {{state_attr('sensor.low_level_batteries','List Low')}}

btw, Ive tested to dont use the |int along with > '0' which seems to help too. maybe hacky, but still.

digging some further, there’s 1 other automation triggered by a binary that gets fired. Odd thing is, this is 1 of 2 binaries checking for quakes, 1 for general quakes at all, one for quakes near.

      earthquakes_active:
        friendly_name: Earthquakes active
        value_template: >
          {{states('sensor.earthquakes')|int > 0}}
        device_class: safety

      earthquakes_near_active:
        friendly_name: Earthquakes near active
        value_template: >
          {{states('sensor.earthquakes_near')|int > 0}}
        device_class: safety

the template sensors they are based on are:

      earthquakes:
        friendly_name: Earthquakes
        value_template: >
          {{states.geo_location|selectattr('attributes.source','eq','usgs_earthquakes_feed')
            |list|count}}
        attribute_templates:
          list: >
            {% if states.geo_location|selectattr('attributes.source','eq','usgs_earthquakes_feed')
            |list|count > 0 %}
            {{states.geo_location|selectattr('attributes.source','eq','usgs_earthquakes_feed')
              |map(attribute='name')|join(',\n')}}
            {% else %} No Quakes registered
            {% endif %}

      earthquakes_near:
        friendly_name: Quakes near
        value_template: >
          {% set km = states('input_number.quakes_near')|float %}
          {% set location = states('input_select.quakes_near') %}
          {% set ns = namespace(count=0) %}
          {% for s in states.geo_location|selectattr('attributes.source','eq','usgs_earthquakes_feed')
             if distance(s.entity_id,location) < km %}
              {% set ns.count = ns.count + 1 %}
          {% endfor %}
          {{ns.count}}

of these, the generic quakes binary triggers this automation:

  - alias: Quake Alert
    id: Quake Alert
    trigger:
      platform: state
      entity_id: binary_sensor.earthquakes_active
      to: 'on'

why is this triggering and the other more complex one not, on reload of templates, I must find out. Probably because the quake template doesnt use |int inside the template itself (so it might be hacky by design? and the quakes_near uses the function distance(), which solves the issue.

because I also tried

          {%- set ns = namespace(below=0) %}
          {%- for s in expand('group.battery_sensors')
            if s.state|int < states('input_number.battery_alert_level')|int %}
              {%- set ns.below = ns.below + 1 %}
          {%- endfor %}
          {{ns.below}}

but this still |int 's unknown states to 0, so will always make it trigger… And I can see that because at startup most of the battery sensors are displayed as unknown%, in the list:

        attribute_templates:
          List Low: >
            {%- set alert_level = states('input_number.battery_alert_level')|int %}
            {%- set count = expand('group.battery_sensors')
                                              |map(attribute='state')|map('int')
                                              |select('<',alert_level)
                                              |list|count %}
            {% set phrase = 'battery is' if count == 1 else 'batteries are' %}
            {%- if count > 0 %}
            {%- for s in expand('group.battery_sensors')
                          if s.state not in ['unknown','unavailable','None'] and
                             s.state|int < alert_level %}
            {%- if loop.first %}{{loop.length}} {{phrase}} below {{alert_level}} %: {% endif %}
            {{s.name + ': ('+ s.state + '%),\n'}}
            {%- endfor %}
            {%- else %} All batteries above {{alert_level}} %
            {%- endif %}

so I hope to have excluded that with the if s.state not in ['unknown','unavailable','None']

to be continued
Why this didn’t trigger before 115 is a question too…