SONOS TTS Script

Okay, I was able to figure out the nuances here. I think I’ve got it. I’m using a similar format to create a recursive script to transition lights that don’t support it natively.

I might be stupid but I can’t get it to work. When i call the test_ttl script nothing happens for me.


configuration.yaml
script: !include_dir_merge_named includes/scripts


scripts/sonos_tts.yaml

sonos_tts:
  alias: Sonos Text To Speech
  sequence:
    - service: media_player.sonos_snapshot
      data_template:
        entity_id: "{{ 'media_player.' ~ where }}"
    - service: tts.google_say
      data_template:
        entity_id: "{{ 'media_player.' ~ where }}"
        message: "{{ what }}"
    - delay:
        seconds: 1
    - delay: >-
        {% set duration = states.media_player[where].attributes.media_duration %}
        {% if duration > 0 %}
          {% set duration = duration - 1 %}
        {% endif %}
        {% set seconds = duration % 60 %}
        {% set minutes = (duration / 60)|int % 60 %}
        {% set hours = (duration / 3600)|int %}
        "{{ [hours, minutes, seconds]|join(':') }}"
    - service: media_player.sonos_restore
      data_template:
        entity_id: "{{ 'media_player.' ~ where }}"

scripts/test_tts.yaml

test_tts:
  alias: Test for TTS
  sequence:
    - service: script.turn_on
      entity_id: script.say
      data:
        variables:
          where: 'media_player.kitchen'
          what: 'Test.'

@christian.ek The new version only expects where: ‘kitchen’, since media_player. is already part of the script and templates.

Found the error… I renamed it sonos_tts but when calling the script i used script.say

1 Like

Thanks for the great script! I added some features to really make sure that the message is played only in the specific media player (unjoin first) and not to the whole group that it is connected to. On top of that I changed the volume so it wouldnt use the same volume as the speaker was set to.

    # > SONOS TTS
  say:
    alias: SONOS TTS
    sequence:
      - service: media_player.sonos_snapshot
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          with_group: yes
      - service: media_player.sonos_unjoin
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
      - service: media_player.volume_set
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          volume_level: 0.45
      - service: tts.google_say
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          message: "{{ what }}"
# Add a delay in a length which you think fits best for all the things you want to say over TTS
      - delay:
          seconds: 1
      - delay: >-
          {% set duration = states.media_player[where].attributes.media_duration %}
          {% if duration > 0 %}
            {% set duration = duration - 1 %}
          {% endif %}
          {% set seconds = duration % 60 %}
          {% set minutes = (duration / 60)|int % 60 %}
          {% set hours = (duration / 3600)|int %}
          {{ [hours, minutes, seconds]|join(':') }}
      - service: media_player.sonos_restore
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          with_group: yes
1 Like

Cant get this to work :frowning: It complaining about invalid config. It dosnt like the automation part i think?

17-02-19 23:49:24 ERROR (MainThread) [homeassistant.bootstrap] Invalid config for [automation]: [service] is an invalid option for [automation]. Check: automation->service. (See /home/hass/.homeassistant/configuration.yaml, line 163). Please check the docs at https://home-assistant.io/components/automation/
Failed config

Heres my config

coniguration.yaml
# Google Text to speech  
tts:
  - platform: google
    cache: true
    cache_dir: /tmp/tts
    time_memory: 300
    language: 'sv'

# Include
group: !include groups.yaml
sensor: !include sensors.yaml
switch: !include switches.yaml
script: !include_dir_merge_named script
automation: !include_dir_merge_list automation

script/sonos_tts.yaml
# > SONOS TTS
  say:
    alias: SONOS TTS
    sequence:
      - service: media_player.sonos_snapshot
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          with_group: yes
      - service: media_player.sonos_unjoin
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
      - service: media_player.volume_set
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          volume_level: 0.45
      - service: tts.google_say
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          message: "{{ what }}"
# Add a delay in a length which you think fits best for all the things you want to say over TTS
      - delay:
          seconds: 1
      - delay: >-
          {% set duration = states.media_player[where].attributes.media_duration %}
          {% if duration > 0 %}
            {% set duration = duration - 1 %}
          {% endif %}
          {% set seconds = duration % 60 %}
          {% set minutes = (duration / 60)|int % 60 %}
          {% set hours = (duration / 3600)|int %}
          {{ [hours, minutes, seconds]|join(':') }}
      - service: media_player.sonos_restore
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          with_group: yes

automation/sonos_test.yaml
- service: script.turn_on
  entity_id: script.say
  data:
    variables:
      where: 'kontor'
      what: 'Hej där!'

Could you post the hole content of your automation since the error you posted is about the automation, not about the script.

I couldn’t get it to work with the {{ where }} and {{ what }} either.
Now that I have placed the “where” and the “what” within the actual scripts, it works fine again…

Maby Im doing this wrong but the hole automation is:

- service: script.turn_on
  entity_id: script.say
  data:
    variables:
      where: 'kontor'
      what: 'Hej där!'

it is just for test before I include it in some automation that I have running. I have tried include it in this one but without luck.

