I need some help with my script (noob warning)

i have a script that handles how my alexa speakers makes announcements.
i call the script from my automations and can supply variables to the script so it knows which alexa device to play the notification and sets the speaker volume for the notification.

in my automation i call the service to run the script like so:

service: script.alexa_announce_gate_left_open
data:
  speaker_device: media_player.echo_show
  speaker_service: notify.alexa_media
  announce_volume: 0.4

i’m trying to improve the script further by adding a room occupancy variable so that the announcement plays if someone is in that room. if there was nobody it waits until someone enters the room unless the alarm was already cleared.

so i added a condition in the script that checks the state of the particular speaker’s room occupancy boolean.
the script works fine if I use the actual boolean name ie input_boolean.room_occupancy_study, but I need that to be ‘{{ speaker_room }}’. However I get the error Message malformed: Entity {{ speaker_room }} is neither a valid entity ID nor a valid UUID for dictionary value @ data[‘sequence’][1][‘if’][0][‘entity_id’]

for a start i was going to have speaker_room as another data variable that the automation passes to the script, but i eventually want to make it more advanced by deriving the correct speaker_room value based on the speaker that is being called. maybe that could be done using a bunch of if/else statements? i haven’t figured out that part yet. i’m taking baby steps.

i’m really not programmer so whatever i’ve done is from googling and copy-pasting. but i’m quite happy with what i could achieve.

here’s the script that i’ve come up with. any pointers would be very much appreciated!

alias: Alexa Announce Gate Left Open
sequence:
  - variables:
      gate_open_msg: Someone didn't close the gate
      old_volume: '{{ state_attr(speaker_device,''volume_level'') | float }}'
  - if:
      - condition: state
        entity_id: '{{ speaker_room }}'
        state: 'on'
    then:
      - service: media_player.volume_set
        data:
          volume_level: '{{ announce_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
      - service: '{{ speaker_service }}'
        data:
          data:
            type: tts
          message: '{{ gate_open_msg }}'
          target: '{{ speaker_device }}'
      - service: media_player.volume_set
        data:
          volume_level: '{{ old_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
    else:
      - wait_for_trigger:
          - platform: state
            entity_id:
              - '{{ speaker_room }}'
            to: 'on'
      - condition: state
        entity_id: binary_sensor.zone_gate_open
        state: 'on'
      - service: media_player.volume_set
        data:
          volume_level: '{{ announce_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
      - service: '{{ speaker_service }}'
        data:
          data:
            type: tts
          message: '{{ gate_open_msg }}'
          target: '{{ speaker_device }}'
      - service: media_player.volume_set
        data:
          volume_level: '{{ old_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
mode: parallel
max: 5

State Condition’s entity_id option doesn’t support templates. Use a Template Condition.

      - condition: template
        value_template: '{{ is_state(speaker_room, 'on') }}'

In addition, State Trigger’s entity_id doesn’t support templates.

      - wait_for_trigger:
          - platform: state
            entity_id:
              - '{{ speaker_room }}'  <----- Invalid
            to: 'on'

Consider replacing it with a Template Trigger (or replacing the wait_for_trigger with a wait_template).

wow you’re amazing! i read that page but i never understood what it meant until you pointed to it.

i updated my script and added OR condition to the templates so that the sequence runs as long as the {{ speaker_device }} AND the room it is in is occupied. i didn’t have to use the {{ speaker_room }} variable and that saved me a ton of time!
i didn’t know how to do a template trigger, but your wait_template suggestion was such a good one!

here’s my new script. it works! i’m so pleased! thank you so much!

now i’m going to find out how to make Alexa pause if something else was playing and resume after the announcement.

alias: Alexa Announce Gate Left Open
sequence:
  - variables:
      gate_open_msg: Someone didn't close the gate
      old_volume: '{{ state_attr(speaker_device,''volume_level'') | float }}'
  - if:
      - condition: template
        value_template: >-
          {{ (speaker_device == 'media_player.echo_show' and
          is_state('input_boolean.room_occupancy_study', 'on')) or
          (speaker_device == 'media_player.sonos_beam' and
          is_state('input_boolean.room_occupancy_living_room', 'on'))  }}
    then:
      - service: media_player.volume_set
        data:
          volume_level: '{{ announce_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
      - service: '{{ speaker_service }}'
        data:
          data:
            type: tts
          message: '{{ gate_open_msg }}'
          target: '{{ speaker_device }}'
      - service: media_player.volume_set
        data:
          volume_level: '{{ old_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
    else:
      - wait_template: >-
          {{ (speaker_device == 'media_player.echo_show' and
          is_state('input_boolean.room_occupancy_study', 'on')) or
          (speaker_device == 'media_player.sonos_beam' and
          is_state('input_boolean.room_occupancy_living_room', 'on'))  }}
        continue_on_timeout: true
      - condition: state
        entity_id: binary_sensor.zone_gate_open
        state: 'on'
      - service: media_player.volume_set
        data:
          volume_level: '{{ announce_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
      - service: '{{ speaker_service }}'
        data:
          data:
            type: tts
          message: '{{ gate_open_msg }}'
          target: '{{ speaker_device }}'
      - service: media_player.volume_set
        data:
          volume_level: '{{ old_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
mode: parallel
max: 5
2 Likes

Glad to hear it solved the problem.

Please consider marking my post above with the Solution tag. It will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. This helps users find answers to similar questions. For more information refer to guideline 21 in the FAQ.

