I have been running HomeAssistant in our apartment for quite a while now. It is pretty well integrated and can adjust the lights, detect presence in all rooms and monitors temperature and humidity. One feature that I’ve been meaning to add for quite a while now is voice feedback using Text To Speech. HomeAssistant is running on my server in the livingroom that doesn’t have any speakers nearby. Ideally, the sound output should go through the Echo Dot but the API currently doesn’t support output besides what the Alexa Skills provide.
Thankfully, it is possible to connect to the Dot using Bluetooth for audio playback. Unfortunately, the setup on the server side wasn’t all that easy which is why I’m writing up the steps that I collected from various sources. This should work for a HomeAssistant installation on a Ubuntu 17.10 machine and assumes that HomeAssistant is already configured properly.
First, we’ll want to install the dependencies:
sudo apt install pulseaudio pulseaudio-module-bluetooth vlc bluez bluez-tools
Since I’m running the server headless, there are no X-sessions and therefore pulseaudio will not be started for the login user. Instead, we can run pulseaudio in system mode. To do so, we need to create the necessary users and groups.
addgroup --system pulse adduser --system --ingroup pulse --home /var/run/pulse pulse addgroup --system pulse-access adduser pulse audio adduser homeassistant pulse-access
The last line allows the homeassistant user to access the audio devices.
Now we can create a systemd service file /etc/systemd/system/pulseaudio.service with the following content:
[Unit] Description=PulseAudio system server [Service] Type=notify ExecStart=/usr/bin/pulseaudio --daemonize=no --system --realtime --log-target=journal [Install] WantedBy=multi-user.target
Since we want to allow pulseaudio to access bluetooth devices, we have to add some d-bus rules in /etc/dbus-1/system.d/pulse.conf:
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <policy user="root"> <allow own="org.pulseaudio.Server"/> <allow send_destination="org.bluez"/> <allow send_interface="org.bluez.Manager"/> </policy> <policy user="pulse"> <allow own="org.pulseaudio.Server"/> <allow send_destination="org.bluez"/> <allow send_interface="org.bluez.Manager"/> </policy> <policy context="default"> <deny own="org.pulseaudio.Server"/> <deny send_destination="org.bluez"/> <deny send_interface="org.bluez.Manager"/> </policy> </busconfig>
Last but not least, we need to tell pulseaudio to always load the relevant bluetooth modules. This can be done by adding the following lines in /etc/pulse/system.pa:
### Automatically load driver modules for Bluetooth hardware .ifexists module-bluetooth-policy.so load-module module-bluetooth-policy .endif .ifexists module-bluetooth-discover.so load-module module-bluetooth-discover .endif
Finally, we can enable and start the service:
systemctl --system enable pulseaudio.service systemctl --system start pulseaudio.service
Now we need to make sure that Bluetooth is enabled and running:
systemctl --system enable bluetooth.service systemctl --system start bluetooth.service
Then we can pair the Echo Dot. This is done by using the command bluetoothctl.
sudo bluetoothctl [bluetooth]# discoverable on Changing discoverable on succeeded [bluetooth]# pairable on Changing pairable on succeeded [bluetooth]# agent on Agent registered [bluetooth]# default-agent Default agent request successful
Now, the server should be visible to the Echo Dot under its hostname. Pairing can be initiated through the Alexa app. During the pairing, there might be a request for confirmation. Afterwords, bluetoothctl can be quit.
At this point, everything should already be working. We can test this by adding the following lines in the HomeAssistant configuration:
media_player: - platform: vlc tts: - platform: google
We can the go to the web interface and in the service call section call the service tts.google_say with the following parameters:
This should cause HomeAssistant to request a TTS audio file from the Google TTS service. The file is then passed on to VLC which will play the file through the default pulseaudio device which is the bluetooth device.
This setup will continue to work as long as the server isn’t rebooted or the connection drops. In order to ensure that the bluetooth device is always connected, we can add a small daemon that repeatedly verifies that the device is connected and otherwise connects it. To do so, we create the script /usr/local/bin/echo-watchdog.sh (Fill in your Echo Dot’s MAC address):
#!/bin/bash MAC="XX:XX:XX:XX:XX:XX" while : do if ! [[ $(hcitool con | grep $MAC) ]]; then echo "Echo is not yet connected" echo -e "connect $MAC\nquit\n" | bluetoothctl fi sleep 1 done
chmod +x /usr/local/bin/echo-watchdog.sh
And then we can create a systemd service file /etc/systemd/system/echo-watchdog.service for it:
[Unit] After=bluetooth.service [Service] ExecStart=/usr/local/bin/echo-watchdog.sh [Install] WantedBy=default.target
By enabling and starting it, we make sure that the server always tries to connect the Echo Dot when it is available:
systemctl --system enable echo-watchdog.service systemctl --system start echo-watchdog.service
Now everything is up and running and TTS can be integrated into the HomeAssistant scripts.