Attempting to TTS attributes from weather.home entity

Apologies for such a rudimentary question, but have been banging my noob head into the brick wall of assumed knowledge for over a day and a half so far just trying to read the current temperature on a Sonos from attributes within the weather.home entity.

I’m using a Docker image on a QNAP nas and currently lack the skill to have anything beyond the stock “stable” release as it was auto installed a few days ago. (v2021.12.7)

I have attempted to copy the appropriate syntax from several examples, but while the Automation itself is now working reasonably reliably - the temperature is always “unknown” by the time TTS has finished with it.

The relevant automation is set up as this:

alias: Nightcast
description: ''
trigger:
  - platform: time
    at: '22:40:00'
condition: []
action:
  - service: sonos.snapshot
    data:
      entity_id: media_player.study
  - service: sonos.unjoin
    target:
      entity_id: media_player.study
  - service: media_player.volume_set
    target:
      entity_id: media_player.study
    data:
      volume_level: 0.3
  - service: tts.picotts_say
    data:
      entity_id: media_player.study
      message: >-
        Good evening. It is {{states('weather.home')}} outside. Current
        temperature is {{states('weather.home_attributes.temperature')}}. The
        forecast minimum overnight is
        {{states('weather.home_attributes.templow')|round}}.
  - delay:
      hours: 0
      minutes: 0
      seconds: 8
      milliseconds: 0
  - service: sonos.restore
    data:
      entity_id: media_player.study
mode: single

I’m working on the assumption there is still a syntax issue in referencing the attribute, but have tried everything I have been able to find by googling the question, and trying every combination I can think of based on a yaml primer syntax reference I found elsewhere as well - all to no avail.

Also, the time delay was copied in because someone else’s implementation used it - but the logic of this also escapes me. If the time delay is too short, the TTS message get cut short, but then the same delay seems to repeat again after the TTS message is complete before the sonos.restore service is called. Logic suggests (at least to me) that one action should complete before the next action is initiated - which would render the time delay obsolete. Experience shows that my logic is incorrect, but I don’t understand why…

Any pointers to aid my understanding would be warmly received. Making it work is clearly an objective, but understanding why it doesn’t already is a higher priority for me right now.

Thanks in anticipation

1 Like

To get the value of an entity’s attribute, use the state_attr function.

{{ state_attr('weather.home', 'temperature') }}

Generally speaking, when you start playing media, the command to begin playing the media executes and finishes instantly. The actual playing of the media will take a certain amount of time to complete but the command to begin playing it finishes instantly. That’s why there’s a delay in your automation, to give time to complete the playing of the TTS message before the sonos.restore command is executed.

What’s better than a fixed delay is a wait_for_trigger that waits for the media_player’s state to change from playing to idle.

1 Like

Thanks @123 Taras. The ‘state_attr’ function does seem to overcome the initial syntax problem.

It seems however only to be able to address the first set of attributes. The first occurrence of the “templow” attribute is in the forecast for the next day - which appears to be beyond the scope of the function?

I had not seen any reference to this function in any of my googling. Where does one find the authoritative reference of function and syntax as it applies to Home Assistant? Posting perpetual noob questions is likely to frustrate me even more than your good selves, and I would much rather go to a source of truth to find out for myself. The on-line documentation does seem to be very strong on “you can do this”, but quite light on “this is how to accomplish it”.

I did manage to change the fixed delay to a wait_for_trigger event, but initially had trouble getting it to work. Found that the media player state after the playlist completes is paused rather than idle - and it was only dumb luck that I found the state label in the Developer Tools section…

Is there an If-Then conditional structure that can be used in the action list? Eg If temperature is above X degrees then say “open the window” (trivial example I know :slight_smile: )

Many thanks,

yes.

Have you seen this:

there are examples of the “if-else-endif” structure.

Be aware tho that the structure for more than one if is “if-elif-else-endif”.

and tho it’s better to use it, “else” use isn’t technically required.

so you could use “if-endif” or “if-elif-endif”

But this might be more useful in this case (no templating required):

1 Like

It’s well within the function’s ability but the key to success here is to understand how the data within forecast is structured.

All of the screenshots below are from the Template Editor.

The forecast attribute contains a data structure known as a list.

Each item in the list is a data structure known as a dictionary and each one contains 5 keys (with 5 associated values). The items in the list can be retrieved via their index number and the numbering begins with zero.

If I want the templow key in the first (zeroth) item, it can be retrieved like this:

Yes, that’s correct. I had indicated idle but that state typically occurs after the media_player has been paused for a long time (but some media_players change to off). I’m glad to hear you figured this out on your own. For users who don’t know what we are talking about, the following example waits until the media_player has finished playing its media (state changes from playing to paused) before continuing:

      - wait_for_trigger:
          - platform: state
            entity_id: media_player.whatever
            from: 'playing'
            to: 'paused'
5 Likes

Many thanks - all perfectly logical once the constraints of the system are grasped. :smile: )

The next branch of this little exercise is to conditionally select between two different TTS services on that basis of network status. I have a sensor in my modem that reports up / down status of my internet connection, and have built two automatons that trigger respectively on an “up to down” transition, and on a “down to up” transition. Both automatons issue a TTS notification, and change the state of a helper called speak_easy (dropdown type) to the name of one of two TTS services (one on-line and the other off-line).

My current goal is to use the state of the helper to determine which TTS service to call. I was hoping something as simple as…

service: helper.speak_easy

would trigger the right service - but it didn’t. I will start playing with the if-then-else structure to see if I can make that work, but is there a syntactic structure where a helper can just be substituted as a variable directly into the service call?

If the original question was answered, mark the post that supplied the answer with the Solution tag.

Create a separate post for “The next branch of this little exercise”. This helps to keep each topic focused and helps users find answers to similar, specific, questions. Otherwise, your question about how to “conditionally select between two different TTS services” will be buried in a topic about how to get “TTS attributes from weather.home entity”.