I’ve got the same problem. I’ve had some automations with TTS set up for some time and they stopped playing on my Google Home Mini somewhere between November 2019 and March 2020.
The google_translate
TTS service seems to work fine and a mp3
is saved in the tts cache folder, however the file is not played back on the media player.
I’ve debugged the problem and found a solution.
TL;DR: There are three solutions below
My HA is configured with SSL certs from LetsEncrypt. Port 8123 is forwarded and I can access HA from outside my network using my.domain.tld
over HTTPS. I use AdGuard Home with DNS rewrite to rewrite my.domain.tld
to 192.168.1.100
so I can use my domain to access HA from everywhere.
Here are some tests I’ve run using the Services in Developer Tools.
I’ve run tests with my router configured to use AdGuard Home as DNS as well as using my ISP assigned DNS with the same results.
Normal setup with SSL enabled.
http:
ssl_certificate: /ssl/fullchain.pem
ssl_key: /ssl/privkey.pem
# Local HTTPS content with IP NAY
# It does NOT work via media_player.play_media
# It works via Chrome after manually proceeding past the Cert/Privacy error
entity_id: media_player.living_room_speaker
media_content_id: 'https://192.168.1.100:8123/local/audio/service-bell_daniel_simion.wav'
media_content_type: music
# Local HTTPS content with domain NAY
# It does NOT work via media_player.play_media
# It works via Chrome
entity_id: media_player.living_room_speaker
media_content_id: 'https://my.domain.tld:8123/local/audio/service-bell_daniel_simion.wav'
media_content_type: music
# External HTTPS content with domain YAY
# It works via media_player.play_media
# It works via Chrome
entity_id: media_player.living_room_speaker
media_content_id: 'https://www.external.tld/service-bell_daniel_simion.wav'
media_content_type: music
So I disabled SSL in configuration.yaml
http:
# ssl_certificate: /ssl/fullchain.pem
# ssl_key: /ssl/privkey.pem
# Local HTTP content with IP YAY
# It works! via media_player.play_media
# It works! via Chrome
entity_id: media_player.living_room_speaker
media_content_id: 'http://192.168.1.100:8123/local/audio/service-bell_daniel_simion.wav'
media_content_type: music
# Local HTTP content with domain NAY
# It does NOT work via media_player.play_media
# It works via Chrome
entity_id: media_player.living_room_speaker
media_content_id: 'http://my.domain.tld:8123/local/audio/service-bell_daniel_simion.wav'
media_content_type: music
# External HTTPS content with domain YAY
# It works via media_player.play_media
# It works via Chrome
entity_id: media_player.living_room_speaker
media_content_id: 'https://www.external.tld/service-bell_daniel_simion.wav'
media_content_type: music
Since test results with and without AdGuard Home are the same, I’m ruling it out as a cause.
External domains works (both HTTP and HTTPS) so it doesn’t seem to be the cause.
HTTP with IP works.
HTTPS with IP doesn’t work (probably because the SSL cert is for my.domain.tld
so there’s a privacy/safety warning)
HTTP and HTTPS with domain does NOT work. Which leads me to think that the domain does not resolve. I use AdGuard Home as DNS to resolve my.domain.tld
locally.
Conclusion
my.domain.tld
is sent to the Google Home Mini.
The Home Mini, I’ve read, has Google DNS coded into it, so it doesn’t use AdGuard Home to resolve (and rewrite) my domain like all the other devices on my network, but instead resolves using Google DNS which will resolve to my public (router) IP.
Once it’s resolved, it tries to play the file, but instead of requesting it from my HA instance it now requests it from my public (router) IP and therefore 404s
.
Solution 1 - An local subdomain
I configured a subdomain local.my.domain.tld
pointing to my HA local IP (192.168.1.100
) and volla, my tests pass. Note that I have a wildcard certificate for my.domain.tld
, so I can have subdomains using the same certificate.
This allowed me to get TTS working by setting the tts
base_url
to this internal sub-domain.
# Text to speech
tts:
- platform: google_translate
base_url: !secret tts_base_url # local.my.domain.tld
service_name: google_translate_say
I hope this helps someone.
Why this setup?
Now I asked myself why I have this problem? The answer lies in my setup. When I started using HA, I wanted to access HA in my phone browser using the same my.domain.tld
everywhere I go. It’s works fine when requesting from outside my LAN, but on the LAN the domain resolves and points to my router. To get around this I used DNS rewriting to point the domain to my HA instance when resolving it internally.
HA now has an app and the app can be configured with a URL
and Internal Connection URL
which sort of takes care of things. It automatically switches between the (local) IP and (public) domain, I guess, based on whether I’m connected to my Home Network WiFi SSIDs or not. This works great when you’re just using the app, but, if you want to use your phone’s browser or your laptop, you still have to go to either https://192.168.1.100
(local) or https://my.domain.tld
(public), which I find somewhat annoying.
Alternative Solutions
Solution 2 - Use a reverse proxy
There are alternative solutions to the problem. If you don’t use SSL or if you make use of a reverse proxy for SSL, you can set your !secret tts_base_url
to just use your IP (http://192.168.1.100:8123
) over HTTP. The Home Mini doesn’t need to resolve this, so it plays fine. In my case, since I have configured my HA http
to use SSL and not a reverse proxy, I cannot reach https://192.168.1.100:8123
without getting an SSL warning, because I don’t have a certificate for the IP.
Solution 3 - Change the DNS on your Google Home
I searched around and found that one can change the DNS on the Google Home. See this Google support page on changing the DNS of the speaker. Updating the DNS to your router IP should make it use the same DNS as the other devices on your network (AdGuard Home in my case). Update: I can’t get the Google WiFi app to detect my speaker, maybe it only works if you also have Google WiFi.
Solution 4 - Block Google DNS
Some have suggested blocking 8.8.8.8
and 8.8.4.4
as a solution. I haven’t tested this, but it could be a viable solution for some.
Final note
Recently v0.110
HA added Internal URL and External to Configuration > General. Setting the internal URL to local.my.domain.tld
should solve lots of problems.