TTS - telling the time

Hi All

Finally got the Sonos TTS up and running reading allot of pages in this wonderful forum :slight_smile:

I also found the code for telling the time but cant get it working my test automation is this (Works)
but instead of telling the time I get funny talk saying %…

# Test speaking on Sonos
  - alias: test speaking
    trigger:
     - platform: state
       from: 'off'
       to: 'on'
       entity_id: switch.sonoff_pow_r2
    action:
     - service: script.turn_on
       entity_id: script.say
       data:
         variables:
           where: 'kkken'
           what: 'The time is {{ now().hour}}  {{ "%0.02d" | format(now().strftime("%-M") | int) }}'

And the Sonos script (That I had the most luck with) is this one:

    # > SONOS TTS script to speak with text-to-speech
      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 }}"
          language: 'da'
    # Add a delay (default 1) 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

I see so many possibilities in TTS on my Sonos speakers, but telling the time would be nice

Best regards
Casperse

Looks like at least, in the action of your automation, you need to change data to data_template.

Thanks! @pnbruckner

1 Like

@pnbruckner sorry to bother you again but I seem to only get the hours not the minutes
always just 00 on minutes
Do you by any chance see what could be causing this?

‘The time is {{ now().hour}} {{ “%0.02d” | format(now().strftime("%-M") | int) }}’

I would check your quotes, it worked for me

@RobDYI is right, it works if you use the correct quotes (i.e., not fancy curly quotes.) However, having said that, why so complicated? Why not just:

"The time is {{ now().strftime('%H %M') }}" 

The Sonos TTS requires the fancy curly quotes instead of “” see last lines where & what (see above)
@pnbruckner trying your code I get this error

Validate your configuration if you recently made some changes to your configuration and want to make sure that it is all valid
Configuration invalid
Error loading /config/configuration.yaml: while scanning for the next token
found character ‘%’ that cannot start any token
in “/config/configuration.yaml”, line 622, column 53

@RobDYI I cant see the difference…it tell the time in hours 22 and then always 00

Can you post what you have now? This topic is way too long to go back and try to read everything and figure out what you may or may not have. Even if the Sonos TTS requires fancy curly quotes, you still have to satisfy the jinja template, which requires normal single or double quotes. If you post what you have I may be able to spot what is wrong.

@pnbruckner its only 8 posts :wink:, but they are long - I tried so many options now, also tried many different TTS scripts for Sonos but this is best in regards to calculating the length and ungrouping speakers

TTS Script:

script:

 # > SONOS TTS script to speak with text-to-speech
  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 }}"
          language: 'da'
# Add a delay (default 1) 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

And the automation script triggering the time: (working just only saying hours and 00)

automation:

# Test speaking on Sonos
  - alias: Test speaking on Sonos
    hide_entity: true
    trigger:
     - platform: state
       from: 'off'
       to: 'on'
       entity_id: switch.sonoff_pow_r2
    action:
     - service: script.turn_on
       entity_id: script.say
       data_template:
         variables:
           where: 'kkken'
           what: 'Klokken er nu {{ now().hour}} {{ "%0.02d" | format(now().strftime("%-M") | int) }}'
     - service: notify.ios_group_caspersen_home
       data:
         message: "Sonos test triggered {{ states('sensor.time') }}"
         title: "Home Assistant"

Ok, maybe try this in the automation:

           what: "Klokken er nu {{ now().strftime('%H %M') }}"

Or even this:

           what: "Klokken er nu {{ now().hour }} {{ now().minute }}"
1 Like

@pnbruckner Thanks allot this solved it :+1:

1 Like

@pnbruckner {{ now().hour }} {{ now().minute }} says 20 35 .
How can we display it as 8 35 PM or AM
Please help thanks in advance

Best way is probably:

{{ now().strftime('%I %M %p') }}
2 Likes

Thanks.
Curious from wr to get these syntax ? so that we can try out without troubling u always

now() returns a standard Python datetime.datetime object. So check the Python documentation – e.g., https://docs.python.org/3.5/library/datetime.html#datetime.datetime.

BTW, if you don’t want the result to zero pad the numbers, then you could also do this:

{% set time = now().strftime('%I %M %p').split(' ') %}
{{ time[0]|int }} {{ time[1]|int }} {{ time[2] }}
2 Likes

@pnbruckner sorry to bother you again but I just got another issue this time telling the temperature sensor on Sonoff correctly its working and it tells the temperature outside…

BUT the temperature is listed as 6.5 °C and I think the dot “.” should be a comma “,” in order for google to speak it

# Have temperatur for Google Assistant
# https://community.home-assistant.io/t/help-with-more-advanced-google-assistant-actions/58559/6
  have_temp:
    alias: "Temperatur i haven"
    sequence:
    - service: tts.google_say
      entity_id: media_player.stue, media_player.sonos_koekken
      data_template:
        message: 'Temperaturen i haven er {{ states("sensor.havetemperatur") }} grader'
        cache: false

Is there any easy way to substitute the . with a comma in the above syntax?
Or should it be done at the sensor:

# Udendørstemperatur sensor
  - platform: mqtt
    state_topic: 'tele/Sonoff_TH16_1/SENSOR'
    name: 'Havetemperatur'
    unit_of_measurement: '°C'
    value_template: '{{ value_json["DS18B20"]["Temperature"] }}'

So Far I haven’t been successful in getting this pronounced correctly in Danish :wink:
As always your help is much appreciated

You can probably do it in either place, depending on what you want:

message: "Temperaturen i haven er {{ states('sensor.havetemperatur').replace('.', ',') }} grader"

or

value_template: "{{ value_json.DS18B20.Temperature.replace('.', ',') }}"

Perfect, I did try something similar but I got the “parantes” wrong
Thanks!

i have this scrip

message: oven is on for {{ (as_timestamp(now()) - as_timestamp(states.automation.oven_warning.attributes.last_triggered))| timestamp_custom("%M") }} minutes!

for tigger at 5 mins, i got 05 mins

what should i do?

I assume you don’t like the zero???

How about:

message: oven is on for {{ (as_timestamp(now()) - as_timestamp(states.automation.oven_warning.attributes.last_triggered))//60 }} minutes!
1 Like