Chime TTS - Play audio before/after TTS audio lag free

You’re right, it has to do with your Media folder. I do not believe Chime_TTS is set up to allow shared network folders.

Any reason why you can’t have a folder where HAss is setup to store your media?

See if adding the http:// in front of your IP address and replace :hassio_media with /hassio_media will help. Like this:

http://192.168.1.83/hassio_media/

I’m able to view the shared folder in my browser using:

file://10.0.0.55/Media/

So you could try this as well:

file://192.168.1.83/hassio_media

It doesn’t work :cry: :sob: :sob:

Any reason why you’re trying to use a network folder instead of a local folder?

Wondering about the cache option. When I attempt to run the service with the cache option enabled I get the following unknown error:

I am using the Nabu Casa Cloud TTS as the TTS Platform, playing to a homepod mini, it works so long as the cache option is not set.

I have the default location set for the path to store temporary TTS audio mp3 files as:

/media/sounds/temp/chime_tts/

I see a file written to that location when the cache option is disabled (it clears after the announcement is played as expected), however I don’t see anything written there when cache option is enabled (most likely because it errors out).

I enabled debug logging via the Chime TTS integration and this is what I see in the logs:

Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/chime_tts/__init__.py:1267
integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 09:16:03 (10 occurrences)
Last logged: 09:35:59

