Managing bluetooth connections with systemd

· momo's blog


context #

A few day ago, I setup my raspberry pi as a AirPlay and Spotify connect speaker using rpi-audio-receiver. At first I tested it with an speaker connected with an aux cable, but I wanted to output to a bluetooth box. When starting the pi, it should automatically connect to the bluetooth box and on connection failures and losses it should try to reconnect. I searched online, but didn't find anything suitable for a headless setup, so I wrote this systemd service.

systemd service #

/etc/systemd/system/bluetooth-device@.service

[Unit]
Description=Bluetooth Device %i
After=bluetooth.target pulseaudio.service
StartLimitIntervalSec=60
StartLimitBurst=5

[Install]
WantedBy=multi-user.target

[Service]
ExecStart=/usr/local/bin/systemd-bluetooth.sh %i
Restart=on-failure
RestartSec=10

bash script #

/usr/local/bin/systemd-bluetooth.sh

 1#!/bin/bash
 2
 3MAC_ADDR=$1
 4
 5monitor_connection() {
 6  echo "started connectivity watchdog for device ${MAC_ADDR}"
 7  while true
 8  do
 9    bluetoothctl info $MAC_ADDR | grep "Connected" | grep no && on_disconnected_exit
10    sleep 10
11  done
12}
13
14connect() {
15  bluetoothctl connect $MAC_ADDR
16}
17
18disconnect() {
19  bluetoothctl disconnect $MAC_ADDR
20}
21
22on_disconnected_exit() {
23  echo "device ${MAC_ADDR} is not connected anymore, exiting"
24  exit 1
25}
26
27graceful_exit() {
28  echo "received exit request, disconnecting and exiting"
29  disconnect
30  exit 0
31}
32
33trap graceful_exit SIGTERM SIGABRT INT
34
35connect
36monitor_connection

usage #

1sudo systemctl daemon-reload
2sudo systemctl start bluetooth-device@DEVICE_MAC_ADDR
3sudo systemctl status bluetooth-device@DEVICE_MAC_ADDR