Variable is Undefined

Sorry if I post this in the wrong section, it’s late and I’m losing my mind.

Haven’t used variables before, but they seemed pretty straight forward.
Here’s my code:

- alias: "Repeat Until Sensors Update"
  repeat:
    sequence:
      - delay:
          seconds: 5
      - variables: 
          stamp: "{{ as_timestamp(now()) - as_timestamp(states.sensor.ryan_s_iphone_11_last_update_trigger.last_changed) | int }}"
    while:
      - condition: template
        value_template: "{{ stamp >= 60 }}"
      - condition: template
        value_template: "{{ repeat.index <= 25 }}"

and here’s the error message when I run the script:
Error: In ‘template’ condition: UndefinedError: ‘stamp’ is undefined

I’ve tried everything I can think of, but no success.
It’s probably something simple (I hope)
Appreciate any help you can provide.

What about this version?


sequence:
  - variables:
      stamp: >-
        {{ as_timestamp(now()) -
        as_timestamp(states.sensor.ryan_s_iphone_11_last_update_trigger.last_changed)}}
  - repeat:
      sequence:
        - delay:
            seconds: 5
      while:
        - condition: template
          value_template: '{{ stamp >= 60 }}'
        - condition: template
          value_template: '{{ repeat.index <= 25 }}'

Show how you are calling the script and passing the value of stamp.

@pedolsky
Appreciate the try, but I want/need to recalculate the value of Stamp through each loop (it’s the only reason for the loop in the first place).

@123 Taras
I’m not passing stamp, I am defining stamp in the loop (it’s in the code)

Oops! My mistake. :man_facepalming:

123 has left the chat … :wink:

Probably a scope issue. The scope of the variable’s value within the loop is not visible outside the loop (namely in the while condition)

I would have thought that the “while condition” was part of the loop as it has to check those conditions each time through the loop in order to know when to exit the loop. Plus, maybe I don’t understand variables in Home Assistant well enough, but I would have thought that any variable I create using this method would be available throughout the script they were created in.

It’s not.

The example in your first post defines a variable inside the repeat. That means its scope is limited to within the repeat. In pedolsky’s example, the variable is defined outside of the repeat so its scope is everything after the line where it’s defined.

The repeat has to evaluate the condition in while before it begins to execute sequence. In your example, stamp isn’t defined yet and only exists within sequence.

I recommend you review this section of the Scripting documentation: Scope of variables

Would this work for you. You may recalculate “stamp” more often. That or make it a sensor that will calculate once a minute.

sequence:
  - repeat:
      sequence:
        - delay:
            seconds: 5
      while:
        - condition: template
          value_template: >- 
            '{{  as_timestamp(now()) - 
                 as_timestamp(states.sensor.ryan_s_iphone_11_last_update_trigger.last_changed) >= 60 }}'
        - condition: template
          value_template: '{{ repeat.index <= 25 }}'

@rjing001
The example you posted just seems to kill time waiting for the calculation’s result to decrease below 60 seconds. It waits for a maximum of 5 x 25 = 125 seconds. Why not just use a wait_template with a timeout?

wait_template: "{{ now() - states.sensor.ryan_s_iphone_11_last_update_trigger.last_changed < timedelta(minutes=1) }}"
timeout: '00:02:05'

Yeah, I stumbled on that a couple hours after I made that comment. Make’s my head hurt. But I do appreciate you pointing it out.

Hey thanks @AllHailJ for the input, I’ll try that when I get a chance. But right now I’ve hit a roadblock. I’m using a request_location_update notification to try and force an update (hence the loop to wait for the update) and it has stopped responding. Not sure why. The documentation said it’s hit and miss but it was initially working. Until I can get it to respond, I’m stuck because the template will never update. If anyone has any ideas, I’m all ears.

Thanks again @123. Yeah I tried a wait for trigger initially, but the calculation never updated in the script, even though I was seeing it update in the Developer Tools Template screen. But, it is slightly different than my first try. So, if I can get my other issue to resolve itself, I’ll try this as well. (see post above)

The template I posted above is evaluated every minute, because now() updates every minute, and whenever the value of last_changed changes.

When either of the two causes the template to update, if the calculated result is less than 1 minute, the template’s reports true and the wait_template finishes waiting. If it fails to evaluate to true within the timeout period, it times out and continues executing whatever actions that may come after it (if any).

Because timeout is just over 2 minutes, you can expect a minimum of two evaluations to be performed (because now() causes an update every minute). There will be more evaluations if the value of last_changed changes during that time period.