1 Like

hi! hope you don’t mind, i tried defining a variable for my condition template and wait_template (since they are exactly the same) but it doesn’t seem to work for the wait_template. it works fine for the condition template. is there something i’m missing?

here’s my script:

alias: Announce Close Gate At Night
sequence:
  - variables:
      speaker_device: media_player.echo_show
      speaker_service: notify.alexa_media
      announce_volume: 0.3
      announcement_msg: '{{ ("1","2","3") | random }}'
      old_volume: '{{ state_attr(speaker_device,''volume_level'') | float }}'
      mediaplayer_State: '{{ states(speaker_device) }}'
      speaker_template: >
        {{ (speaker_device == 'media_player.echo_show' and
        is_state('input_boolean.room_occupancy_study', 'on')) or (speaker_device
        == 'media_player.sonos_beam' and
        is_state('input_boolean.room_occupancy_living_room', 'on')) or
        (speaker_device == 'media_player.kitchen_2' and
        is_state('input_boolean.room_occupancy_kitchen', 'on')) or
        (speaker_device == 'media_player.landing_2' and
        is_state('input_boolean.room_occupancy_1st_floor', 'on')) }}
  - if:
      - condition: template
        value_template: '{{ speaker_template }}'
    then:
      - service: media_player.media_pause
        target:
          entity_id: '{{ speaker_device }}'
      - service: media_player.volume_set
        data:
          volume_level: '{{ announce_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
      - service: '{{ speaker_service }}'
        data:
          data:
            type: tts
          message: '{{ announcement_msg }}'
          target: '{{ speaker_device }}'
      - service: media_player.volume_set
        data:
          volume_level: '{{ old_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
      - condition: template
        value_template: '{{ mediaplayer_State == ''playing'' }}'
      - delay:
          hours: 0
          minutes: 0
          seconds: 10
          milliseconds: 0
      - service: media_player.media_play
        target:
          entity_id: '{{ speaker_device }}'
    else:
      - wait_template: '{{ speaker_template }}'
        timeout: '00:30:00'
        continue_on_timeout: false
      - condition: state
        entity_id: binary_sensor.zone_gate_open
        state: 'on'
      - service: media_player.media_pause
        target:
          entity_id: '{{ speaker_device }}'
      - service: media_player.volume_set
        data:
          volume_level: '{{ announce_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
      - service: '{{ speaker_service }}'
        data:
          data:
            type: tts
          message: '{{ announcement_msg }}'
          target: '{{ speaker_device }}'
      - service: media_player.volume_set
        data:
          volume_level: '{{ old_volume }}'
        target:
          entity_id: '{{ speaker_device }}'
      - condition: template
        value_template: '{{ mediaplayer_State == ''playing'' }}'
      - delay:
          hours: 0
          minutes: 0
          seconds: 10
          milliseconds: 0
      - service: media_player.media_play
        target:
          entity_id: '{{ speaker_device }}'
mode: parallel
max: 5

oh yea the script can also pause and resume music now (if there’s any music playing). feeling pleased with myself!

i think that i can actually remove the entire if block. it is actually exactly the same as the else block aside from the wait_template. so the new script is only half the length. it should work, right?

anyway still trying to figure out how to make the wait_template work with my speaker_template variable

alias: Announce Close Gate At Night
sequence:
  - variables:
      speaker_device: media_player.echo_show
      speaker_service: notify.alexa_media
      announce_volume: 0.3
      announcement_msg: '{{ ("1","2","3") | random }}'
      old_volume: '{{ state_attr(speaker_device,''volume_level'') | float }}'
      mediaplayer_State: '{{ states(speaker_device) }}'
      speaker_template: >-
        {{ (speaker_device == 'media_player.echo_show' and
        is_state('input_boolean.room_occupancy_study', 'on')) or (speaker_device
        == 'media_player.sonos_beam' and
        is_state('input_boolean.room_occupancy_living_room', 'on')) or
        (speaker_device == 'media_player.kitchen_2' and
        is_state('input_boolean.room_occupancy_kitchen', 'on')) or
        (speaker_device == 'media_player.landing_2' and
        is_state('input_boolean.room_occupancy_1st_floor', 'on')) }}
  - wait_template: '{{ speaker_template }}'
    timeout: '00:30:00'
    continue_on_timeout: false
  - condition: state
    entity_id: binary_sensor.zone_gate_open
    state: 'on'
  - service: media_player.media_pause
    target:
      entity_id: '{{ speaker_device }}'
  - service: media_player.volume_set
    data:
      volume_level: '{{ announce_volume }}'
    target:
      entity_id: '{{ speaker_device }}'
  - service: '{{ speaker_service }}'
    data:
      data:
        type: tts
      message: '{{ announcement_msg }}'
      target: '{{ speaker_device }}'
  - service: media_player.volume_set
    data:
      volume_level: '{{ old_volume }}'
    target:
      entity_id: '{{ speaker_device }}'
  - condition: template
    value_template: '{{ mediaplayer_State == ''playing'' }}'
  - delay:
      hours: 0
      minutes: 0
      seconds: 10
      milliseconds: 0
  - service: media_player.media_play
    target:
      entity_id: '{{ speaker_device }}'
mode: parallel
max: 5

i realised i should have started a new topic instead of adding on to this one.

i have reposted my question here:
https://community.home-assistant.io/t/script-using-a-variable-for-wait-template/420244