Wait template with script field/variable

Hello! I created one script with two fields: light and mode. I use these to apply effects to some lights.

Before any effect though, I created an scene to save the previous state:

service: scene.create
data:
  scene_id: "{{ slugify(light) }}_snapshot_{{ slugify(mode) }}"
  snapshot_entities: "{{ light }}"
alias: Save original state

Immediately after the scene, I’m sending a variety of effects based on mode.
And then I’ll call the previously created scene like this:

service: scene.turn_on
target:
  entity_id: scene.{{slugify(light)}}_snapshot_{{ slugify(mode) }}
alias: Restore original state

But I’m facing one problem with two lights: Sometimes the effect starts up before the scene is created and that means the original state is lost.
Instead of adding 1~3 seconds delay after scene.create, I wanted to use a wait template, like this:

wait_template: >-
  {{ as_timestamp(now()) -
  as_timestamp(states('scene.'~slugify('light.bad_cloud_bad_choice)~'_snapshot_'~slugify('notify')))
  > 0}}
continue_on_timeout: true
timeout: "00:00:05"

The template above works nicely with fixed entities but I’m having trouble making the template work with the script fields:

wait_template: >-
  {{ as_timestamp(now()) -
  as_timestamp(states('scene.'~slugify(light)~'_snapshot_'~slugify(mode)))
  > 0}}
continue_on_timeout: true
timeout: "00:00:05"
[139772959912000] Error handling message: In 'template' condition: ValueError: Template error: as_timestamp got invalid input 'unknown' when rendering template '{{ as_timestamp(now()) - as_timestamp(states('scene.'~slugify(light)~'_snapshot_'~slugify(mode))) > 0}}' but no default was specified (unknown_error)

I’m outside of my depth here, anyone can help me out?

I added the entire script here.

Create a script variable containing a unique name for the scene entity. I suggest using the current time, as a timestamp, because it’s an easy way to get a unique value.

alias: Lights - Apply effects
sequence:
  - variables:
      s_id: '{{ now().timestamp() | string | slugify }}'
      e_id: 'scene.{{ s_id }}'
  - choose: []
    default:
      - service: scene.create
        data:
          scene_id: "{{ s_id }}"
          snapshot_entities: "{{ light }}"
        alias: Save original state
      - wait_template: >-
          {{ now().timestamp() - states(e_id) | as_timestamp > 0 }}
        continue_on_timeout: true
        timeout: "00:00:05"

      ... etc ...

      - service: scene.turn_on
        target:
          entity_id: '{{ e_id }}'
        alias: Restore original state

  ... etc ...

NOTE

I’m not sure why you’re using a choose statement without any conditions (the first choose) but that’s a separate discussion (so I left it as-is).


EDIT

Correction. Replaced oid with s_id.

1 Like

Hello and thanks for the help!

I’m not sure why you’re using a choose statement without any conditions (the first choose ) but that’s a separate discussion (so I left it as-is).

The original script has more things, but I figured I would just leave the relevant parts.

I applied the changes as suggested and updated the gist but I get pretty much the same error:

Logger: homeassistant.components.script.lights_apply_effects
Source: helpers/script.py:409
Integration: Scripts (documentation, issues)
First occurred: 16:52:49 (2 occurrences)
Last logged: 16:52:49

Lights - Apply effects: Choose at step 2: default: Error executing script. Error for wait_template at pos 2: In 'template' condition: ValueError: Template error: as_timestamp got invalid input 'unknown' when rendering template '{{ now().timestamp() - states(e_id) | as_timestamp > 0 }}' but no default was specified
Lights - Apply effects: Error executing script. Error for choose at pos 2: In 'template' condition: ValueError: Template error: as_timestamp got invalid input 'unknown' when rendering template '{{ now().timestamp() - states(e_id) | as_timestamp > 0 }}' but no default was specified

It’s like the wait template action is not capable of reading the variables!

That’s due to a typo I made in the second script variable’s definition.

Replace this:

      e_id: 'scene.{{ oid }}'

with this:

      e_id: 'scene.{{ s_id }}'

To make as_timestamp more robust, it should be supplied with a default value. If it can’t convert the supplied value to a timestamp it will report the default value (as opposed to failing with an error).

      - wait_template: >-
          {{ now().timestamp() - states(e_id) | as_timestamp(default = now().timestamp()) > 0 }}
1 Like

Thanks for the help! I just did a minor change on the default value and it’s working great now!

1 Like