- alias: "Mail vattenläcka diskbänk"
  initial_state: True
  hide_entity: False
  trigger:
    - platform: state
      entity_id: switch.fuktdiskbank
      to: 'on'
  action:
    - service: notify.gmailtoni
      data_template:
        title: "Vattenläcka under diskbänk"
        message: "Möjlig vattenläcka under diskbänk kontrollera"
    - service: notify.gmailmalin
      data_template:
        title: "Vattenläcka under diskbänk"
        message: "Möjlig vattenläcka under diskbänk kontrollera"
    - service: script.turn_on
      entity_id: script.say
      data:
        variables:
          where: 'kontor'
          what: 'Hej där!'

@Toni: This is not even not a half automation ;). If something should be automated there are two things essential: what shall be automated an when - you are totaly missing the when part. I would recommend walking through the hole automation tutorial setp by step, since this is the most essential thing within HA and home automation: Automating Home Assistant - Home Assistant

As you can see, I have not quite got the hang of this yet :slight_smile: I will have second look at the getting started :sweat: It was not mention to be a full automation just something simple i could manually trigger from the frontend.

What about the following automation? This automation works fine without the last sonos part. Here im trying to send a tts message to one sonos speaker “media_media_player.kontor” after 2 email has been sent.

 - alias: "mail water leak"
   initial_state: True
   hide_entity: False
   trigger:
     - platform: state
       entity_id: switch.fuktdiskbank
       to: 'on'
   action:
     - service: notify.gmailtoni
       data_template:
         title: "Water leaks under kitchen sink"
         message: "Possible water leak under kitchen sink."
     - service: notify.gmailmalin
       data_template:
         title: "Water leaks under kitchen sink"
         message: "Possible water leak under kitchen sink."
     - service: script.turn_on
       entity_id: script.say
       data:
         variables:
           where: 'kontor'
           what: 'Hello!'

@domlen Can you see whats wrong with the automation above?

Hi,
Can you paste your script code aswell? Do you get an error message?

Heres my script.

# SONOS TTS
  say:
    alias: SONOS TTS
    sequence:
      - service: media_player.sonos_snapshot
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          with_group: yes
      - service: media_player.sonos_unjoin
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
      - service: media_player.volume_set
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          volume_level: 0.45
      - service: tts.google_say
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          message: "{{ what }}"
# Add a delay in a length which you think fits best for all the things you want to say over TTS
      - delay:
          seconds: 1
      - delay: >-
          {% set duration = states.media_player[where].attributes.media_duration %}
          {% if duration > 0 %}
            {% set duration = duration - 1 %}
          {% endif %}
          {% set seconds = duration % 60 %}
          {% set minutes = (duration / 60)|int % 60 %}
          {% set hours = (duration / 3600)|int %}
          {{ [hours, minutes, seconds]|join(':') }}
      - service: media_player.sonos_restore
        data_template:
          entity_id: "{{ 'media_player.' ~ where }}"
          with_group: yes

The error I get:

17-02-19 23:49:24 ERROR (MainThread) [homeassistant.bootstrap] Invalid config for [automation]: [service] is an invalid option for [automation]. Check: automation->service. (See /home/hass/.homeassistant/configuration.yaml, line 163). Please check the docs at https://home-assistant.io/components/automation/
Failed config

So I think the script is ok.

whats on line 163 in your configuration.yaml

Dear all,

If you can also help me with this related issue:

https://github.com/home-assistant/home-assistant/issues/6424

Thank you a lot in advance :slight_smile:

I just had a quick look at your config and wondering if you’re asking for all 3 sensors to trigger before the automation runs. Have you tried with just one entity_id to see if that works?

I’m getting:
voluptuous.error.MultipleInvalid: offset "0:0:0" should be format 'HH:MM' or 'HH:MM:SS'
when the dynamic delay is calculated.
Any idea?

It’s getting 0:0:0 for the duration instead something like 00:00:35. It would be helpful to see your configuration to see why it’s getting nothing for the duration.

here you go. Please let me know if you need more.

configuration:

homeassistant:
  name: Home
  latitude: !secret home_latitude
  longitude: !secret home_longitude
  elevation: 21
  unit_system: metric
  time_zone: Europe/Brussels
  customize: !include customize.yaml

tts:
  - platform: google
    cache: true
    time_memory: 300
    language: 'nl'

scriot:

sonos_tts:
  alias: Sonos Text To Speech
  sequence:
- service: media_player.sonos_snapshot
  data_template:
    entity_id: "{{ 'media_player.' ~ where }}"
- service: tts.google_say
  data_template:
    entity_id: "{{ 'media_player.' ~ where }}"
    message: "{{ what }}"
- delay:
    seconds: 1
- delay: >-
    {% set duration = states.media_player[where].attributes.media_duration %}
    {% if duration > 0 %}
      {% set duration = duration - 1 %}
    {% endif %}
    {% set seconds = duration % 60 %}
    {% set minutes = (duration / 60)|int % 60 %}
    {% set hours = (duration / 3600)|int %}
    "{{ [hours, minutes, seconds]|join(':') }}"
- service: media_player.sonos_restore
  data_template:
    entity_id: "{{ 'media_player.' ~ where }}"

automation:

 alias: 'Testing TTS to Sonos'
  trigger:
    - platform: state
      entity_id: input_boolean.test
      from: "off"
      to: "on"
  action:
    - service: script.turn_on
      entity_id: script.sonos_tts
      data:
        variables:
          where: 'playbar'
          what: 'Hallo!'
    - service: input_boolean.turn_off
      entity_id: input_boolean.test
1 Like