TTS local en español con Home Assistant: Piper, tts.speak y anuncios sin pisar la música

Los anuncios de voz en español se pueden montar 100% en local con Piper: instalas una voz en Home Assistant, usas la acción tts.speak y el audio sale por el altavoz que elijas sin salir de tu red. Aquí está el YAML completo y el patrón para que el anuncio no pise la música que suena en ese momento.

Flujo de un anuncio TTS local con Piper Automatización de Home Assistant que llama a tts.speak, Piper convierte el texto a voz y el audio sale por un altavoz local sin pasar por la nube. Flujo de un anuncio local (sin nube) Automatización detecta fin de lavadora tts.speak mensaje + destino Piper texto → voz es-ES local media_player altavoz de la LAN Patrón recomendado: guardar volumen → anunciar → restaurar Si el destino es un streamer sin voz (p. ej. WiiM), el anuncio va a otro altavoz. Diagrama propio. Sin conexión a servicios externos.
Flujo del anuncio: la automatización llama a tts.speak, Piper genera la voz en local y el reproductor elegido la emite. Nada sale de la LAN.

Primero, qué hace cada pieza

Home Assistant tiene dos formas de hablar. La vieja, tts.say, está marcada como legacy en la documentación oficial. La actual es tts.speak: eliges la entidad TTS (aquí, tts.piper) y le pasas el reproductor de destino y el mensaje.

action: tts.speak
target:
  entity_id: tts.piper
data:
  media_player_entity_id: media_player.living_room
  message: "La lavadora ha terminado."
  language: "es-ES"
  cache: true

La forma legacy, por si la ves en tutoriales viejos, mezclaba el reproductor en entity_id e invocaba la integración directamente:

action: tts.google_translate_say
data:
  entity_id: media_player.living_room
  message: "May the force be with you."

Si tu YAML no funciona, comprueba primero que no estás copiando sintaxis de tts.say sobre tts.speak. Es el fallo más tonto y más común.

Instalar Piper y elegir voz en español

Piper es un motor de texto a voz que corre en local: sin cuenta, sin nube, sin enviar el texto fuera de tu red. Home Assistant lo integra como servicio de voz y te deja elegir qué voz descargar.

  1. Añade la integración Piper desde Ajustes → Dispositivos y servicios. Si tu instalación necesita el add-on Piper, se instala aparte desde Ajustes → Complementos; la interfaz te lo pide cuando toca.
  2. Descarga una voz en español. La lista varía según la versión, así que elige la que en tu instalación aparezca como es-ES o variante de España.
  3. La entidad se llama tts.piper. Si tienes varias voces descargadas, cada una puede exponer su propia variante; la integración te mostrará cuál hay que usar.

No te doy un número de versión de Piper ni de Home Assistant sin confirmarlos en tu instalación: cambian rápido y un número falso aquí valdría menos que nada. A fecha de hoy, la documentación oficial confirma que Piper es la ruta para TTS completamente local.

Placa Raspberry Pi en una caja transparente, del tipo que se usa como reproductor de audio en red y altavoz local
Una Raspberry Pi como la que hace de reproductor de audio en red. Foto de Pixabay en Pexels

Automatización completa: la lavadora que habla

Ejemplo entero, para que lo copies y cambies solo las entidades. El disparador depende de tu sensor; si el tuyo no es sensor.lavadora, cámbialo por el que tengas.

alias: "Avisar por voz cuando acaba la lavadora"
trigger:
  - platform: state
    entity_id: sensor.lavadora
    to: "finished"
action:
  - service: tts.speak
    target:
      entity_id: tts.piper
    data:
      media_player_entity_id: media_player.living_room
      message: "La lavadora ha terminado. Puedes tender la ropa."
      language: "es-ES"
      cache: true

cache: true guarda el audio generado para no volver a sintetizar el mismo mensaje una y otra vez. Útil para mensajes fijos.

Que el anuncio no pise la música

Si el altavoz de destino está reproduciendo música y le mandas TTS, lo normal es que el sonido se solape o que la música cambie de volumen según el reproductor. El patrón fiable es guardar el volumen, bajar al nivel del anuncio y restaurarlo al terminar.

action:
  - service: media_player.volume_set
    target:
      entity_id: media_player.living_room
    data:
      volume_level: 0.35
  - service: tts.speak
    target:
      entity_id: tts.piper
    data:
      media_player_entity_id: media_player.living_room
      message: "La lavadora ha terminado."
      announce: true
  - service: media_player.volume_set
    target:
      entity_id: media_player.living_room
    data:
      volume_level: 0.55

El parámetro announce: true hace el ducking (bajar la música y reanudar) solo en dispositivos que lo soportan, como ciertos altavoces con pila de voz propia. No todos lo aceptan; si el tuyo no, le quitas esa línea y usas el volumen manual. La guía de Ayuda Domótica sobre TTS 2026 lo documenta igual para altavoces que reciben el anuncio a un volumen distinto.

Anuncios con Music Assistant

Music Assistant expone music_assistant.play_announcement, y ahí es donde la gente se equivoca: esa acción sirve para enviar un fichero de audio por URL, no para sintetizar texto.

service: music_assistant.play_announcement
target:
  entity_id: media_player.ma_player
data:
  url: "http://192.168.1.100:8123/local/audio/timbre.mp3"

Para texto sin fichero, no uses esto: llama a tts.speak y apunta a la entidad media_player que crea Music Assistant. La documentación de Music Assistant lo dice explícito: para mensajes de texto usa los servicios TTS de Home Assistant y dirige el destino al reproductor de MA.

Hay un caso documentado en la discusión #3770 del repo de Music Assistant: con play_announcement el retardo puede ser grande y, además, la música no siempre se reanuda al terminar. Si te pasa, no es tu instalación: es la diferencia entre pausa-reproducción y el comportamiento del reproductor. La solución que propone la comunidad es separar: el TTS va a un altavoz con pila de voz, la música se queda en el streamer. Son entidades distintas y cada una hace su trabajo.

Tabla rápida: motores TTS local frente a nube

MotorEjecuciónEspañolCuándo usarlo
PiperLocalSíPrivacidad y funcionamiento sin internet
Google Translate TTSNubeSíPruebas rápidas; el texto sale de tu red
Nabu Casa Cloud TTSNube (pago)Según vozCalidad alta si aceptas nube

La regla para este sitio es simple: si el anuncio dice algo de tu casa, Piper lo mantiene dentro de la casa. Si es un texto de prueba, usa lo que te dé menos fricción.

Casos límite que te vas a encontrar

  • Altavoz que suena a otro volumen. Algunos altavoces, sobre todo los que integran lógica propia, reciben el TTS a un volumen distinto del que tenían. Se resuelve con media_player.volume_set antes y después, o con announce: true si lo soporta.
  • Streamer sin voz. Un streamer de música (por ejemplo WiiM Mini) no es un altavoz de voz: no le mandes Piper y esperes un ducking educado. El anuncio va a un dispositivo con altavoz y pila de voz; la música se queda en el streamer. Así dejan de pelear TTS y Music Assistant.
  • VLANs IoT. Si aíslas la domótica en una VLAN, comprueba que el tráfico entre el contenedor de Home Assistant y el altavoz está permitido. Un anuncio que no suena casi nunca es culpa de Piper; suele ser un internal_url/external_url mal configurado o una VLAN que corta el paso.

Fuentes

Última revisión: 10/09/2026

Primera versión publicada el 10/09/2026. Sintaxis de tts.speak contrastada con la documentación oficial; el aviso sobre play_announcement y reanudación viene de la discusión #3770 del repositorio.