[140007382949968] Error handling message: Unknown error (unknown_error) Steve of Queanbeyan from 192.168.1.44 (Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 27, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 793, in handle_execute_script
    script_result = await script_obj.async_run(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1773, in async_run
    return await asyncio.shield(create_eager_task(run.async_run()))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 464, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 528, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 558, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 526, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 763, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 726, in _async_run_long_action
    return await long_task
           ^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2741, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2784, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/chime_tts/__init__.py", line 116, in async_say
    result = await queue.add_to_queue(async_say_execute, service, is_say_url)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/chime_tts/queue_manager.py", line 33, in async_process_queue
    result = await asyncio.wait_for(
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
  File "/config/custom_components/chime_tts/__init__.py", line 138, in async_say_execute
    audio_dict = await async_get_playback_audio_path(params, options)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/chime_tts/__init__.py", line 716, in async_get_playback_audio_path
    audio_dict = await async_get_cached_audio_data(hass, filepath_hash)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/chime_tts/__init__.py", line 1287, in async_get_cached_audio_data
    audio_dict = await async_retrieve_data(hass, filepath_hash)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/chime_tts/__init__.py", line 1267, in async_retrieve_data
    return _data[DATA_STORAGE_KEY].get(key, None)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

Some announcements I play are regular and routine so it makes sense to enable the cache. Any ideas as to why it errors out?

Thanks for the integration. Works very well except for the cache issue.

Also having issues trying to setup a custom mp3 file.

Seems to get stuck, with an endless spinning progress wheel when I try to add a custom mp3 file:

Closing that window gives me, five minutes or so so far…

Then…

Same result for both the media and config/www locations.

Seems to result in a system reboot…

Perhaps this is relevant…

Logger: homeassistant.util.loop
Source: util/loop.py:56
First occurred: 12:27:55 (1 occurrences)
Last logged: 12:27:55

Detected blocking call to import_module with args ('custom_components.chime_tts',) in /usr/src/homeassistant/homeassistant/loader.py, line 1052: ComponentProtocol, importlib.import_module(self.pkg_path) inside the event loop Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/src/homeassistant/homeassistant/__main__.py", line 223, in <module> sys.exit(main()) File "/usr/src/homeassistant/homeassistant/__main__.py", line 209, in main exit_code = runner.run(runtime_conf) File "/usr/src/homeassistant/homeassistant/runner.py", line 190, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File "/usr/local/lib/python3.12/asyncio/base_events.py", line 672, in run_until_complete self.run_forever() File "/usr/local/lib/python3.12/asyncio/base_events.py", line 639, in run_forever self._run_once() File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1988, in _run_once handle._run() File "/usr/local/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/src/homeassistant/homeassistant/setup.py", line 165, in async_setup_component result = await _async_setup_component(hass, domain, config) File "/usr/src/homeassistant/homeassistant/setup.py", line 320, in _async_setup_component component = await integration.async_get_component() File "/usr/src/homeassistant/homeassistant/loader.py", line 1004, in async_get_component comp = self._get_component() File "/usr/src/homeassistant/homeassistant/loader.py", line 1052, in _get_component ComponentProtocol, importlib.import_module(self.pkg_path)

I have updated to v1.1.0-beta13. This has resolved the cache and custom file issues.

Sorry I didn’t get a chance to test this earlier. Thanks for clarifying the announce flag - that makes sense.

I’ve updated to beta13 - all tests below are on this version. TL;DR All seems good with announce: false. Still volume issues when announce: true.

Let’s build up a story so we’re on the same page, then I’ll report my findings.

User story: When an announcement is played and I’m listening to music, the announcement should play over my music. If I’m playing my music loud, then my music volume should reduce (duck), the chime and announcement played at the requested volume, then my music should resume at my previous loud volume. If my music is quiet then it doesn’t really matter about reducing the volume or not, but the announcement should still play at the requested volume. If I’m not listening to music, then the announcement only should play. [@Nimrod_Dolev does this match your expectation?]

For my use case, I would always have announce: true, as I don’t know what the state of all the speakers will be. Some will be playing music, others not, soundbars may or may not be playing audio from the connected TV, different volumes, etc. So announce: true is the safest, so the final speaker states are the same as the initial states.

All tests with a single Sonos speaker this time, join and unjoin false. cache true.

Test 1, single speaker, no music, 10% initial volume, announce: FALSE. 60% announcement volume.
Expected result: Play announcement at 60%
Actual results:

  • Initial speaker volume: 10%. No music playing.
  • Volume during announcement: 60%
  • Final speaker volume: 10%. No music playing.
    Summary: as expected

Test 2, single speaker, no music, 10% initial volume, announce: TRUE. 60% announcement volume.
Expected result: Play announcement at 60%, as per Test 1
Actual results:

  • Initial volume: 10%. No music playing.
  • Volume during announcement: <10%. First ~1s is at 10%, then lower
  • Final volume: 10%. No music playing.
    Summary: Announcement played at <10% volume, which is too low for an announcement

Test 3, single speaker, no music, 80% initial volume, announce: TRUE. 60% announcement volume.
Expected result: Play announcement at 60%, as per Test 1
Actual results:

  • Initial volume: 80%. No music playing.
  • Volume during announcement: <10%. First ~1s is at 10%, then lower
  • Final volume: 80%. No music playing.
    Summary: Announcement played at <10% volume, which is too low for an announcement. The initial volume of the speaker does not affect the announcement volume.

Test 4, single speaker, music playing at volume 10%, announce: FALSE. 60% announcement volume.
Expected result: Music should stop, announcement should play at 60%, volume should return to 10%
Actual results:

  • Initial volume: 10%. Music playing.
  • Volume during announcement: 60%
  • Final volume: 10%. No music playing
    Result: as expected

Test 5, single speaker, music playing at volume 80%, announce: TRUE, 60% announcement volume
Expected result: Music volume should reduce to below 60%, announcement should play at 60%, then music volume return to 80%
Actual results:

  • Initial volume: 80%, music playing
  • Volume during announcement: Music volume reduces, my estimate is to about 20%. 1s of the announcement plays at 10% volume, the result is inaudible
  • Final volume: 80%, music playing
    Summary: Seems to be the same problem at Test 3

It’s starting to get complicated… but I’m happy to keep testing for you. If you want a debug log, let me know which test and I’ll repeat it and collect logs. Join/unjoin, which I haven’t tested this time, adds complexity to the initial/final states. imho, join of all speakers is the best experience for an announcement. Would it be better/simpler when announce: true, to snapshot the states of all speakers (group memberships, play/pause states), play the announcement as per announce: false (ie, replace audio), then restore back the group memberships and play/pause states?

Thank you for the detailed testing report!

Reviewing the debug log messages for each test might shed some more light on this, thank you.

For Sonos media players, Chime TTS uses the media_player.play_media with the extra dictionary to set the volume (as per the Sonos integration’s documentation) to set the volume during the announcement.
The documentation states that “older Sonos hardware or legacy firmware versions (“S1”) may not fully support [the extra dictionary]” - could this be the issue?

You might want to also try the fade_audio parameter instead of announce. It completely fades out the currently playing audio before the Chime TTS announcement, and then fades the previous audio back in after the announcement ends.

I have only S2 speakers. Thanks for the documentation link, I’ll experiment with calling the play_media directly and see if there’s still an issue with announce and volume. It could be with the Sonos integration rather than chime_tts. Fade is a good idea, I’ll check that, too.

I believe I have identified and fixed the issue, and released a new beta: v1.1.0-beta14.

Please upgrade to the new version and let me know if it resolves the issue :+1:

1 Like

Looks like you already updated to beta15, I used that version.

Wow, I reckon you got it. announce: true works perfectly on my single sonos speaker with music playing and without. I’ll test multi-speaker if i get some time tomorrow.

Not that it affects me, but could you check announce: false? One small volume bug - I think you should stop the media before changing the volume, or if you already do then maybe give it a small delay to apply. When announce: false (where you’re replacing media) and music playing, there’s 1 second of loud music before it stops, and then the chime plays. Like i said - doesn’t affect me, but some people might want this.

Amazing work :smiley:

J

Hi are there any docker (compose) users? I’m struggling to get this work and looking for a good example of the configuration. It plays the “end_chime_path” but doesn’t react on “chime_path” or the “message”.

I get errors like:
- Error calling tts.async_get_media_source_audio: Failed to connect. Probable cause: Unknown

homeassistant.components.media_source.error.Unresolvable: Unknown source directory.

how a part of my docker compose looks like:

    volumes:
      - /share/hass:/config
      - /share/backup/media:/media

I created the following folders there:
image

How the home assistant config looks like:

homeassistant:
  packages: !include_dir_named packages
  media_dirs:
    media: /media
  allowlist_external_dirs:
    - /media

and the chime config:
image
I’ve tried almost everything (I think) so any help is appreciated. What am I missing?

If you hear playback of the end_chime_path file then it seems like your setup is at least partially correct.

Could you please enable debug logging for Chime TTS and provide the logs?

Hm after a long time of changing a lot of things in hope to solve the issue, the end chime isnt doing anything either.

2024-06-14 16:42:36.455 DEBUG (MainThread) [custom_components.chime_tts]      - media_content_id: media-source://media_source/local/sounds/temp/chime_tts/sh8x8171.mp3
2024-06-14 16:42:36.455 ERROR (MainThread) [homeassistant.core] Error executing service: <ServiceCall media_player.play_media (c:01J0BK6K9754HX2Q2C0ANNFVBG): entity_id=['media_player.woonkamer'], announce=False, extra=, media_type=music, media_id=media-source://media_source/local/sounds/temp/chime_tts/sh8x8171.mp3>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 2761, in _run_service_call_catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 2784, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 977, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 1049, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/cast/media_player.py", line 674, in async_play_media
    sourced_media = await media_source.async_resolve_media(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/media_source/__init__.py", line 172, in async_resolve_media
    return await item.async_resolve()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/media_source/models.py", line 84, in async_resolve
    return await self.async_media_source().async_resolve_media(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/media_source/local_source.py", line 79, in async_resolve_media
    source_dir_id, location = self.async_parse_identifier(item)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/media_source/local_source.py", line 65, in async_parse_identifier
    raise Unresolvable("Unknown source directory.")
homeassistant.components.media_source.error.Unresolvable: Unknown source directory.

Can you please enable debug logging so that I might be able to understand more?

  1. Turn on debug logging:

    service: logger.set_level
    data:
      custom_components.chime_tts: debug
    
  2. Call the service chime_tts.say again.

  3. Check your log messages in Home Assistant:

    https://{YOUR_HOME_ASSISTANT_ADDRESS}:8123/config/logs?filter=chime_tts
    

    and click LOAD FULL LOGS

Yes what I’ve tried:

service: chime_tts.say
target:
  entity_id: media_player.woonkamer
data:
  message: tesssttjeee
  tts_platform: tts.google_nl_com

nothing happens except the device starts

2024-06-14 19:30:50.168 DEBUG (MainThread) [custom_components.chime_tts.queue_manager] Adding service call to queue
2024-06-14 19:30:50.168 DEBUG (MainThread) [custom_components.chime_tts] ----- Chime TTS Say Called. Version v1.1.0-beta15 -----
2024-06-14 19:30:50.168 INFO (MainThread) [custom_components.chime_tts.helpers.media_player] Turning on "media_player.woonkamer"...
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers] ----- General Parameters -----
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * entity_ids = ['media_player.woonkamer']
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * message = tesssttjeee
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * final_delay = 0.0
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * offset = 450.0
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * cache = False
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * volume_level = -1
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * fade_audio = False
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * announce = False
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * tts_pitch = 0
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * tts_speed = 100.0
2024-06-14 19:30:50.169 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * tts_platform = tts.google_nl_com
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]      now playing: False
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]      target volume: -1.0
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]      initial volume: -1.0
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]      platform: cast
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]    - 0: entity_id: media_player.woonkamer
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * media_players_array:
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * unjoin_players = False
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]  * join_players = False
2024-06-14 19:30:50.172 DEBUG (MainThread) [custom_components.chime_tts]     * options = {}
2024-06-14 19:30:50.172 DEBUG (MainThread) [custom_components.chime_tts]     * language = None
2024-06-14 19:30:50.172 DEBUG (MainThread) [custom_components.chime_tts]     * cache = False
2024-06-14 19:30:50.172 DEBUG (MainThread) [custom_components.chime_tts]     * message = 'tesssttjeee'
2024-06-14 19:30:50.172 DEBUG (MainThread) [custom_components.chime_tts]     * tts_platform = 'tts.google_nl_com'
2024-06-14 19:30:50.172 DEBUG (MainThread) [custom_components.chime_tts]  - Generating new TTS audio with parameters:
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]      announce supported: False
2024-06-14 19:30:50.170 DEBUG (MainThread) [custom_components.chime_tts.helpers.helpers]      join supported: False
2024-06-14 19:30:50.222 ERROR (MainThread) [custom_components.chime_tts] async_get_playback_audio_path --> Audio has no duration
2024-06-14 19:30:50.222 WARNING (MainThread) [custom_components.chime_tts] Error generating TTS audio from messsage segment #1: {'type': 'tts', 'message': 'tesssttjeee'}
2024-06-14 19:30:50.222 ERROR (MainThread) [custom_components.chime_tts]    - Error calling tts.async_get_media_source_audio: Failed to connect. Probable cause: Unknown
2024-06-14 19:30:50.222 ERROR (MainThread) [custom_components.chime_tts] async_get_playback_audio_path --> Unable to generate local audio file
2024-06-14 19:30:50.222 DEBUG (MainThread) [custom_components.chime_tts] ----- Chime TTS Say Completed in 50.0 ms -----

It looks like the issue might be with Home Assistant’s tts component failing to generate TTS audio.

Are you able to successfully generate TTS audio with tts.google_nl_com, independent of Chime TTS? Eg:

service: tts.speak
data:
  media_player_entity_id: media_player.woonkamer
  message: test
target:
  entity_id: tts.google_nl_com