What am I doing wrong? (TTS with restore of previous state)

Hi,
I hope somebody can help me. What am I doing wrong?
During the last day I managed to write my first script, to put a TTS message to one of my speakers and try to restore the speaker state afterwards.

sequence:
  - if:
      - condition: template
        value_template: "{% set WasOff=is_state( Player ,'off') %}{{WasOff}}"
    then:
      - service: media_player.turn_on
        data: {}
        target:
          entity_id: "{{Player}}"
      - wait_template: "{{ is_state( Player,'playing') }}"
        timeout: 3
  - service: script.mediaplayer_snapshot
    data: {}
  - if:
      - condition: template
        value_template: "{{ is_state( Player ,'playing') }}"
    then:
      - service: media_player.media_stop
        data: {}
        target:
          entity_id: "{{Player}}"
  - wait_template: "{{ is_state( Player,'idle') }}"
    timeout: 10
  - service: media_player.volume_set
    data:
      volume_level: 0.25
    target:
      entity_id: "{{Player}}"
  - service: tts.google_translate_say
    data:
      entity_id: "{{Player}}"
      message: "{{Nachricht}}"
  - wait_template: "{{ is_state( Player,'playing') }}"
    timeout: 10
  - wait_template: "{{ is_state( Player,'idle') }}"
    timeout: 40
  - service: script.mediaplayer_restore
    data: {}
  - if:
      - condition: template
        value_template: "{{WasOff}}"
    then:
      - delay: 5
      - service: media_player.turn_off
        data: {}
        target:
          entity_id: "{{Player}}"
mode: single

My problem is the Variable “WasOff” which should reflect the power state of the speaker. The variable “Player” contains the entityID of the speaker and is consistent through the whole script.
The problem that I try to solve is that the snapshot function doesn’t store the speakers mode (input) when the speaker is off, when creating the snapshot.
So my goal was to switch it on so the the input is active, snapshot the state and switch it off afterwards, when I had to switched it on, before the snapshot.
The problem is, that the variable “WasOff” never seems to reflect the state at the end of the script.
I am at a loss, can somebody with more knowledge than me help please?
Cheers

1 Like

Ok, It took me another few hours to find out about the scope of variables in scripts.
So they seem to be useless to store temporary states.

I used a boolean helper instead and that works. It’s just outside the script and I don’t like it.

Is there any other way?

You defined WasOff as a Jinja2 variable, not as a script variable. The scope of a Jinja2 variable is even more restricted than a script variable.

Define the script variable at the top of the script and its scope will be the entire script. Note that script variables are defined in lower-case.

sequence:
  - variables:
      wasoff: "{{ is_state(Player, 'off') }}"
  - if:
      - condition: template
        value_template: "{{ wasoff }}"
    then:
      - service: media_player.turn_on
        data: {}
   ... the rest of your script ...

hello @umtauscher ,
When have this working would you mind your finished project, or maybe create a blueprint for it.
I would love to use it myself as well.

thanks anyway.

1 Like

You can use this existing script blueprint or modify it to do exactly what you want.

1 Like

@Taras
Thanks, but I don’t have sonos speakers and I already experienced, that the mediaplayer interface is not the same using different manufacturers. For exaple SONOS speakers have the state “paused” when beeing idle, Yamaha Musiccast has the state ‘idle’ or ‘off’
I have a Yamaha-Musicast setup.

@ nielsnl68 Sure, I will post my script as soon as I have tested it sufficiently. I am far from putting it into a blueprint.
Cheers

Actually, my response was intended for nielsnl68. In addition, regardless of the speaker’s integration, the linked script also serves as an example of how to use script variables correctly. If nielsnl68 isn’t using Sonos speakers, the script blueprint can be easily modified as needed.

Did you try the script variable example I posted above? Any questions about the difference between Jinja2 variables and script variables?

i also do not use those way to expansive sonos speakers, i just received my espaudio Muze proto board from raspiaudio.com.

Like I said in my previous post, it doesn’t matter if you are not using Sonos speakers. The linked script blueprint can be easily modified to work with whatever media_player integration you are using. If you don’t want to modify it, just search for other examples of resuming music after a TTS message because there are many of them.

