Google assistant not speaking via tts

A few weeks ago I was able to go to my Lovelace card that shows my Google Home devices and was able to type text into the “text to speak” field and the Google Home device would say it.

Since then I’ve updated my configuration.yaml a bunch of times and now Google Home won’t speak the text.

This is my config. Any suggestions? I don’t see any errors in the HA log.
thanks

# Text to speech
tts:
  platform: google_translate
  base_url: https://xxxxx:8123
  service_name: google_say

Why do you have base_url set?

Should it be http:// (no TLS)?

the doc and communicate says many different things so I’m not sure what should be set where. Some say the base_url within tts should be the local hassio IP and some say http vs https, so I really have no idea what it should be.

Use HTTP with your local IP for HA.

Should fix ya right up.

still nothing. I click the google home device card in the lovelace UI. On that popup, I click the little power icon, I hear my Google Home makes an initialize noise. Then I put some text in the ‘text to speak’ field, click the send icon and Google Home doesn’t say anything.

What does the HA logs show?

I see these all the time, but nothing else when Google doesn’t work.

My SSL cert (via the DuckDNS addon) seems to be working fine when I hit my external base_url.

ssl.SSLError: [SSL: SSLV3_ALERT_CERTIFICATE_UNKNOWN] sslv3 alert certificate unknown (_ssl.c:1076)
2019-08-07 13:42:31 ERROR (MainThread) [homeassistant.core] Error doing job: SSL handshake failed
Traceback (most recent call last):
  File "uvloop/sslproto.pyx", line 500, in uvloop.loop.SSLProtocol._on_handshake_complete
  File "uvloop/sslproto.pyx", line 484, in uvloop.loop.SSLProtocol._do_handshake
  File "/usr/local/lib/python3.7/ssl.py", line 774, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: HTTP_REQUEST] http request (_ssl.c:1076)

Ah DuckDNS addon strikes again, I’m not sure how to get around this issue. I use a Nginx proxy and let that handle the SSL certs while my internal Home Assistant runs just http keeping everything open for Google Home/Chromecast/etc.

I think there’s a thread about this on the forum, try searching I’m sure you’ll find it.

Did you restart HA?

yes, I modified the tts to have base_url of “http://local_ip:8123” ,restarted HASS, still nothing.
What I don’t understand is why the Google Assistant device beeps (so I know HASS is able to talk to it), when I hit my external HASS over https, the cert works shows good without error in my browser. I think SSL handshake is red haring.

if your router does loopback-NAT, this might work:

base_url: https://your.duckDNS.domain.org:8123

For a little background: Setting the tts: platform base_url to a non-TLS IP (http://) negates any certification validation between the tts: component and HA instance (hence why base_url: https://... wouldn’t seem to serve any purpose in your scenario).
So with base_url: set to http://..., nothing you’re seeing in your browser over https:// should be relevant to the tts: platform configuration.

As a side note: Self-signed certificates are considered ‘non-trusted’. I’m guessing you receive a “Your connection is not private” warning in your browser when navigating to HA over https://…? This would also prevent the tts component from being able to reach your HA instance (if you were using TLS). As a little more complex but comprehensive solution, you could either try what firstof9 suggested, or generate a free trusted (a.k.a. “Green Bar”) certificate from https://zerossl.com/ and negate any need for configuring base_url: (as well as getting rid of the warnings in your browser and logs).

Right, that seems to confirm that the URL Ha is using is correct – which should be the base_url: configured under tts:, assuming there are no typos, syntax errors, etc. (your original codeblock looks correct) – but the actual TTS data is not getting through. I think the most likely cause would be that Google’s TTS API can’t reach HA’s tts: component, which would likely be related to the certification errors you’re seeing in your log.

Edit: fixed typo
Edit2: more typos :roll_eyes:

Hi, I do have a valid trusted SSL cert installed and when I hit the external interface for my HA in my browser, the cert looks fine. I also know this to be true because Google Assistant (free) integreation works and that wouldn’t be the case using a self assigned cert.

If I remember back a few weeks ago, when I first setup my HA, it auto discovered my Google Home devices (I never had to set them up in HA or authenticate through Google). At that time, the google speak worked through HA and I believe this was all before my SSL cert was installed. So, knowing that, why does HA tts even need an SSL cert if HA makes the connection to the external translate.google.com API? That API isn’t making a call back to my HA, right? The HA is making the source connection. A network flow diagram of the tts steps here would be nice :slight_smile:

Flow as follows:

  1. You Input TTS Text
  2. HA contacts translate.google.com and downloads the generated mp3 of the text you entered
  3. HA then pings the media player you’ve selected via the chromecast protocol
  4. HA sends the base_url to the media player as the URL to play media from via the chromecast protocol
  5. Your media player plays the file (if it’s supported)

Now if your base_url is HTTPS your SSL Cert needs to be installed as well, BUT if the base_url doesn’t match the domain name the SSL Cert has, it will be rejected by a Google Home as it’s being sent a url that doesn’t match the cert, aka invalid. Thus the suggestion I posted earlier of using your duckDNS.org url as the base_url.

Your issue is occuring because you have Home Assistant handling the SSL directly. I use a Nginx reverse proxy to get around bottlenecks such as this, still keeps my exterior connections encrypted but my internal connections open.

Thanks for the details. I’ll look into Nginx I guess but it seems like some room for enhancement in HA. What would be nice is to be able to have HA listen on 8123 https, but also on 8124 (or whatever port) on http, then be able to pass that http local non-secure port has the base_url in tts.

This seems to bring us full circle, back to why I asked my first question:

In the tts component, base_url is not a requirement. Have you tried simply removing it?

Just to follow up with jparthum’s reply with technical detail on that, not setting the tts base_url will make it default to the base_url defined in the http component.

In case it’s brought up :wink:

1 Like

Removing base_url from tts: does not make a difference, which makes sense because without it, the base_url from http: is used, which is "https://<public_addr>8123. We know that without NAT loopback, the google devices can’t reach the external address to download the tts mp3 files.

Like I mentioned above what’s the likelihood of a 2nd listening hass port to be enabled within a future release, which would allow for non-ssl on that port?

OK then I’d leave that removed to simplify troubleshooting.

Now, do you have base_url set in the HTTP integration? ← Oops, I overlook where you specified “base_url from http:”. Can you use a phone over a cellular connection (disconnected from your local network) to reach HA using the exact URL specified as your HTTP base_url (including port number)?

yes, hitting my base_url address listed in the HTTP section (https://xxxxx.duckdns.org:8123) externally works fine. But with no NAT Loopback option, my Google Home can’t reach it.