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 .