diff --git a/bluetooth-audio/.asoundrc b/bluetooth/.asoundrc similarity index 100% rename from bluetooth-audio/.asoundrc rename to bluetooth/.asoundrc diff --git a/bluetooth-audio/Dockerfile.aarch64 b/bluetooth/Dockerfile.aarch64 similarity index 88% rename from bluetooth-audio/Dockerfile.aarch64 rename to bluetooth/Dockerfile.aarch64 index 7e3a575e..9823bab4 100644 --- a/bluetooth-audio/Dockerfile.aarch64 +++ b/bluetooth/Dockerfile.aarch64 @@ -14,6 +14,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 diff --git a/bluetooth-audio/Dockerfile.template b/bluetooth/Dockerfile.template similarity index 88% rename from bluetooth-audio/Dockerfile.template rename to bluetooth/Dockerfile.template index 6dbe9c6b..dc979de3 100644 --- a/bluetooth-audio/Dockerfile.template +++ b/bluetooth/Dockerfile.template @@ -14,6 +14,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 diff --git a/bluetooth-audio/bluetooth-agent b/bluetooth/bluetooth-agent similarity index 100% rename from bluetooth-audio/bluetooth-agent rename to bluetooth/bluetooth-agent diff --git a/bluetooth/bluetooth-control b/bluetooth/bluetooth-control new file mode 100644 index 00000000..3ae5a659 --- /dev/null +++ b/bluetooth/bluetooth-control @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +# Set up variables +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 + +# Set up next +if [[ ! -d /sys/class/gpio/gpio$NEXT_GPIO ]]; then + echo "$NEXT_GPIO" > /sys/class/gpio/export + sleep 1 +fi +echo "in" > /sys/class/gpio/gpio$NEXT_GPIO/direction + +# Set up previous +if [[ ! -d /sys/class/gpio/gpio$PREVIOUS_GPIO ]]; then + echo "$PREVIOUS_GPIO" > /sys/class/gpio/export + sleep 1 +fi +echo "in" > /sys/class/gpio/gpio$PREVIOUS_GPIO/direction + +# Set up utput gpio (there is one energy input missing) +if [[ ! -d /sys/class/gpio/gpio$OUTPUT_GPIO ]]; then + echo "$OUTPUT_GPIO" > /sys/class/gpio/export + sleep 1 +fi +echo "out" > /sys/class/gpio/gpio$OUTPUT_GPIO/direction + +while : ; do + +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" + printf "discoverable on\npairable on\nexit\n" | bluetoothctl > /dev/null + touch /usr/src/is_discoverable + (sleep 180 ; printf "Closing bluetooth discovery. \n" ; printf "discoverable off\npairable off\nexit\n" | bluetoothctl > /dev/null ; rm /usr/src/is_discoverable) & + else + printf "The device is already discoverable. \n" + fi +fi + +if [ -a /var/cache/bluetooth/reconnect_device ]; then + +# Get the alsa name of the connected device +DEVICE="$(echo "$(amixer -D bluealsa scontrols)" | sed -n " s,[^']*'\([^']*\).*,\1,p ")" + +# Get and parse the MAC Adress of the connected device +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)" + +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 + +# Next track +while [[ "$(cat /sys/class/gpio/gpio$NEXT_GPIO/value)" == 1 ]]; do + if [[ "$SKIP_STOP" == 0 ]]; then + printf "Playing the next track. \n" + dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED/player0 org.bluez.MediaPlayer1.Next + sleep 0.5 + fi + SKIP_STOP="1" +done + +SKIP_STOP="0" + +# Previous track +while [[ "$(cat /sys/class/gpio/gpio$PREVIOUS_GPIO/value)" == 1 ]]; do + if [[ "$SKIP_STOP" == 0 ]]; then + printf "Playing the previous track. \n" + dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED/player0 org.bluez.MediaPlayer1.Previous + sleep 0.5 + fi + SKIP_STOP="1" +done + +SKIP_STOP="0" + +fi + +TIMER="0" + +fi + +done diff --git a/bluetooth-audio/bluetooth-scripts/bluetooth-connect b/bluetooth/bluetooth-scripts/bluetooth-connect similarity index 78% rename from bluetooth-audio/bluetooth-scripts/bluetooth-connect rename to bluetooth/bluetooth-scripts/bluetooth-connect index a5d5b3bc..6d80e203 100644 --- a/bluetooth-audio/bluetooth-scripts/bluetooth-connect +++ b/bluetooth/bluetooth-scripts/bluetooth-connect @@ -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) \ No newline at end of file diff --git a/bluetooth-audio/bluetooth-scripts/bluetooth-disconnect b/bluetooth/bluetooth-scripts/bluetooth-disconnect similarity index 77% rename from bluetooth-audio/bluetooth-scripts/bluetooth-disconnect rename to bluetooth/bluetooth-scripts/bluetooth-disconnect index 3db00623..b6a7956b 100644 --- a/bluetooth-audio/bluetooth-scripts/bluetooth-disconnect +++ b/bluetooth/bluetooth-scripts/bluetooth-disconnect @@ -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) \ No newline at end of file diff --git a/bluetooth-audio/bluetooth-udev b/bluetooth/bluetooth-udev similarity index 94% rename from bluetooth-audio/bluetooth-udev rename to bluetooth/bluetooth-udev index 3930f85a..831e1e86 100644 --- a/bluetooth-audio/bluetooth-udev +++ b/bluetooth/bluetooth-udev @@ -1,4 +1,5 @@ -#!/bin/bash +#!/usr/bin/env bash + export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket name=$(sed 's/\"//g' <<< $NAME) @@ -26,12 +27,13 @@ add) fi ;; remove) + printf "discoverable off\npairable off\nexit\n" | bluetoothctl + amixer -M sset PCM,0 $CONNECTION_NOTIFY_VOLUME% > /dev/null & amixer -M sset Digital,0 $CONNECTION_NOTIFY_VOLUME% > /dev/null & aplay -D hw:0,0 /usr/src/sounds/disconnect.wav > /dev/null 2>&1 - printf "discoverable on\npairable on\nexit\n" | bluetoothctl amixer -M sset PCM,0 $SYSTEM_OUTPUT_VOLUME% > /dev/null & amixer -M sset Digital,0 $SYSTEM_OUTPUT_VOLUME% > /dev/null & if [[ -z "$BLUETOOTH_SCRIPTS" ]]; then diff --git a/bluetooth-audio/sounds/connect.wav b/bluetooth/sounds/connect.wav similarity index 100% rename from bluetooth-audio/sounds/connect.wav rename to bluetooth/sounds/connect.wav diff --git a/bluetooth-audio/sounds/disconnect.wav b/bluetooth/sounds/disconnect.wav similarity index 100% rename from bluetooth-audio/sounds/disconnect.wav rename to bluetooth/sounds/disconnect.wav diff --git a/bluetooth-audio/start.sh b/bluetooth/start.sh similarity index 67% rename from bluetooth-audio/start.sh rename to bluetooth/start.sh index 8ce1ffc6..5572a7e2 100644 --- a/bluetooth-audio/start.sh +++ b/bluetooth/start.sh @@ -52,10 +52,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 "$DEVICE_NAME" if ! [ -z "$BLUETOOTH_PIN_CODE" ] && [[ $BLUETOOTH_PIN_CODE -gt 1 ]] && [[ $BLUETOOTH_PIN_CODE -lt 1000000 ]]; then @@ -66,6 +68,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 + printf "discoverable off\npairable off\nexit\n" | bluetoothctl > /dev/null +fi + # Reconnect if there is a known device sleep 2 if [ -f "/var/cache/bluetooth/reconnect_device" ]; then @@ -74,7 +80,40 @@ 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" + + NEXT_GPIO="${NEXT_GPIO:-10}" + echo $NEXT_GPIO > /usr/src/next_gpio + printf "Next track button input is on GPIO$NEXT_GPIO \n" + + PREVIOUS_GPIO="${PREVIOUS_GPIO:-9}" + echo $PREVIOUS_GPIO > /usr/src/previous_gpio + printf "Previous track button input is on GPIO$PREVIOUS_GPIO \n" + + OUTPUT_GPIO="${OUTPUT_GPIO:-11}" + echo $OUTPUT_GPIO > /usr/src/output_gpio + printf "A extra energy output is on GPIO$OUTPUT_GPIO \n" + + if [[ ! -z "CLOSE_DISCOVERY" ]]; then + touch /usr/src/close_discovery + printf "Bluetooth discovery will be deactivated if the device connects and bluetooth discovery got activated via gpio. \n" + fi + + bash /usr/src/bluetooth-control & +fi + sleep 2 printf "Device is discoverable as \"%s\"\n" "$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 diff --git a/bluetooth-audio/udev-rules/99-bluetooth-udev.rules b/bluetooth/udev-rules/99-bluetooth-udev.rules similarity index 100% rename from bluetooth-audio/udev-rules/99-bluetooth-udev.rules rename to bluetooth/udev-rules/99-bluetooth-udev.rules diff --git a/docker-compose.yml b/docker-compose.yml index 47cc4720..d6668f23 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '2' services: - bluetooth-audio: - build: ./bluetooth-audio + bluetooth: + build: ./bluetooth restart: on-failure network_mode: host privileged: true diff --git a/images/gpio-pins.png b/images/gpio-pins.png new file mode 100644 index 00000000..5e7a2fd4 Binary files /dev/null and b/images/gpio-pins.png differ diff --git a/repo.yml b/repo.yml index 7276f3a2..e944302c 100644 --- a/repo.yml +++ b/repo.yml @@ -1 +1,4 @@ type: balena +upstream: + - repo: balena-sound + url: https://github.com/balenalabs/balena-sound \ No newline at end of file