SONOS TTS Script

Anytime! I had another thread I started for finding travel time from a google calendar and creating an alert when it’s time to leave. I built on that quite a bit so I may add to that thread, I’ll send you the link in a PM. Probably won’t have time to post for a day or so but I will send it to you.

I’m not using Exchange for my google calendar. But I do use iCloud predominantly and I find that creating a iCal link and imported into Google does seem to work just fine. It syncs only every 12 hours or so but it does work.

So I’m using this script for my TTS and it works great if I want only one speaker to talk, now Im thinking I would like to create a group for certain things, not sure how to modify

TTS Script

 - sonos_say:
    alias: "Sonos TTS script"
    sequence:
     - service: media_player.sonos_snapshot
       data_template:
         entity_id: "{{ sonos_entity }}"
     - service: media_player.sonos_unjoin
       data_template:
         entity_id: "{{ sonos_entity }}"
     - service: media_player.volume_set
       data_template:
         entity_id: "{{ sonos_entity }}"
         volume_level: "{{ volume }}"
     - service: tts.google_say
       data_template:
         entity_id: "{{ sonos_entity }}"
         message: "{{ message }}"
     - delay: "{{ delay }}"
     - service: media_player.sonos_restore
       data_template:
         entity_id: "{{ sonos_entity }}"

Does anyone know if there is a way to set a number of random messages for ‘What’ in the automation? It would be good to have a number of random messages.

1 Like

How can I add a state variable at the message field, such that the message is something like

what: "Temperature is {{states('sensor.now_temperature')}}."

I can’t seem to pass the sensor variable…

Try “Temperature is {{ states.sensor.now_temperature.state }}.”

1 Like

Thanks. That, plus switching to

`data_template`

instead of

`data`

on the automation side worked!

1 Like

Does anyone have any audio sync issues with multiple Sonos speakers? It seems like they all don’t start at the same time so there is an echo.

1 Like

You need to join them first and then set the message to play to the group, not specific speakers.

1 Like

@CtrlX Thanks! I was joining the ones I wanted then also had them all defined in the tts.google_say service definition. If I would have read the script a little closer I would have noticed that only the master is defined there.

Appreciate it!

I would also like to have that feature. Additionally, I am interested in how you organize your messages in your config to have them use states of sensor etc.

Hi Guys

I have read most of this thread and various others. Having spent two days unsuccessfully trying to get the SONOS TTS service to work I am hoping someone here can point me in the right direction.

Currently I have followed the script in Post #1, as follows

# > SONOS TTS
  say:
    alias: Sonos Text To Speech
    sequence:
      - service: media_player.sonos_snapshot
        entity_id: media_player.den
      - delay: '00:00:07'    
      - service: media_player.volume_set
        entity_id: media_player.den
        data:  
          volume_level: 0.50
    #  - service: media_player.select_source
     #   data_template:
    #      entity_id:
   #         - media_player.den
   #       source: Hei!
      - service: tts.google_say
        entity_id: media_player.den
        data:
          message: "Good Morning"
      # Add a delay in a length which you think fits best for all the things you want to say over TTS
      - delay: '00:00:30'
      - service: media_player.sonos_restore
        entity_id: media_player.den

My automation simply calls the script as follows

 - alias: Notification Audio - Good morning weekday
    trigger:
      - platform: time
        at: '07:10:00'
    action:
      #- delay: '00:00:30'
      - service: script.turn_on
        entity_id: script.say

Unfortunately, I hear nothing at the designated time or if I trigger the automation manually.

Any ideas? One thought I had reading other threads was my Fritzbox router could be an issue due to loopback NAT, but not really investigated that in any detail

Any help most welcome

I think you need “data_template:” instead of “data:”

Also, in the automation, “entity_id” should be the player, the script should be the service you want to use.

I have mine configured following the doc and it works great.

Thanks for the tip.

Just tried the configuration using VOICERSS. Still nothing.

I do not know if it is relevant, but this is a random error that I am getting the home-assistant log.

2017-12-10 22:51:42 ERROR (MainThread) [aiohttp.access] Error in logging
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/aiohttp/helpers.py", line 554, in __get__
    return inst._cache[self.name]
KeyError: 'remote'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/aiohttp/helpers.py", line 521, in log
    for key, value in fmt_info:
  File "/usr/lib/python3.6/site-packages/aiohttp/helpers.py", line 513, in <genexpr>
    for key, method in self._methods)
  File "/usr/lib/python3.6/site-packages/aiohttp/helpers.py", line 473, in _format_a
    ip = request.remote
  File "/usr/lib/python3.6/site-packages/aiohttp/helpers.py", line 556, in __get__
    val = self.wrapped(inst)
  File "/usr/lib/python3.6/site-packages/aiohttp/web_request.py", line 319, in remote
    peername = transport.get_extra_info('peername')
  File "/usr/lib/python3.6/asyncio/sslproto.py", line 306, in get_extra_info
    return self._ssl_protocol._get_extra_info(name, default)
  File "/usr/lib/python3.6/asyncio/sslproto.py", line 547, in _get_extra_info
    return self._transport.get_extra_info(name, default)
AttributeError: 'NoneType' object has no attribute 'get_extra_info'

Also I am using HASS.IO and Lets Encrypt.

Did you try using it in an automation only just to see if it works?

Edited CP, from mine:

- alias: TTS Test
  trigger:
  - platform: time
    at: '07:10:00'
  action:
  - service: media_player.sonos_snapshot
    data_template:
      entity_id: media_player.den
      with_group: true
  - service: media_player.sonos_unjoin
    data_template:
      entity_id: media_player.den
  - service: media_player.volume_set
    data_template:
      entity_id: media_player.den
      volume_level: 0
  - service: media_player.volume_set
    data_template:
      entity_id: media_player.den
      volume_level: 0.6
  - service: tts.voicerss_say
    data_template:
      entity_id: media_player.den
      message: This is a test!
  - delay:
      seconds: 2
  - delay: "{% set duration = states.media_player.den.attributes.media_duration\
      \ %} {% if duration > 0 %}\n  {% set duration = duration - 1 %}\n{% endif %}\
      \ {% set seconds = duration % 60 %} {% set minutes = (duration / 60)|int % 60\
      \ %} {% set hours = (duration / 3600)|int %} {{ \"%02i:%02i:%02i\"|format(hours,\
      \ minutes, seconds)}}"
  - service: media_player.sonos_restore
    data_template:
      entity_id: media_player.den
      with_group: true

I will give it a go. I’ll let you know how I get on.

:cry: No luck. Still silence!

NEW UPDATE

Whilst testing the automation only, I see that a filename comes up in SONOS on Home Assistant. Something along the lines of

3ef4457…75dfc1991-en-US_voicerss.mp3. If I try to play this from my the web browser on my phone, I get the message Unable to play 3ef4457…75dfc1991-en-US_voicerss.mp3 unable to connect to xxxxx.duckdns.org

Not sure that it is significant, but I’ll take it as progress.

Any thoughts?

Yes, it creates a file in the TTS directory.

It should display the text you you put in as the message.

Maybe something to do with your duckdns, I’m using Amazon Polly without duckdns, so not sure what else needs to be checked.

1 Like

SOLVED

After a little bit of digging I realised that I had changed the port that I was using for xxxxx.duckdns.org. Made the necessary changes in base_url and bingo TTS is working :grinning:

Thanks for the tips!

:+1: Great.