TTS on Bluetooth speaker via Raspberry Pi

man coding is different here

media_player:
- platform: bluetooth_speaker
address: 88:C6:26:AC:41:1F
volume: 50

Ahhhā€¦ can you change the address to use underscore instead of colons?

And volume needs to be between 0 and 1.

So replace your config with this:

media_player: 
  - platform: bluetooth_speaker
    address: 88_C6_26_AC_41_1F
    volume: 0.50

I will modify the code to support colons, but for now, just underscores supported.

I ment pasting code in forums is different then in the chat

I changed the colons out still same issue. I am going to try with different speaker in the am. Thanks for help so far

If Iā€™m using the same bluetooth adapter for presence detection via detecting my miband or my mobile phone (I have to look into how I did this), will I be able to use the same adapter for this purpose too? Or are these adapters single purpose, if they are constantly listening for a bluetooth device they cant be transmitting?

@marksev1 I think youā€™re right here. As soon as I enabled Bluetooth presence detection tracking in HA, the TTS playback became choppy on the Bluetooth speaker.

I wonder if there is a way to temporarily stop the Bluetooth adapter from listening so that the TTS can be played, and then resume the listening?

Just for testing, I set the Bluetooth scanning interval to 5 minutes (300 seconds), and after doing that, the TTS playback was smooth, without any choppiness.

  - platform: bluetooth_tracker
    interval_seconds: 300

Looking at the HA Bluetooth presence tracker code, I can see that the scanning is done with a duration of 8 seconds and the default interval is 12 seconds. I guess that means there is only a 4 second window of idle time between cycles.

Anyway, something to look into furtherā€¦

Iā€™ve created a GitHub repo for this custom component.

The new version of the component no longer includes the associated shell script (play_url_bluetooth.sh) since the component itself (i.e. Python code) does the work the script used to perforn (i.e. launches mplayer with the correct parameters).

So, all you need to do is copy the new version of the custom component from the GitHub repo:

custom_components/media_player/bluetooth_speaker.py

Iā€™ve also included a sample media player config:

media_player.yaml


  - platform: bluetooth_speaker
    address: 00:2F:AD:12:0D:42
    volume: 0.65
#    cache_dir: /tmp/tts    # Optional - make sure it matches the same setting in TTS config

As you can see, the Bluetooth deviceā€™s address now supports colons rather than only underscores. Also, the cache_dir setting should be set to the same directory as what you have in your TTS config (if youā€™ve specified it all). This is because the new version of the component no longer saves a copy of the MP3 file from the TTS URL, but instead, it plays the original MP3 file from the TTS cache folder.

3 Likes

I havenā€™t tried it myself, but you should be able to. See https://www.youtube.com/watch?v=mhtvWn70meA

I managed to make it work, but i have to connect the portable speaker manually with ā€œbluetoothctlā€ and then ā€œconnect FC:58:FA:D2:84:0ā€
Iā€™m guessing this is because of my cheap speaker (this one: Myria DC-0598)

I will try again tomorrow evening when I return from work with a pair of Soundsticks III

I think my real problem was with some permisions, i donā€™t run homeassistant from pi user, i have a separate user ā€œhomeassistantā€ for it, and I created the files in guest mode from samba using a mac. I figured it out after testing the

mplayer -ao pulse::bluez_sink.88_C6_26_AC_41_1F -volume 50 /tmp/crowd.mp3 command and received an acces denied.

@hackertc Great to see progress!

Did you add your homeassistant user to the pulse-access group? Maybe that will help with permissionsā€¦

sudo adduser homeassistant pulse-access

yes, i did this and fixed my problem :smiley: (forgot to mention in the last post) I will play with it and come back with some feedback and suggestions if i can find any :slight_smile:

1 Like

@hackertc Are you using the latest version of the bluetooth speaker component I put on GitHub, or the original one from the first post?

Made some good progress on this. I am close to releasing the latest version. This one allows the following two components to play nicely together:

  • Bluetooth tracker (presence detection)
  • Bluetooth speaker (for TTS)

As was discussed already, since the Bluetooth tracker constantly scans for devices, it interferes with the playback of audio on the Bluetooth speaker. After trying lots of approaches, the only one that worked was to power off, and power on, the Bluetooth on the Raspberry Pi. That terminates any existing presence detection scanning, granting the Bluetooth speaker exclusive access to the Piā€™s Bluetooth. Once the MP3 file has completed playing, access to Bluetooth is handed back to the Bluetooth tracker.

The flow is something like this:

  • Bluetooth tracker component continually scans for devices (presence detection)
  • TTS service gets called to play something on the Bluetooth speaker
  • TTS Bluetooth speaker component disables Bluetooth tracker component
  • TTS Bluetooth speaker component powers off Bluetooth, and powers it on again (terminates any running scans)
  • TTS Bluetooth speaker component plays the TTS MP3 file
  • TTS Bluetooth speaker component enables Bluetooth tracker component
  • Bluetooth tracker component continues scanning for devices (presence detection)

A bit more testing to do, but in the next day or so, I will put it up on GitHub.

Iā€™ve been testing for a while now, playing lengthy TTS files, and each one is played seamlessly (without any interruptions). Between these TTS playbacks, I can see the Bluetooth tracker scanning and finding devices. So both of these scenarios seem to be coexisting just fine.

OK, itā€™s now ready on GitHub. Only three files are required to make this all work:

custom_components/device_tracker/bluetooth_tracker.py

  • This is a drop-in replacement for the existing Bluetooth tracker component. It contains the exact same functionality as the original, except that it can be enabled/disabled so that the TTS service can gain exclusive access to the Piā€™s Bluetooth.

custom_components/media_player/tts_bluetooth_speaker.py

  • This is the Bluetooth speaker component that can play TTS MP3 files. Whenever it needs to play TTS, it disables the Bluetooth tracker, plays the file to the Bluetooth speaker, and re-enables the Bluetooth tracker.

configuration.yaml

  • This is a sample configuration showing how the two components are set up.
device_tracker:
  - platform: bluetooth_tracker

media_player:
  - platform: tts_bluetooth_speaker
    address: 00:2F:AD:12:0D:42
    volume: 0.45
#    cache_dir: /tmp/tts    # Optional - make sure it matches the same setting in TTS config

I tested it using Developer Tools > Services int he HA frontend:

This works well on my system, so let me know how you go.

UPDATE: Another improvement. In the Bluetooth tracker, there is no longer any need for the code to power off, and power on, the Bluetooth on the Raspberry Pi, in order to cancel any pending scans (i.e. inquiries). Instead, it now calls a low-level Bluetooth library to cancel the ā€˜pending inquiriesā€™. Much nicer than power cycling the Bluetooth!

1 Like

Does this work with the Bluetooth low energy tracker enabled?

I should give the onboard BT a chance instead of taking dongle maybe

@matt2005 No idea. I donā€™t have any Bluetooth LE devices, but maybe you can try it?

@thundergreen I have only been using the Raspberry Pi onboard Bluetooth module. Would be interesting to see if this works the same using a dongle.

Doco has been added to the GitHub repo, and I have updated the first post in this thread to rermove the ā€˜oldā€™ instructions, and point everyone to the GitHub repo instead.

1 Like