Condition Template trigger attribute availability

I have a template in an automation condition. This works as expected, except when for some reason the integration supplying the entity with the trigger changing attribute is not available (e.g. on a reload), then an error gets thrown.

trigger:
  - platform: state
    entity_id: climate.ac
    attribute: temperature
condition:
  - condition: template
    value_template: "{{ trigger.from_state.attributes.temperature | int >= 16 }}"
  - condition: template
    value_template: "{{ trigger.to_state.attributes.temperature | int >= 16 }}"

How do I test for the existence of that attribute BEFORE testing it against “int >= 16”?

Is it by using an availability_template?

OK, I have worked out how to check availability as part of an automation condition. I also checked to see what value is returned by climate.ac temperature attribute when the integration is not loaded - it’s ‘null’.
So I tried this:

trigger:
  - platform: state
    entity_id: climate.ac
    attribute: temperature
condition:
  - condition: template
    value_template: >-
      {{ state_attr('climate.ac','temperature') not in ['unavailable', 'unknown', 'none', 'null'] }}
  - condition: template
    value_template: "{{ trigger.from_state.attributes.temperature | int >= 16 }}"
  - condition: template
    value_template: "{{ trigger.to_state.attributes.temperature | int >= 16 }}"

…but…
On a reload, the third condition fails first (presumably as the integration’s temperature attribute disappears from its current set temp but no “to” value; it then fails the second condition as it comes back up - as it is set “to” the default, but comes from nothing.

But I would have thought that my first condition should check if it is available to use?

Not necessarily. Lists have no order. Just because you wrote them in that order does not mean they will be checked in that order.

All you need to do is supply a default for the |int filter that fails the greater than test, like this:

condition:
  - condition: template
    value_template: "{{ trigger.from_state.attributes.temperature | int(0) >= 16 }}"
  - condition: template
    value_template: "{{ trigger.to_state.attributes.temperature | int(0) >= 16 }}"
1 Like

That’s interesting that the conditions are not sequentially evaluated as written - filing that little tidbit of info away for later use :slight_smile: Thanks for that - very useful to know.

But… adding (0) does not fix it…

It’s now written as:

trigger:
  - platform: state
    entity_id: climate.ac
    attribute: temperature
condition:
  - condition: template
    value_template: "{{ trigger.from_state.attributes.temperature | int(0) >= 16 }}"
  - condition: template
    value_template: "{{ trigger.to_state.attributes.temperature | int(0) >= 16 }}"

…but still errors (note the other three conditions not shown are simple boolean helper checks, so they are always successful):

2022-10-17 20:14:30.103 WARNING (MainThread) [homeassistant.components.automation] Error evaluating condition in 'AC auto: Change climate.ac target temp handler':

In 'condition' (item 2 of 5):

In 'template' condition: UndefinedError: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'temperature'

2022-10-17 20:14:30.164 WARNING (MainThread) [homeassistant.components.automation] Error evaluating condition in 'AC auto: Change climate.ac target temp handler':

In 'condition' (item 1 of 5):

In 'template' condition: UndefinedError: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'temperature'

Note that triggering the automation while climate.ac is available works fine - it’s only on a reboot or a reload that the trigger fails. So whilst not critical, it shows that my code is not effectively catching error situations.

One last try:

condition:
  - condition: template
    value_template: >
      {% if state_attr('climate.ac','temperature')|is_number %}
        {{ trigger.from_state.attributes.temperature | int() >= 16 }}
      {% else %}
        {{ false }}
      {% endif %}
  - condition: template
    value_template: >
      {% if state_attr('climate.ac','temperature')|is_number %}
        {{ trigger.to_state.attributes.temperature | int(0) >= 16 }}
      {% else %}
        {{ false }}
      {% endif %}
1 Like

Thanks Tom. One quick check, is the variation of int() and int(0) a deliberate difference?

I’ve tried with int(), with int(0) and with int - all the same result, but checking to be sure.
All are an improvement… :slight_smile: it now only generates one error on a reload instead of two, and always on item 1 of 5.

2022-10-17 21:56:35.355 WARNING (MainThread) [homeassistant.components.automation] Error evaluating condition in 'AC auto: Change climate.ac target temp handler':

In 'condition' (item 1 of 5):

In 'template' condition: UndefinedError: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'temperature'

I feel like this should work…

OK, so it is the trigger.from that is failing.
This passes with no errors (but obviously doesn’t do what I need):

  - condition: template
    value_template: >
      {% if state_attr('climate.ac','temperature') | is_number %}
        {{ true }}
      {% else %}
        {{ false }}
      {% endif %}

OK, I’m going to try without the failing trigger.from condition test completely. The following works without throwing any errors.

trigger:
  - platform: state
    entity_id: climate.ac
    attribute: temperature
condition:
  - condition: template
    value_template: >
      {% if state_attr('climate.ac','temperature') | is_number %}
        {{ trigger.to_state.attributes.temperature | int(0) >= 16 }}
      {% else %}
        {{ false }}
      {% endif %}

This has multiple tests in it - is it a number, is it an integer, and is it greater than 16.

Regardless of what the previous value was I think this should be OK, although I’ll have to keep an eye open for the weird fringe cases that this A/C unit throws at my automation whenever I think I have it sorted…

EDITED: this wasn’t a fix, as I needed the missing trigger.from_state to prevent the automation running when the triggering state change was from a restart, not from a temperature input change.

I think I cracked it…

On startup (or back up from a reload), trigger.from_state for climate.ac has no attribute ‘temperature’ defined. I can validate this by stopping the integration and looking in developer tools - there is no temperature attribute.

This is why trigger.from_state.attributes.temperature is generating the error, regardless of what tests I tried - you cannot apparently test an attribute for is_defined on that dict if is not there.

In 'template' condition: UndefinedError: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'temperature'

I checked to see what attributes are available when it is not running, and there is a ‘restore’ attribute which is only available when the integration is not running, including briefly on restart/reload.

I have edited the value template as follows, and it works, preventing the automation from triggering on a restart/start (which was the goal of the 1st condition test):

trigger:
  - platform: state
    entity_id: climate.ac
    attribute: temperature
condition:
  - condition: template
    value_template: >
      {% if trigger.from_state.attributes.restored == true %}
        {{ false }}
      {% else %}
        {{ trigger.from_state.attributes.temperature | int(0) >= 16 }}
      {% endif %}
  - condition: template
    value_template: >
      {% if state_attr('climate.ac','temperature') | is_number %}
        {{ trigger.to_state.attributes.temperature | int(0) >= 16 }}
      {% else %}
        {{ false }}
      {% endif %}