Automation does not advance after wait_for_template is true

I have been checking the community posts for a working solution to sending out email when a new episode is posted on a website. I first tried a return while condition loop but it seemed to run a set number of times without advancing to the notify action after the loop. I am using a wait_for_template now and it just waits without advancing to the notify action. All of the individual parts work as intended but it never advances past the wait_for_template (template evaluates as true but doesn’t advance). Here is the yaml for the automation and the script used in it.

alias: Search for Latest Episode
description: "Search for latest episode on website"
triggers:
  - trigger: calendar
    entity_id: calendar.full_season_schedule
    event: start
    offset: "0:0:0"
conditions: []
actions:
  - action: script.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: script.get_last_episode
  - wait_template: >-
      {{ states('input_text.last_episode') !=
      states('sensor.latest_episode') | trim }}
    continue_on_timeout: true
  - action: notify.mygmail_gmail_com
    metadata: {}
    data:
      message: >-
        Replay {{ states('sensor.latest_episode') | trim }} at
        "link_to_web_page"
      title: >-
        Latest episode posted {{
        states('sensor.latest_episode') | trim }}
      target:
        - [email protected]
        - [email protected]
      data:
        cc:
          - [email protected]
        bcc:
          - [email protected]
        from: [email protected]
mode: single
`
script.get_last_episode
action: input_text.set_value
target:
  entity_id: input_text.last_episode
data:
  value: "{{states('sensor.latest_episode') | string }}"

Any help with this would be appreciated.
Thank you

A few things I notice:

  • continue_on_timeout is irrelevant because you’re not using any timeouts
  • when storing the value to input_text.last_episode, you’re using | string, but I would think you (also) need | trim

Thank you, I will add the | trim to the script. Strangely wait_for_template as written is waiting but doesn’t move on after the the latest.episode sensor changes and the template evaluates as true. If it was just a format issue caused by not trimming white space wouldn’t it fail to evaluate correctly as the white space would be present in the input text but not on the latest.episode sensor?

How exactly do you conclude it evaluates correctly?

I tested the template in developers template after there was an update at the website and it evaluates as true whereas its false at the start of the calendar event trigger. The traces get to the wait template and stops but never progresses even after evaluating to true. Puzzling.

At which point does the second automation (the one updating input_text.last_episode) run?

The script “get last episode” runs just before the wait template. Initially the input text and sensor state would match but when the website posts the latest episode it evaluates to true (states don’t match) and should then advance to the notify action.

Hmm all I can think of is to add a notification (or logger entry) right before the wait_template that logs the value of the template that you’re using:

- action: system_log.write
  data:
    level: error
    message: "Condition: {{ states('input_text.last_episode') != states('sensor.latest_episode') | trim }}"
- wait_template: ...

Then when the automation triggers, check the system log for this “error” message.

Thank you for the suggestion. I had already used a notification to my mobile app step when I was testing the automation initially and it evaluated as false as it should before the website changes. The wait_for_template should wait until it evaluates as true then continue to the next action. Everything works except the wait_for_template does not advance when the sensor last episode changes. The last episode sensor is populated by scrape. I noticed that for at different times for exactly 10 minutes the sensor changes to unavailable usually once a day.

scrape:
  - resource: https://content_website
    sensor:
      - name: "Latest Episode"
        select: ".short_descr"
        index: 0

Even if it’s unavailable, the condition should still evaluate to true. So I’m not sure what’s going on :thinking:

As a workaround, perhaps it’s possible to split up the automation into two, the first calling the script, the second triggering on sensor.latest_episode changing.

Thanks for your help with this. I added back the notifications ahead of the wait_for _template and it triggered but refuse to advance. I decided that I am missing some basic understanding of how the wait for template works and decided to rewrite the automation to trigger on a state change in the website sensor (excluding unavailable and unknown) against the last sensor value saved in the input text. I will check how it works out and will avoid any future (non) use of wait_for_template.

To be honest, you and me both, because I would expect it to work as you’ve explained.

AFAIK, you don’t necessarily have to check against the last sensor value because sensor triggers only trigger on state changes, so this might be enough:

trigger:
  trigger: state
  entity_id: sensor.latest_episode
  not_to:
    - unavailable
    - unknown
1 Like

This is precisely what I ended doing with the addition of a condtion template and a setting of the input text at the end to compare in the input text. This to make sure the automation doesn’t get past the trigger if the state goes from unavailable or unknown to the unchanged website scrape.

condition: template
value_template: >-
  {{ states('input_text.last_episode') !=
  states('sensor.latest_episode') | string | trim }}
action: input_text.set_value
target:
  entity_id: input_text.last_episode
data:
  value: "{{ states('sensor.latest_episode') | string | trim }}"

Thanks again for your input.

Actually it just occurred to me that maybe I could add a not_from to the trigger so it will only trigger when there is an actual change to the website.

trigger:
  trigger: state
  entity_id: sensor.latest_episode
  not_from:
    - unavailable
    - unknown
  not_to:
    - unavailable
    - unknown