Text To Speech on Android Auto

Is there currently any way to have the companion app play TTS through Android Auto instead of the handset when i’m driving? If not is there any plan to bring this feature? It would be really nice to have it coming through the speakers and interrupt then resume any other AA audio that’s playing.

TTS uses the media stream which should play in your car if you have it set to Android Auto/Bluetooth. If you have it set to radio then you will not hear the media play.

I have Android Auto in my car and the only time it plays through my speakers is when my audio is on the actual source of the phone and not AM/FM/XM etc…

Ok, during all my tests i’ve had AA up on the display, generally with Google Maps navigation and/or a podcast playing in Pocket Casts. I have another message notification in the same automation that displays a pop-up banner over my nav correctly. What do you think the problem might be with TTS?

service: notify.mobile_app_oneplus_7t_pro
data:
  message: TTS
  data:
    ttl: 0
    priority: high
    media_stream: alarm_stream_max
    tts_text: The heating has been turned down until you return

this line here overrides the media stream and uses the alarm stream to play at the loudest volume the phone has, remove it and it will use the media stream.

We mention this at the 3rd example in the docs

https://companion.home-assistant.io/docs/notifications/notifications-basic#text-to-speech-notifications

Ahh I had it on media_stream: alarm_stream previously and it was too quiet to hear from the handset when driving so changed it to max thinking I wouldn’t get it to come out through AA. So presumaly ‘alarm_stream’ has the same issue? I’ll test with ‘General’ tomorrow and see how that goes. Thanks for the help.

yes that is correct, both use the phones Alarm stream which has a separate volume level from other streams. When your phones connects to BT only the music stream is passed along and that is used by default for TTS, see the first example in the link above. Phones have multiple media streams to do different things.

the purpose of alarm stream is in case your phone is on silent, it will still play like in the case of an important notification like alarm going off etc…

I’m with you, so by removing the media_stream line completely I should get the default music stream.

yup thats correct

Edit: you can even be smart with it and use teh app provided sensors for when connected to the car via BT or Android Auto and send the appropriate service call.

Great idea! I have some security automations that wake me up with loud (alarm_stream_max) TTS at night if a person is detected by one of my external cameras. I can switch that to the music stream when AA is connected so it also works when i’m in the car. Really appreciate your help.

1 Like

If someone stumbles upon this thread, here is how I solved that issue. Although I use Android Auto for navigation, I sometimes still listen to the car radio and the Android TTS doesn’t switch to the phone media source automatically (at least in my car). But if a media app on the phone starts playing, it automatically switches.

This is why I now play TTS through VLC and not directly on Android.
Advantage 1: Automatically switches the source in my car
Advantage 2: You can choose any TTS engine you like. At least in German the Android engine is quite unnatural

Step 1: Generate the TTS file through the HA API: Text-to-speech (TTS) - Home Assistant
Step 2: Send an intent to VLC with the URL of the TTS file

Works very reliably for me.

Great tip! Thank you.

Could you share your scripts/automations to achieve this? I’ve recently discovered that you can play audio while on the car and I’m excited to try this.

I’m also interested in how you performed the interaction to get the tts file since I’ve tried and I seem to be missing something. Thanks!

Step 1: Shell command to retrieve the path (there might be easier ways to achieve this, but the only way I found is through the API)

shell_command:
  tts_api: >
    curl -X POST -H "Authorization: Bearer <<your long lived access token>>" -H "Content-Type: application/json" -d '{"message": "{{mymessage}}", "engine_id": "google_cloud"}' http://localhost:8123/api/tts_get_url

Depending on your engine you might have to change the engine id (translate, polly, nabu casa,…).

Step 2 (optional): Make a script that parses the full URL:

alias: TTS Service URL
variables:
  answer: InitialValue
sequence:
  - service: shell_command.tts_api
    data:
      mymessage: |
        {{message}}
    response_variable: json_data
  - variables:
      answer: >
        {% set parsed_data = json_data['stdout'] | from_json %} {'value':
        '<<your external https HA URL>>{{parsed_data.path}}' }
  - stop: Return answer
    response_variable: answer
mode: single
fields:
  message:
    selector:
      text: null
    name: message
    description: TTS Message
    required: true

Step 3: Use it in scripts and automations:

sequence:
  - service: script.tts_service_url
    data:
      message: >-
        The text that should be spoken
    response_variable: url
  - service: notify.mobile_app_florian #Change to your service
    data:
      message: command_activity
      data:
        intent_package_name: org.videolan.vlc
        intent_action: android.intent.action.VIEW
        intent_uri: "{{url.value}}"
1 Like

Hi Florian, I configured the script, but there is no way to make it work if the smartphone or tablet screen is off. How did you solve it?

Check the documentation, especially if you have accepted the permission: Notification Commands | Home Assistant Companion Docs
Make sure all energy saving options are disabled for the app and that it is allowed to run in the background.

Besides the initial permission, there was nothing I had to do, it just worked (using a Pixel 7).

1 Like