TTS calls do not include the port number in the URL

I have 2023.9.2; HASS OS 10.5
Running with Lets encrypt Addon and CloudFlared addon for remote access.

From my configuration YAML:

http:
  server_port: 8123
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.30.33.0/24
  ip_ban_enabled: false
  login_attempts_threshold: 5
  ssl_certificate: /ssl/fullchain.pem
  ssl_key: /ssl/privkey.pem

homeassistant:
  name: 12MOTT
  unit_system: metric
  packages: !include_dir_named packages
  internal_url: "https://auto.mydomain.com:8123"
  external_url: "https://auto.mydomain.com"
  country: AU

I run my own internal split brain DNS so internally,
https://auto.mydomain.com → the internal IP of HASS (172.17.128.7)
whereas externally it resolves to cloudflare.

PROBLEM:
I have built an ESPHome MAX98357a media player.
Using the ‘media’ tab in Lovelace will result in a call to (from the ESPHome web server logs):
https://auto.mydomain.com/api/tts_proxy/5be36f479d40d09e3c154274e4c603230c69f593_en-us_be0728c770_tts.piper.wav
This call fails and nothing happens on the ESPhome as it cannot reach HASS to retrieve the WAV.

If I manually specify the port:
https://auto.mydomain.com:8123/api/tts_proxy/5be36f479d40d09e3c154274e4c603230c69f593_en-us_be0728c770_tts.piper.wav
using a cached TTS string (by sending it to the browser then copy/paste) then the ESPHome media player is then able to play the file.

The manual call is done using developer tools:

service: media_player.play_media
data:
  media_content_id: >-
    https://auto.mydomain.com:8123/api/tts_proxy/5be36f479d40d09e3c154274e4c603230c69f593_en-us_be0728c770_tts.piper.wav
  media_content_type: music
target:
  entity_id: media_player.ld2410_media_player

QUESTION:
Any ideas how to get the internal port to be specified in the call string? The reason it’s needed for me is because using a call service like this does not include the port:

service: tts.speak
data:
  media_player_entity_id: media_player.ld2410_media_player
  message: Waa waa
  cache: true
target:
  entity_id: tts.piper
|16:53:50|[D]|[media_player:059]|'LD2410 Media Player' - Setting|
| --- | --- | --- | --- |
|16:53:50|[D]|[media_player:066]|Media URL: https://auto.mydomain.com/api/tts_proxy/6d29aef4e0fb79af63096704f42610c07bf39f27_pt-pt_a877e2b3bf_tts.piper.wav|

Without the port in there the tts.speak service call is useless to me.

I don’t really want to tear apart all the cloudflared and letsencrypt stuff to use a separate reverse proxy if I don’t have to.

I’ve worked around it with this NAT rule from the IOT VLAN (where the ESPHome device exists) to the IP resolved by DNS.


But I am curious if there is a better fix.

I think I also have this problem. I can send music to my ESPHome MAX98357a but not STT from Piper.
Mine is supposed to be just an ESP Voice Assistant; I can speak commands, but not hear the “replies”.
I use DuckDNS and an apache proxy.
Did you find a (better) fix?
If not, can you please explain you fix better? I don’t get what the IOT VLAN is… Is that something I can do in my router, or does it have to be in the proxy configuration?

Hi @catacluj,
All my IoT devices live on a separate VLAN. This VLAN does not have access to the internet, with some exceptions.

The inter-VLAN router is my PFSense UTM device.

As the ESPHome devies (IOT VLAN) need to transit this router to reach my server VLAN (where HASS-OS lives), then I can adjust the traffic as it passes through my router.

What I perform is using a feature called NAT (it’s technically PAT) where a connection from ESPHome in IOT VLAN:
ESPhome(IOTVLAN) -> HASSOS (ServerVLAN):443
is adjusted by my router to actually connect to:
-> HASSOS(ServerVLAN):8123

The ESP home logs from the device still show the device calling the server port 443, but the actual traffic arrives on port 8123 which solved my problem.

I didn’t spend any more time on it since my post so I don’t know if there is a better fix now.

Thank you @wokwon .

This is still an issue if you use SSL because it uses the external url, which with split brain DNS ditches the port. They added this because their reasoning was that SSL = HA cloud, but having to rely on mucking around in your router to fix it because it assumes that you want the cloud is the opposite of what HA is supposed to be working towards.