https://community.home-assistant.io/search?q=Resume%20music%20

1 Like

@Taras
I tested the mentioned automation and it didn’t work. I even could not select any of my speakers.
I will continue with mine. Thanks
@nilesnl68
If you are still interrested, I append my script that is working now for me.
I didn’t parameterize the TTS Engine and the speak-volume, but since you have the script you could easily modify it.
Maybe there is a way to automaticcal select the standard TTS engine?

fields:
  Nachricht:
    name: Nachricht
    description: The text to be spoken
    required: true
    selector:
      text: null
  Player:
    name: Player
    description: Entity of the player (loudspeaker)
    required: true
    selector:
      entity:
        domain: media_player
sequence:
  - variables:
      wasoff: "{{ is_state(Player, 'off') }}"
  - if:
      - condition: template
        value_template: "{{ wasoff }}"
    then:
      - service: media_player.turn_on
        data: {}
        target:
          entity_id: "{{Player}}"
      - wait_template: "{{ is_state( Player,'playing') }}"
        timeout: 3
  - service: script.mediaplayer_snapshot
    data: {}
  - if:
      - condition: template
        value_template: "{{ is_state( Player ,'playing') }}"
    then:
      - service: media_player.media_stop
        data: {}
        target:
          entity_id: "{{Player}}"
  - wait_template: "{{ is_state( Player,'idle') or is_state( Player,'paused') }}"
    timeout: 10
  - service: media_player.volume_set
    data:
      volume_level: 0.55
    target:
      entity_id: "{{Player}}"
  - delay: 1
  - service: tts.google_translate_say
    data:
      entity_id: "{{Player}}"
      message: "{{Nachricht}}"
  - wait_template: "{{ is_state( Player,'playing') }}"
    timeout: 10
  - wait_template: "{{ is_state( Player,'idle') or is_state( Player,'paused') }}"
    timeout: 40
  - service: script.mediaplayer_restore
    data: {}
  - if:
      - condition: template
        value_template: "{{wasoff}}"
    then:
      - delay: 1
      - service: media_player.turn_off
        data: {}
        target:
          entity_id: "{{Player}}"
mode: queued
icon: mdi:volume-high
max: 10

This one is tested with Yamaha musiccast and Sonos speaker
Cheers

Glad to hear that the correct use of variables that I had suggested has corrected the problem you reported.

Please consider marking my post above with the Solution tag (only the topic’s author can mark one post). 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 other users find answers to similar questions.

For more information, refer to guideline 21 in the FAQ.

Sorry, I forgot the 2 subscripts

alias: Mediaplayer Restore
sequence:
  - service: scene.turn_on
    target:
      entity_id: scene.musiccast_snapshot
    metadata: {}
mode: single
icon: mdi:speaker
alias: Mediaplayer Snapshot
sequence:
  - service: scene.create
    data:
      scene_id: musiccast_snapshot
      snapshot_entities: >-
        media_player.kueche1, media_player.kueche2, media_player.wilhelms_buro,
        media_player.badezimmer, media_player.verstarker_schlafzimmer,
        media_player.wohnzimmer_rx_2050
mode: single
icon: mdi:speaker

You have to put all your speakers in that one.

@taras
Thanks for your help. It took me while to realize, that the variable never has to change during the script. So I got rid of the binary helper.

1 Like

That’s because the author of that blueprint used a feature of the Entity Selector that allows you to restrict displayed entities to a specific domain and integration.

    selector:
      entity:
        domain: media_player
        integration: sonos

The integration is set to sonos so the selector will only display media_players based on the Sonos integration. Entity Selector can also constrain the selection by device_class.

Or just create a group and loop through that. Or loop through a states.media_player.<...> template

Hey @123 , was just reading through this; I wrote the script you linked to. Nice breakdown of what I did and why. My script is definitely written for Sonos but I tried to document it to make it easy for people to adapt it or learn from it.

Anyhow, just wanted to send out a small shout-out / thanks