Skip to content

Commit

Permalink
Add bluetooth control support
Browse files Browse the repository at this point in the history
Change-type: major
  • Loading branch information
AlexProgrammerDE committed Feb 20, 2020
1 parent 04c3317 commit 11798d1
Show file tree
Hide file tree
Showing 18 changed files with 168 additions and 13 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
This project adheres to [Semantic Versioning](http://semver.org/).

# v2.0.1
## (2020-02-14)

* dac: Add dtoverlay for miniBoss DAC [Tomás Migone]

# v2.0.0
## (2020-02-12)

Expand Down
2 changes: 2 additions & 0 deletions DAC_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Please add the configuration values that work for your DAC to the table below.
| [Pisound][4] | pisound | Yes
| [Hifiberry DAC+][6] | hifiberry-dacplus | [Yes][7]
| [InnoMaker][8] | allo-boss-dac-pcm512x-audio | [Yes][9]
| [miniBoss DAC][10] | allo-boss-dac-pcm512x-audio | Yes


[1]: http://www.suptronics.com/Xseries/x400.html
Expand All @@ -32,3 +33,4 @@ Please add the configuration values that work for your DAC to the table below.
[7]: https://forums.balena.io/t/no-sound-from-dac/61343/5
[8]: http://www.inno-maker.com/product/hifi-dac-hat/
[9]: https://github.com/balenalabs/balena-sound/pull/98
[10]: https://allo.com/sparky/miniboss-rpi-zero.html
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,21 @@ If you don't want to use multi-room or you only have one device, you can disable

By default, balenaSound bluetooth will connect using Secure Simple Pairing mode. If you would like to override this and use Legacy Mode with a PIN code you can do it by defining the `BLUETOOTH_PIN_CODE` environment variable. The PIN code must be numeric and up to six digits (1 - 999999).

**Note**: Legacy Mode is no longer allowed on [iOS](https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf) devices.
**Note:** Legacy Mode is no longer allowed on [iOS](https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf) devices.

### GPIO bluetooth control

balenaSound allows you to control your mobile over bluetooth (Volume up/down and play/resume/stop) and enable bluetooth discovery. This feature is at default enabled, you can disable it by creating the `DISABLE_BLUETOOTH_CONTROL` variable (with any value, for example: `1`). You will have to connect some buttons to your GPIO pins to make use of this feature. We are using these pins:

![GPIO Pins](images/gpio-pins.png)

* GPIO17= Volume up
* GPIO27= Bluetooth discovery
* GPIO22= Volume down

If you don´t like these gpio pins you can set others manually with `VOLUME_UP_GPIO` `VOLUME_DOWN_GPIO` or/and `BLUETOOTH_GPIO` to another gpio. The value should be something like `17` or `27`(The number should be the one of the gpio and not of the pin!).

**Note:** Deactivating the automatic discovery of the device is recommended. This can be done by creating the `DISABLE_AUTO_DISCOVERY` variable (with any value, for example: `1`)

### Bluetooth scripts

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.0
2.0.1
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ RUN install_packages \
# Copy sounds
COPY sounds /usr/src/sounds

# Copy bluetooth-control script
COPY bluetooth-control /usr/src/
RUN chmod +x /usr/src/bluetooth-control

# Setup udev rules - this lets us play the connect/disconnect sound,
# turn off discover/pairing when a client is connected
# and also run a python script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ RUN install_packages \
# Copy sounds
COPY sounds /usr/src/sounds

# Copy bluetooth-control script
COPY bluetooth-control /usr/src/
RUN chmod +x /usr/src/bluetooth-control

# Setup udev rules - this lets us play the connect/disconnect sound,
# turn off discover/pairing when a client is connected
# and also run a python script
Expand Down
File renamed without changes.
101 changes: 101 additions & 0 deletions bluetooth/bluetooth-control
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env bash

# Set up variables
VOLUME_UP_GPIO=$(</usr/src/volume_up_gpio)

BLUETOOTH_GPIO=$(</usr/src/bluetooth_gpio)

VOLUME_DOWN_GPIO=$(</usr/src/volume_down_gpio)

TIMER="0"

BLUETOOTH_DISCOVERABLE="0"

# Set up + volume
if [[ ! -d /sys/class/gpio/gpio$VOLUME_UP_GPIO ]]; then
echo "$VOLUME_UP_GPIO" > /sys/class/gpio/export
sleep 1
fi
echo "in" > /sys/class/gpio/gpio$VOLUME_UP_GPIO/direction

# Set up bluetooth
if [[ ! -d /sys/class/gpio/gpio$BLUETOOTH_GPIO ]]; then
echo "$BLUETOOTH_GPIO" > /sys/class/gpio/export
sleep 1
fi
echo "in" > /sys/class/gpio/gpio$BLUETOOTH_GPIO/direction

# Set up - volume
if [[ ! -d /sys/class/gpio/gpio$VOLUME_DOWN_GPIO ]]; then
echo "$VOLUME_DOWN_GPIO" > /sys/class/gpio/export
sleep 1
fi
echo "in" > /sys/class/gpio/gpio$VOLUME_DOWN_GPIO/direction

while : ; do

DEVICE="$(echo "$(amixer -D bluealsa scontrols)" | sed -n " s,[^']*'\([^']*\).*,\1,p ")"
MAC="$(cat /var/cache/bluetooth/reconnect_device)"
MAC_PARSED="$(echo ${MAC//:/_})"
# PLAYER_ADDRESS="$(echo "$(dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED org.freedesktop.DBus.Properties.Get string:org.bluez.MediaControl1 string:Player)" | cut -d'"' -f 2)"

while [[ "$(cat /sys/class/gpio/gpio$BLUETOOTH_GPIO/value)" == 1 ]]; do
if [[ "$TIMER" < 3 ]]; then
TIMER=$((TIMER+1))
sleep 1
fi
done

if [[ "$TIMER" == 3 ]]; then
if [[ ! -a /usr/src/is_discoverable ]]; then
printf "Making the device for 3 min discoverable. \n"
hciconfig hci0 up
touch /usr/src/is_discoverable
(sleep 180 ; hciconfig hci0 down ; rm /usr/src/is_discoverable) &
else
printf "The device is already discoverable. \n"
fi
fi

if [[ ! -z "$(echo "$(amixer -D bluealsa scontrols)" | sed -n " s,[^']*'\([^']*\).*,\1,p ")" ]]; then

# Volume up
if [[ "$(cat /sys/class/gpio/gpio$VOLUME_UP_GPIO/value)" == 1 ]]; then
printf "Setting volume higher. \n"
amixer -D bluealsa sset "$DEVICE" 10%+
sleep 0.5
fi

if [[ "$TIMER" == 1 ]]; then
if [[ "$(dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED/player0 org.freedesktop.DBus.Properties.Get string:org.bluez.MediaPlayer1 string:Status | cut -d'"' -f 2)" == *"playing"* ]]; then
printf "Stoping music playback. \n"
dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED/player0 org.bluez.MediaPlayer1.Pause
else
printf "Starting music playback. \n"
dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED/player0 org.bluez.MediaPlayer1.Play
fi
fi

if [[ "$TIMER" == 2 ]]; then
if [[ "$(dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED/player0 org.freedesktop.DBus.Properties.Get string:org.bluez.MediaPlayer1 string:Status | cut -d'"' -f 2)" == *"playing"* ]]; then
printf "Stoping music playback. \n"
dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED/player0 org.bluez.MediaPlayer1.Pause
else
printf "Starting music playback. \n"
dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED/player0 org.bluez.MediaPlayer1.Play
fi
fi


# Volume down
if [[ "$(cat /sys/class/gpio/gpio$VOLUME_DOWN_GPIO/value)" == 1 ]]; then
printf "Setting volume lower. \n"
amixer -D bluealsa sset "$DEVICE" 10%-
sleep 0.5
fi

fi

TIMER="0"

done
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
#!/usr/bin/python
# This sript runs, when your pi connects to a bluetooth device and BLUETOOTH_CONNECT is set to anything.
# This sript runs, when your pi connects to a bluetooth device and BLUETOOTH_SCRIPTS is set to true.
# You can add your own code. BalenaSound has gpiozero installed so you can work with it.
# Here is a example:

# from gpiozero import LED
# from time import sleep

# led = LED(17)
# led = LED(16)

# led.off()
# sleep(1)

# sleep(1)
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#!/usr/bin/python
# This sript runs, when your pi disconnects from a bluetooth device and BLUETOOTH_DISCONNECT is set to anything.
# This sript runs, when your pi disconnects from a bluetooth device and BLUETOOTH_SCRIPTS is set to true.
# You can add your own code. BalenaSound has gpiozero installed so you can work with it.
# Here is a example:

# from gpiozero import LED
# from time import sleep

# led = LED(17)
# led = LED(16)

# led.off()
# sleep(1)
# sleep(1)
3 changes: 3 additions & 0 deletions bluetooth-audio/bluetooth-udev → bluetooth/bluetooth-udev
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ add)
if [[ -z "$BLUETOOTH_SCRIPTS" ]]; then
python /usr/src/bluetooth-scripts/bluetooth-connect
fi
if [[ -a /usr/src/is_discoverable ]]; then
hciconfig hci0 down
fi
;;
remove)
mplayer -volume $CONNECTION_NOTIFY_VOLUME /usr/src/sounds/disconnect.mp3 -really-quiet > /dev/null 2>&1
Expand Down
File renamed without changes.
File renamed without changes.
27 changes: 25 additions & 2 deletions bluetooth-audio/start.sh → bluetooth/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ fi

sleep 2
rm -rf /var/run/bluealsa/
/usr/bin/bluealsa -i hci0 -p a2dp-sink &
/usr/bin/bluealsa -i hci0 -p a2dp-sink --a2dp-volume &

hciconfig hci1 down > /dev/null 2>&1 # Disable onboard bluetooth if using a bluetooth dongle (onboard interface gets remapped to hci1)

hciconfig hci0 up

hciconfig hci0 name "$BLUETOOTH_DEVICE_NAME"

if ! [ -z "$BLUETOOTH_PIN_CODE" ] && [[ $BLUETOOTH_PIN_CODE -gt 1 ]] && [[ $BLUETOOTH_PIN_CODE -lt 1000000 ]]; then
Expand All @@ -52,6 +54,10 @@ else
printf "Starting bluetooth agent in Secure Simple Pairing Mode (SSPM) - No PIN code provided or invalid\n"
fi

if [[ ! -z "$DISABLE_AUTO_DISCOVERY" ]]; then
hciconfig hci0 down
fi

# Reconnect if there is a known device
sleep 2
if [ -f "/var/cache/bluetooth/reconnect_device" ]; then
Expand All @@ -60,6 +66,23 @@ if [ -f "/var/cache/bluetooth/reconnect_device" ]; then
printf "connect %s\nexit\n" "$TRUSTED_MAC_ADDRESS" | bluetoothctl > /dev/null
fi

# Start gpio bluetooth control service
if [[ -z "$DISABLE_BLUETOOTH_CONTROL" ]]; then
VOLUME_UP_GPIO="${VOLUME_UP_GPIO:-17}"
echo $VOLUME_UP_GPIO > /usr/src/volume_up_gpio
printf "Volume up button input is on GPIO$VOLUME_UP_GPIO \n"

BLUETOOTH_GPIO="${BLUETOOTH_GPIO:-27}"
echo $BLUETOOTH_GPIO > /usr/src/bluetooth_gpio
printf "Bluetooth button input is on GPIO$BLUETOOTH_GPIO \n"

VOLUME_DOWN_GPIO="${VOLUME_DOWN_GPIO:-22}"
echo $VOLUME_DOWN_GPIO > /usr/src/volume_down_gpio
printf "Volume down button input is on GPIO$VOLUME_DOWN_GPIO \n"

bash /usr/src/bluetooth-control &
fi

sleep 2
printf "Device is discoverable as \"%s\"\n" "$BLUETOOTH_DEVICE_NAME"
exec /usr/bin/bluealsa-aplay --pcm-buffer-time=1000000 00:00:00:00:00:00
exec /usr/bin/bluealsa-aplay --profile-a2dp 00:00:00:00:00:00
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: '2'
services:
bluetooth-audio:
build: ./bluetooth-audio
bluetooth:
build: ./bluetooth
restart: always
network_mode: host
privileged: true
Expand Down
Binary file added images/gpio-pins.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 11798d1

Please sign in to comment.