Thanks guys for amaizing job.
I am having a problem regarding this line: - delay: '00:00:{{ states.media_player[where].attributes.media_duration | int }}'
After the TTS message the Sonos stops and on pressing Play it replays TTS message.
My message is 2 seconds long. I am afraid that the delay line would be incorrect for
messages under 10 seconds, because it will be, in my case : delay: '00:00:2'
I tried a 0 (zero) in front of {{ states.media_player …, but it does not work.
But, if I am setting delay: '00:00:05' it works as intended.
Is anyone else having the same issue ?
17-01-16 10:23:34 ERROR (Thread-1) [homeassistant.util.yaml] while parsing a block mapping
in "/home/hass/.homeassistant/scripts/sonos_tts.yaml", line 26, column 9
expected <block end>, but found '<scalar>'
in "/home/hass/.homeassistant/scripts/sonos_tts.yaml", line 26, column 28
and then I tested (double quotes outside and singe quotes inside of the template)
17-01-16 10:24:41 ERROR (MainThread) [homeassistant.bootstrap] Invalid config for [script]: [delay] is an invalid option for [script]. Check: script->script->say->sequence->2->delay.
Thanks for the quick answer.
Indeed the first answer is incorrect due to single quotes.
So, it is working fine with double quotes: - delay: "00:00:{{ ('0' ~ states.media_player.living_room.attributes.media_duration) | reverse | truncate(2, True, '') | reverse }}"
First I got the same error (invalid config…) but I had a mistake in the script: -delay: - delay: {00:00:00}
So, recheck the file for typos or bad identation.
I managed to specify a dynamic delay that should be about the duration of the spoken text by the following script. Apparently the initial 1s delay is necessary for the duration in the state to be filled.
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 }}"
{% set duration = states.media_player[where].attributes.media_duration %}
does this mean you are setting your where variable to “.living_room” with the leading period? How did you manage to pass the variable into the set statement?
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.
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
Cant get this to work 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!'
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…