Piper TTS fails on long messages
Describe the issue you are experiencing
When trying to using Piper to generate a long tts message (on Sonos speakers, in my case), the audio never plays on the speaker. This seems to happen at around 35 seconds, for me. Anything shorter than that works fine.
What type of installation are you running?
Home Assistant OS
Which operating system are you running on?
Home Assistant Operating System
Which add-on are you reporting an issue with?
Piper
What is the version of the add-on?
1.4.0
Steps to reproduce the issue
- Run a
media_player.play_mediaservice call with a long piper tts message, e.g.
service: media_player.play_media
target:
entity_id: media_player.soundbar
data:
media_content_type: music
media_content_id: >-
media-source://tts/tts.piper?message="This is a short message. This is a
slightly longer message that takes longer to say. This is an even longer
message where I'm going to keep talking for awhile so the length of the
audio will increase. This is a 4th message to increase the length of the
audio and I will keep talking and talking to make this longer. Lorem ipsum
dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur."
announce: false
- The message fails to play on the speaker.
The same thing happens if I send
announce: true, but with it set to false, I can see a message in the Sonos app that says "Unable to play '' - the connection to was lost" Shorter messages, which is pretty much anything under 35 seconds, always works, and anything longer seems to always fail. I have tried restarting various things (Home Assistant, the addon, etc.), clearing the TTS cache, and none of that has worked.
System Health information
System Information
| version | core-2023.12.3 |
|---|---|
| installation_type | Home Assistant OS |
| dev | false |
| hassio | true |
| docker | true |
| user | root |
| virtualenv | false |
| python_version | 3.11.6 |
| os_name | Linux |
| os_version | 6.1.63-haos |
| arch | x86_64 |
| timezone | America/Chicago |
| config_dir | /config |
Home Assistant Community Store
| GitHub API | ok |
|---|---|
| GitHub Content | ok |
| GitHub Web | ok |
| GitHub API Calls Remaining | 4690 |
| Installed Version | 1.33.0 |
| Stage | running |
| Available Repositories | 1352 |
| Downloaded Repositories | 48 |
Home Assistant Supervisor
| host_os | Home Assistant OS 11.2 |
|---|---|
| update_channel | stable |
| supervisor_version | supervisor-2023.11.6 |
| agent_version | 1.6.0 |
| docker_version | 24.0.7 |
| disk_total | 62.3 GB |
| disk_used | 30.7 GB |
| healthy | true |
| supported | true |
| board | ova |
| supervisor_api | ok |
| version_api | ok |
| installed_addons | Studio Code Server (5.14.2), Z-Wave JS UI (3.0.2), Advanced SSH & Web Terminal (17.0.0), Duck DNS (1.15.0), Dropbox Upload (1.3.0), MariaDB (2.6.1), phpMyAdmin (0.9.0), Mosquitto broker (6.4.0), Zigbee2MQTT (1.34.0-1), Home Assistant Google Drive Backup (0.112.1), Nginx Proxy Manager (0.12.3), ESPHome (2023.11.6), WireGuard (0.10.1), File editor (5.7.0), Piper (1.4.0), Whisper (1.0.0), openWakeWord (1.8.2) |
Dashboards
| dashboards | 4 |
|---|---|
| resources | 29 |
| views | 23 |
| mode | storage |
Recorder
| oldest_recorder_run | December 11, 2023 at 21:41 |
|---|---|
| current_recorder_run | December 15, 2023 at 10:30 |
| estimated_db_size | 8347.56 MiB |
| database_engine | mysql |
| database_version | 10.6.12 |
Spotify
| api_endpoint_reachable | ok |
|---|
Anything in the Supervisor logs that might be useful for us?
No response
Anything in the add-on logs that might be useful for us?
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 35, in run
if not (await self.handle_event(event)):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 104, in handle_event
await self.write_event(
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 26, in write_event
await async_write_event(event, self.writer)
File "/usr/local/lib/python3.11/dist-packages/wyoming/event.py", line 114, in async_write_event
await writer.drain()
File "/usr/lib/python3.11/asyncio/streams.py", line 378, in drain
await self._protocol._drain_helper()
File "/usr/lib/python3.11/asyncio/streams.py", line 167, in _drain_helper
raise ConnectionResetError('Connection lost')
ConnectionResetError: Connection lost
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-8439' coro=<AsyncEventHandler.run() done, defined at /usr/local/lib/python3.11/dist-packages/wyoming/server.py:28> exception=ConnectionResetError('Connection lost')>
Additional information
I see this in the Home Assistant Core log:
Logger: homeassistant
Source: components/wyoming/tts.py:125
First occurred: 10:34:04 (9 occurrences)
Last logged: 11:16:01
Error doing job: Exception in callback SpeechManager._async_get_tts_audio.<locals>.handle_error(<Task cancell...nit__.py:691>>) at /usr/src/homeassistant/homeassistant/components/tts/__init__.py:757
Traceback (most recent call last):
File "/usr/local/lib/python3.11/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/usr/src/homeassistant/homeassistant/components/tts/__init__.py", line 759, in handle_error
if audio_task.exception():
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/tts/__init__.py", line 701, in get_tts_data
extension, data = await engine_instance.internal_async_get_tts_audio(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/tts/__init__.py", line 451, in internal_async_get_tts_audio
return await self.async_get_tts_audio(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/wyoming/tts.py", line 125, in async_get_tts_audio
event = await client.read_event()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/wyoming/client.py", line 25, in read_event
return await async_read_event(self._reader)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/wyoming/event.py", line 77, in async_read_event
json_line = await reader.readline()
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/streams.py", line 548, in readline
line = await self.readuntil(sep)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/streams.py", line 640, in readuntil
await self._wait_for_data('readuntil')
File "/usr/local/lib/python3.11/asyncio/streams.py", line 525, in _wait_for_data
await self._waiter
asyncio.exceptions.CancelledError
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
this should not be closed as i am getting the same issue.
Connection to localhost (127.0.0.1) 10200 port [tcp/*] succeeded! ERROR:asyncio:Task exception was never retrieved future: <Task finished name='Task-39' coro=<AsyncEventHandler.run() done, defined at /lsiopy/lib/python3.12/site-packages/wyoming/server.py:28> exception=ConnectionResetError(104, 'Connection reset by peer')> Traceback (most recent call last): File "/lsiopy/lib/python3.12/site-packages/wyoming/server.py", line 31, in run event = await async_read_event(self.reader) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/lsiopy/lib/python3.12/site-packages/wyoming/event.py", line 62, in async_read_event json_line = await reader.readline() ^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/asyncio/streams.py", line 568, in readline line = await self.readuntil(sep) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/asyncio/streams.py", line 660, in readuntil await self._wait_for_data('readuntil') File "/usr/lib/python3.12/asyncio/streams.py", line 545, in _wait_for_data await self._waiter File "/usr/lib/python3.12/asyncio/selector_events.py", line 1013, in _read_ready__data_received data = self._sock.recv(self.max_size) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ConnectionResetError: [Errno 104] Connection reset by peer
I'm also having the same issue with piper 1.5.2 when getting a large response from chatgpt to home assistant voice preview edtion. I'm using EN GB medium though.
Logger: homeassistant
Source: components/wyoming/tts.py:126
First occurred: 17:38:56 (1 occurrences)
Last logged: 17:38:56
Error doing job: Exception in callback SpeechManager._async_get_tts_audio.<locals>.handle_error() at /usr/src/homeassistant/homeassistant/components/tts/__init__.py:844 (None)
Traceback (most recent call last):
File "/usr/local/lib/python3.13/asyncio/events.py", line 89, in _run
self._context.run(self._callback, *self._args)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/tts/__init__.py", line 846, in handle_error
if audio_task.exception():
~~~~~~~~~~~~~~~~~~~~^^
File "/usr/src/homeassistant/homeassistant/components/tts/__init__.py", line 786, in get_tts_data
extension, data = await engine_instance.internal_async_get_tts_audio(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
message, language, options
^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/usr/src/homeassistant/homeassistant/components/tts/__init__.py", line 492, in internal_async_get_tts_audio
return await self.async_get_tts_audio(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
message=message, language=language, options=options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/usr/src/homeassistant/homeassistant/components/wyoming/tts.py", line 126, in async_get_tts_audio
event = await client.read_event()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/wyoming/client.py", line 25, in read_event
return await async_read_event(self._reader)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/wyoming/event.py", line 79, in async_read_event
json_line = await reader.readline()
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/asyncio/streams.py", line 562, in readline
line = await self.readuntil(sep)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/asyncio/streams.py", line 677, in readuntil
await self._wait_for_data('readuntil')
File "/usr/local/lib/python3.13/asyncio/streams.py", line 539, in _wait_for_data
await self._waiter
asyncio.exceptions.CancelledError
BrokenPipeError: [Errno 32] Broken pipe
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='wyoming event handler' coro=<AsyncEventHandler.run() done, defined at /usr/local/lib/python3.11/dist-packages/wyoming/server.py:31> exception=BrokenPipeError(32, 'Broken pipe')>
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 48, in handle_event
return await self._handle_event(event)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 114, in _handle_event
await self.write_event(
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 29, in write_event
await async_write_event(event, self.writer)
File "/usr/local/lib/python3.11/dist-packages/wyoming/event.py", line 131, in async_write_event
await writer.drain()
File "/usr/lib/python3.11/asyncio/streams.py", line 378, in drain
await self._protocol._drain_helper()
File "/usr/lib/python3.11/asyncio/streams.py", line 167, in _drain_helper
raise ConnectionResetError('Connection lost')
ConnectionResetError: Connection lost
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 41, in run
if not (await self.handle_event(event)):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 50, in handle_event
await self.write_event(
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 29, in write_event
await async_write_event(event, self.writer)
File "/usr/local/lib/python3.11/dist-packages/wyoming/event.py", line 131, in async_write_event
await writer.drain()
File "/usr/lib/python3.11/asyncio/streams.py", line 366, in drain
raise exc
File "/usr/lib/python3.11/asyncio/selector_events.py", line 1057, in write
n = self._sock.send(data)
^^^^^^^^^^^^^^^^^^^^^
BrokenPipeError: [Errno 32] Broken pipe
Same here with piper version 1.5.2 on HAOS Core 2025.1.2 Supervisor 2024.12.3 Operating System 14.1 Frontend 20250109.0:
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='wyoming event handler' coro=<AsyncEventHandler.run() done, defined at /usr/local/lib/python3.11/dist-packages/wyoming/server.py:31> exception=BrokenPipeError(32, 'Broken pipe')>
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 48, in handle_event
return await self._handle_event(event)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 114, in _handle_event
await self.write_event(
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 29, in write_event
await async_write_event(event, self.writer)
File "/usr/local/lib/python3.11/dist-packages/wyoming/event.py", line 131, in async_write_event
await writer.drain()
File "/usr/lib/python3.11/asyncio/streams.py", line 378, in drain
await self._protocol._drain_helper()
File "/usr/lib/python3.11/asyncio/streams.py", line 167, in _drain_helper
raise ConnectionResetError('Connection lost')
ConnectionResetError: Connection lost
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 41, in run
if not (await self.handle_event(event)):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 50, in handle_event
await self.write_event(
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 29, in write_event
await async_write_event(event, self.writer)
File "/usr/local/lib/python3.11/dist-packages/wyoming/event.py", line 131, in async_write_event
await writer.drain()
File "/usr/lib/python3.11/asyncio/streams.py", line 366, in drain
raise exc
File "/usr/lib/python3.11/asyncio/selector_events.py", line 1057, in write
n = self._sock.send(data)
^^^^^^^^^^^^^^^^^^^^^
BrokenPipeError: [Errno 32] Broken pipe
@synesthesiam do we need to re report this because the bot closed it? This is a real problem. But it sort of feels like we are talking to the void here in an issue closed by a bot.
Thank you for tagging me, I don't get notified otherwise! I will take a look.
Hi, I can confirm the same issue here:
s6-rc: info: service discovery successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='wyoming event handler' coro=<AsyncEventHandler.run() done, defined at /usr/local/lib/python3.11/dist-packages/wyoming/server.py:31> exception=BrokenPipeError(32, 'Broken pipe')>
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 48, in handle_event
return await self._handle_event(event)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 114, in _handle_event
await self.write_event(
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 29, in write_event
await async_write_event(event, self.writer)
File "/usr/local/lib/python3.11/dist-packages/wyoming/event.py", line 131, in async_write_event
await writer.drain()
File "/usr/lib/python3.11/asyncio/streams.py", line 378, in drain
await self._protocol._drain_helper()
File "/usr/lib/python3.11/asyncio/streams.py", line 167, in _drain_helper
raise ConnectionResetError('Connection lost')
ConnectionResetError: Connection lost
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 41, in run
if not (await self.handle_event(event)):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/wyoming_piper/handler.py", line 50, in handle_event
await self.write_event(
File "/usr/local/lib/python3.11/dist-packages/wyoming/server.py", line 29, in write_event
await async_write_event(event, self.writer)
File "/usr/local/lib/python3.11/dist-packages/wyoming/event.py", line 131, in async_write_event
await writer.drain()
File "/usr/lib/python3.11/asyncio/streams.py", line 366, in drain
raise exc
File "/usr/lib/python3.11/asyncio/selector_events.py", line 1057, in write
n = self._sock.send(data)
There's some useful info over here that might help: https://github.com/esphome/home-assistant-voice-pe/issues/271
Same issue here. If I'm using piper in an automation with long text (and non static text, e.g.text is not in cache yet), it fails to speak the text in the first place. If I rerun the automation manually right after it failed, it is working. Cache is set to "true".
Same problem
Same issue here. I bought the home assistant voice device and it does not work because piper does not read the responses.
Same here as a workaround I split messages by sentences and send them one by one. This works most of the time but should not be needed.
@synesthesiam it seems this issue is still widespread. I know there's a lot going on, so I am not pressuring for a fix, but could we simply have this issue reopened please?
I agree in the age of LLMs this should be fixed but in the mean time here's workaround: https://community.home-assistant.io/t/simple-script-to-handle-multiple-tts-lines-as-a-batch/589926/2
Pls reopen this Issue. "Not planned" is an bad joke.
They frankly don't want us to report issues, that's why they have a bot that closes them so fast. I understand they get a lot of reports, too many probably, and they just can't deal with it all. It's understandable, I'm thankful to have HA at all. They have to work at their own pace and maybe one day they will independently rediscover this issue and fix it.
@agners Can you reopen this issue please?
I had a similar issue before, and when I looked into the piper logs, I found an issue that I fixed: https://github.com/rhasspy/wyoming-piper/pull/33
I didn't have that issue after fixing that anymore
Hallo, I'm using verions 1.6.4, it works only if the application is connected to the internet. Problem is it is using external url to announce instead of internal url. I want Piper to announce only via internal url. Any suggestions to change the url?
Updating to version 2.1.1: https://github.com/home-assistant/addons/pull/4217