Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bluetooth remote control via GPIO #101

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

AlexProgrammerDE
Copy link
Contributor

@AlexProgrammerDE AlexProgrammerDE commented Feb 8, 2020

Change-type: major

Hi everyone! With #83 becomes balena-sound to a multi speaker project. But i think a good speaker has its own on-board music and volume control buttons. Here is a example:

buttons

Roadmap: (At the top are the more important things. )

finished:

  • Find a bluetooth remote control service (Bluealsa itself: https://github.com/Arkq/bluez-alsa#configuration--usage)
  • Make this feature 100% optional (It should be able to deactivate it 100%.)
  • Rename bluetooth-audio to bluetooth
  • Decide, which GPIO pins should be used ((Pin) Input: 11, 13 and 15 Output: 1, 17 and 4)
  • Delete buffer
  • Implement the bluetooth remote control service
  • Allow discovering via a button
  • Add skipping in both directions
  • Write README info

bugs:

@tmigone and @chrisys i will maybe need help from your side. If i run into some problems i will let you know in the comment section below.

Things i have to remember:
echo "$(amixer -D bluealsa scontrols)" | sed -n " s,[^']*'\([^']*\).*,\1,p "
VOLUME="$(amixer -D bluealsa get "$DEVICE" | awk '$0~/%/{print $5}' | tr -d '[]%')"
VOLUME_PARSED="$(echo "${VOLUME}" | head -1)"
https://askubuntu.com/questions/1113050/sending-pause-resume-playing-and-next-previous-track-bluetooth-commands
dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0/dev_$MAC_PARSED org.bluez.MediaControl1.Play > /dev/null

@AlexProgrammerDE
Copy link
Contributor Author

AlexProgrammerDE commented Feb 10, 2020

@tmigone i have a problem. Are there any ways of communicating between the multi room devices. I had an idea: Pressing buttons on the client device is acting like pressing buttons on the server device itself.

@chrisys
Copy link
Member

chrisys commented Feb 11, 2020

@AlexProgrammerDE great idea here! I think this is going to be an awesome addition to the project.

@AlexProgrammerDE

This comment has been minimized.

@tmigone
Copy link
Contributor

tmigone commented Feb 12, 2020

@AlexProgrammerDE this looks awesome!

Regarding your question, you can send messages between devices using the fleet-supervisor. For example:

You could do something like fleetPublisher.publish('bt-command', { command: 'whatever' })
Let me know if this helps.

EDIT: Now that i think of it, to use this you would need to migrate your control code to node. So i think it's fine if you focus on one device and once that is resolved we can look into the whole fleet.

@AlexProgrammerDE
Copy link
Contributor Author

AlexProgrammerDE commented Feb 20, 2020

@chrisys and @tmigone i had an idea. 🌟 What are buttons without an case? https://github.com/balenalabs/boombeastic/ has its own cases. Could anyone create some 3D models? Buttons integrated would be needed.

@AlexProgrammerDE AlexProgrammerDE changed the title WIP: Add bluetooth remote control via GPIO Add bluetooth remote control via GPIO Feb 20, 2020
@chrisys
Copy link
Member

chrisys commented Mar 24, 2020

Hey @AlexProgrammerDE do you think this would work with the Pimoroni Pirate Audio HATs? Check out @Fiqq90 comment in #111

@AlexProgrammerDE
Copy link
Contributor Author

Hi @chrisys
It should work, but which GPIO Pins are used by it? I didnt find any documentation.

@AlexProgrammerDE
Copy link
Contributor Author

@chrisys i just saw the docs. I will look into it.

@AlexProgrammerDE
Copy link
Contributor Author

AlexProgrammerDE commented Mar 24, 2020

@chrisys
So. The BCM pins are 5, 6, 16, and 20, but i have no HAT, so i cant test it.

@chrisys
Copy link
Member

chrisys commented Mar 25, 2020

@Fiqq90 can you test this on your Pirate audio HAT and let us know how if it works?

@AlexProgrammerDE
Copy link
Contributor Author

By the way @chrisys does the code work? I had it only tested with my Android phone. Does it work with IPhones?

@chrisys
Copy link
Member

chrisys commented Mar 25, 2020

@AlexProgrammerDE I haven't had a chance to test yet

@Fiqq90
Copy link

Fiqq90 commented Mar 25, 2020

@chrisys @AlexProgrammerDE I would love to test it out, but unfortunately I am new to all this. Any guides to get me started on testing via PR? I assume that this latest update for the pimoroni has not been merged with the master that I can download?

@AlexProgrammerDE
Copy link
Contributor Author

AlexProgrammerDE commented Mar 25, 2020

@Fiqq90 it is very easy to use my code. I made a fork of this repository on github. You can very easy download the zip file from there and push it like before.

@AlexProgrammerDE
Copy link
Contributor Author

@Fiqq90 the url of my repository is: https://github.com/AlexProgrammerDE/balena-sound

@Fiqq90
Copy link

Fiqq90 commented Mar 26, 2020

@AlexProgrammerDE Pushed the files from your repo. Unfortunately the buttons still do not work for the pirate audio HAT. Buttons still does nothing to control spotify via bluetooth.

@Fiqq90
Copy link

Fiqq90 commented Mar 26, 2020

From the log screen, volume up is still GPIO17, bluetooth button -> GPIO27, volume down -> GPIO22.

Could we set the inputs to play/pause -> GPIO5, vol down -> GPIO6, next -> GPIO16, vol up -> GPIO20?

@AlexProgrammerDE
Copy link
Contributor Author

AlexProgrammerDE commented Mar 27, 2020

@Fiqq90 i did already think of that case. I implemented it already. VOLUME_UP_GPIO, VOLUME_DOWN_GPIO and BLUETOOTH_GPIO are the enviroment variables for it. You can set them to the number of the GPIO. In your case: 5, 6, 16 and 20. But don´t use a number multiple times!

@AlexProgrammerDE
Copy link
Contributor Author

AlexProgrammerDE commented Mar 31, 2020

@chrisys can you test it please and give me feedback? I am almost finished.

@chrisys
Copy link
Member

chrisys commented Apr 1, 2020

@AlexProgrammerDE I will test it but need to find the hardware to put some buttons on a Pi first

@AlexProgrammerDE
Copy link
Contributor Author

@chrisys it works with jumper cables too. I put many information to the Readme. That should help you to work with it.

Change-type: major
@AlexProgrammerDE
Copy link
Contributor Author

@balena-ci retest

@ghost
Copy link

ghost commented Apr 11, 2020

An error occurred whilst building your landr site preview:

        {
  "name": "JSONHTTPError",
  "status": 422,
  "json": {
    "errors": {
      "subdomain": [
        "must be unique"
      ]
    }
  },
  "message": "Unprocessable Entity",
  "stack": "JSONHTTPError: Unprocessable Entity\n    at NetlifyAPI.createSite (/usr/src/app/node_modules/netlify/src/open-api/index.js:162:15)\n    at processTicksAndRejections (internal/process/task_queues.js:97:5)\n    at async Object.exports.setupSite (/usr/src/app/lib/netlify.js:43:18)\n    at async Object.exports.run (/usr/src/app/lib/build-runner.js:82:7)\n    at async build (/usr/src/app/bot/index.js:104:19)\n    at async /usr/src/app/bot/index.js:156:23"
}

@AlexProgrammerDE
Copy link
Contributor Author

@tmigone this PR is now open for about 4 months. Can we merge it soon?

@AlexProgrammerDE
Copy link
Contributor Author

@balena-ci retest

@tmigone
Copy link
Contributor

tmigone commented Jul 20, 2020

hey @AlexProgrammerDE sorry it took me so long, I'll work on testing this PR this week so we can have it in 2.x.

Comment on lines +22 to +62
# 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

# 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could eliminate a lot of code using a function here. Haven't tested it, but this should be ok:

Suggested change
# 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
# 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
function configure_gpio() {
local GPIO_PIN="$1"
local DIRECTION="$2"
if [[ ! -d /sys/class/gpio/gpio$GPIO_PIN ]]; then
echo "$GPIO_PIN" > /sys/class/gpio/export
sleep 1
fi
echo "$DIRECTION" > /sys/class/gpio/gpio$GPIO_PIN/direction
}
configure_gpio "$VOLUME_UP_GPIO" "in"
configure_gpio "$BLUETOOTH_GPIO" "in"
configure_gpio "$VOLUME_DOWN_GPIO" "in"
configure_gpio "$NEXT_GPIO" "in"
configure_gpio "$PREVIOUS_GPIO" "in"
configure_gpio "$OUTPUT_GPIO" "out"

Comment on lines +4 to +14
VOLUME_UP_GPIO=$(</usr/src/volume_up_gpio)

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

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

NEXT_GPIO=$(</usr/src/next_gpio)

PREVIOUS_GPIO=$(</usr/src/previous_gpio)

OUTPUT_GPIO=$(</usr/src/output_gpio)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it, the other script writes the values into these files, and then this scripts reads the values.
Are the files used anywhere else? Can't we just have all done here and avoid the files alltogether?

Comment on lines +131 to +150
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before, if the code is nearly identical we should try and use functions to reduce code (also easier maintenance!)

@tmigone tmigone marked this pull request as draft October 29, 2020 20:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bluetooth Everything about the bluetooth container enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants