Template trigger does not work

Any ideas why this does not trigger?

  - alias: Bedroom temperature sensor has old data
    trigger:
      platform: template
      value_template: '{{ ((as_timestamp(now()) - as_timestamp(states.sensor.soverom_temperature.last_updated)) / 60) > 5 }}'
    action:
      - service: notify.pushover
        data:
          title: "Sensor warning"
          message: "Temperaturmåling på soverommet er {{ ((as_timestamp(now()) - as_timestamp(states.sensor.soverom_temperature.last_updated)) / 60) |int }} minutter gammel"

If I put '{{ ((as_timestamp(now()) - as_timestamp(states.sensor.soverom_temperature.last_updated)) / 60) > 5 }}'in the dev template editor, it says True. (It said False before I pulled the batteries from the thermometer.)

it won’t work because now() does not create a listener for home assistant to react upon. That trigger will only fire when sensor.soverom_temperature updates. It will not fire when the time changes.

You need to move that to a condition with a trigger that fires every minute or come up with another approach to the template using an entity_id that updates every minute.

2 Likes

Thanks, that makes sense. But I still don’t get any notifications, any ideas?

- alias: Bedroom temperature sensor has old data
  trigger:
    platform: time
    minutes: 1
  condition:
    - condition: numeric_state
      entity_id: sensor.soverom_temperature
      value_template: '{{ (as_timestamp(now()) - as_timestamp(state.last_updated)) / 60 }}'
      above: 5
  action:
    - service: notify.pushover
      data:
        title: "Sensor warning"
        message: "Temperaturmåling på soverommet er {{ ((as_timestamp(now()) - as_timestamp(state.last_updated)) / 60) |int }} minutter gammel"

Yes, now() wont trigger an automation.
Instead, you should use a time_date sensor. This updates every minute if needed

  - platform: time_date
    display_options:
      - 'time'

Then a template trigger can look like that :

- platform: template
  value_template: "{{ (states.input_datetime.alarm_clock.attributes['timestamp'] | timestamp_custom('%H:%M', False) ) == ( states.sensor.time.state ) }} "

In this example, the automation triggers when the current time reaches an input_datetime that I use to store the alarm time for the day.

needs to be ‘/1’

1 Like

Thanks! Switched to \1, still no go. Nothing interesting in the logs either. This is weird.

It needs to be minutes: ‘/1’ not \1

Sorry, I meant to say /1.

Ok, then it’s not the trigger that wrong it’s the condition, I would put it like you have it in the test template version i.e. states.sensor.soverom_temperature.last_updated

that condition is wrong.

value_template for numeric_states is ment to pull out the value, not return a true/false. You’re using it wrong. I understand what you want as well and unfortunately, it’s not possible unless you make a template sensor and trigger off that.

binary_sensor:
  - platform: template
    sensors:
      soverom_temperature:
        value_template: "{{ states('sensor.soverom_temperature') | float >= 5 }}"

then do this trigger. (you won’t need to math it out now).

- alias: Bedroom temperature sensor has old data
  trigger:
    - platform: state
      entity_id: binary_sensor.soverom_temperature
      state: 'on'
      for:
        minute: 1
  action:
    - service: notify.pushover
      data:
        title: "Sensor warning"
        message: "Temperaturmåling på soverommet er 1 minutter gammel"

This will only fire once and never again until it drops below 5 and then above for another minute.

If you want it to fire continuously:

- alias: Bedroom temperature sensor has old data
  trigger:
    - platform: time
      minutes: '\1'
      seconds: 00 #this is needed
  condition:
    - condition: template
      value_template: > 
        {% if is_state('binary_sensor.soverom_temperature','on') %}
          {% if states.binary_sensor.soverom_temperature.last_updated is defined %}
            {{ (as_timestamp(now()) - as_timestamp(states.binary_sensor.soverom_temperature.last_updated)) / 60 }}
          {% else %}
            False
          {% endif %}
        {% else %}
           False
        {% endif %}
  action:
    - service: notify.pushover
      data:
        title: "Sensor warning"
        message: "Temperaturmåling på soverommet er {{ ((as_timestamp(now()) - as_timestamp(states.binary_sensor.soverom_temperature.last_updated)) / 60) | int }} minutter gammel"

EDIT: Editing this because I had a miss-understanding on the original intent. For anyone that stumbles upon this, this will check an verify that the temperature is above 5. If it has been above 5 for 1 minute, it will send the message. OP is just trying to find out if the sensor has changed in the last five minutes.

Thanks, but something seems wrong:

Invalid config for [automation]: [state] is an invalid option for [automation]. Check: automation->trigger->0->state

Also, I’m unsure what states('sensor.soverom_temperature') returns?

You can check in the developer tools, templates.
Enter {{ states.sensor.soverom_temperature.state }}

I guess the “last_updated” is accessible as an attribute
{{ states.Sensor.soverom_temperature.attributes[‘last_updated’] }}

For instance, this is what I get with a weather sensor, in templates.

The state bring the temperature :

{{ states.sensor.m_temperature.state }}
3

Other attributes:

{{ states.sensor.m_temperature.attributes }}

{'attribution': 'Weather details provided by Yahoo! Inc.', 'unit_of_measurement': '°C', 'friendly_name': '° Actuel', 'custom_ui_state_card': 'state-card-custom-ui', 'state_card_mode': 'badges'}

That returns the state from the sensor. There are multiple ways to grab a state.

anyways, the error about the state is because I made a typo. this should be the automation:

- alias: Bedroom temperature sensor has old data
  trigger:
    - platform: state
      entity_id: binary_sensor.soverom_temperature
      to: 'on'
      for:
        minute: 1
  action:
    - service: notify.pushover
      data:
        title: "Sensor warning"
        message: "Temperaturmåling på soverommet er 1 minutter gammel"

That’s what I thought, but I’m not interested in the state/temperature, as you see in the original posting. I’m interested in detecting if a sensor doesn’t send data anymore (e.g. when the battery is dead). So I’m not sure why I would need to check if states('sensor.soverom_temperature') is larger than 5?

Then this should return the attribute you’re looking for (see my post above) :
states.sensor.soverom_temperature.attributes[‘last_updated’]

I still don’t think you understand what is happening here. That’s the template sensor. All that template sensor is doing is creating a binary_sensor that will be true or false if the value is above 5.

binary_sensor:
  - platform: template
    sensors:
      soverom_temperature:
        value_template: "{{ states('sensor.soverom_temperature') | float >= 5 }}"

This was done because of your original requirement here (wanting the value to be above 5).

As I said in my post. That condition is NOT possible. A numeric state value_template cannot be used as a true/false condition.

So, combining the template sensor and automation we get that conditions functionality.

That’s also wrong… last_updated is not a attribute. Last updated is a property on the state object.

states.sensor.soverom_temperature.last_updated

If you are trying to say “above 5 minutes” then the automation is simply:

- alias: Bedroom temperature sensor has old data
  trigger:
    - platform: time
      minutes: '\1'
      seconds: 00 #this is needed
  condition:
    - condition: template
      value_template: > 
        {% if states.sensor.soverom_temperature.last_updated is defined %}
          {{ ((as_timestamp(now()) - as_timestamp(states.sensor.soverom_temperature.last_updated)) / 60) >= 5 }}
        {% else %}
          False
        {% endif %}
  action:
    - service: notify.pushover
      data:
        title: "Sensor warning"
        message: "Temperaturmåling på soverommet er {{ ((as_timestamp(now()) - as_timestamp(states.sensor.soverom_temperature.last_updated)) / 60) | int }} minutter gammel"

EDIT: Also there’s this method too:

- alias: Bedroom temperature sensor has old data
  trigger:
    - platform: time
      minutes: '\1'
      seconds: 00 #this is needed
  condition:
    - condition: template
      value_template: > 
        {% if states.sensor.soverom_temperature.last_updated is defined %}
          {{ (now() - states.sensor.soverom_temperature.last_updated).seconds / 60 >= 5 }}
        {% else %}
          False
        {% endif %}
  action:
    - service: notify.pushover
      data:
        title: "Sensor warning"
        message: "Temperaturmåling på soverommet er {{ ((now() - states.sensor.soverom_temperature.last_updated).seconds / 60) | int }} minutter gammel"

No, I checked that ((now() - last_updated) / 60) > 5, which yields true if the last update was more than five minutes ago.

According to the documentation at Conditions - Home Assistant it can be used as a true/false condition:

condition:
  condition: numeric_state
  entity_id: sensor.temperature
  above: 17
  below: 25
  # If your sensor value needs to be adjusted
  value_template: {{ float(state.state) + 2 }}

The problem is that I use now(), not the numeric_state as such.

Yes the whole condition will, not the value template. Read the documentation again.

pulled directly from the documentation:

You can ONLY process the value of the state, not provide a true/false response.

EDIT: I.E. Anything in value_template template {{}} has to resolve to a numerical result, either a float or an integer.