Skip to content

Latest commit

 

History

History
349 lines (237 loc) · 15.4 KB

setup.md

File metadata and controls

349 lines (237 loc) · 15.4 KB

Software Setup

Caution

The instructions in the section below can be a bit technical and should be streamlined. If you are planning on following them and get stuck, feel free to send an email and I will try to help out.

We are assuming the code is run from a raspberry pi running Raspberry Pi OS Lite 32-Bit and that the raspberry pi has some way to connect to Wi-Fi. Bluetooth connectivity is required if speakers are to be driven wirelessly (as opposed to via 3.5mm jack of the Pi).

Important

We are assuming you will configure your installation of Raspberry Pi OS with username musicpi and device name SpotiStation.

Raspbian OS Lite comes with A Python 3 installation, and a GPIO library, so that will be pre-installed. But we will still need to get pip installed.

sudo apt-get install python3-pip -y

To drive the Adafruit NeoSlider we will need to get the appropriate package

pip3 install adafruit-circuitpython-seesaw

In addition, we will need to activate the I2C (hardware) interface on the Pi (disabled by default). We can do this in the configuration of the raspberry pi.

sudo raspi-config

In the configuration menu, go to Interface Options, enable I2C and close out of the menu.

For reasons that are not entirely clear to me, the NeoSlider does not work well with the default i2c bus frequency. It will randomly lock up the bus, or read values beyond it's normal valid range (0,1023). To fix this, we need to change the i2c bus frequency to 400kHz on the Pi.

  1. Open system config sudo nano /boot/config.txt. Be careful not to mess anything up there.
  2. Find the line dtparam=i2c_arm=on
  3. Add i2c_arm_baudrate=400000 to the same line (comma separated), so it now reads dtparam=i2c_arm=on,i2c_arm_baudrate=400000
  4. Save and exit nano (ctrl s, ctrl x)
  5. Reboot (maybe even power cycle)

We will also need to be able to control the system volume, for which we will need another python package

pip3 install pyalsaaudio

💾 Download the SpotiStation code

We will need to get the SpotiStation code onto the raspberry Pi. You can either

  1. Clone this repository directly (this will get you the latest version of the code)
  2. Download the latest release (generally older but more stable in principle)

Whichever option you chose, we want the contents to be stored in a folder called SpotiStation located in the home directory. Make one and enter it by

cd 
mkdir SpotiStation

And then for option (1) we use

git clone https://github.com/NemoAndrea/SpotiStation.git SpotiStation

And for option (2)

curl -L https://api.github.com/repos/NemoAndrea/SpotiStation/tarball/<version> -o spotistation.tgz
tar -xvf spotistation.tgz --strip-components=1 -C SpotiStation

Where you replace <version> with whichever release is the latest, e.g. v0.1.0

🌈 RGB panel setup

We follow Adafruit's guide and install the drivers by Henner Zeller [email protected]. Download and run the installer script by:

curl https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/main/rgb-matrix.sh >rgb-matrix.sh
sudo bash rgb-matrix.sh

And follow the instructions in the installer script. We are using the matrix bonnet, not the hat with RTC. We also want the quality option.

  • Solder jumper between 4 and 18, picture quality is not good enough without. Analog audio (3.5mm jack or HDMI) will be disabled, but Bluetooth audio is fine.
  • Enable the CPU core reservation (pi 3, zero 2, and 4) in /boot/cmdline.txt, by adding isolcpus=3 to the file (space separated from other items in that file). Example contents: console=serial0,115200 console=tty1 root=PARTUUID=060e4657-02 rootfstype=ext4 fsck.repair=yes rootwait isolcpus=3

🎵 Setup - Spotify (background)

To stream Spotify, we will use spotifyd. We need to install the latest release (for ARMv6), as per the instructions laid out on their raspberry pi guide page. For completeness I will cover the contents of their page here. If in doubt, follow the instructions on spotifyd's page. Make sure you get the latest release. At the time of writing, the latest version is 0.3.3, so we install that with:

wget https://github.com/Spotifyd/spotifyd/releases/download/v0.3.3/spotifyd-linux-armv6-slim.tar.gz

This setup assumes you are downloading this into your home directory on the raspberry pi. (type cd to go there if you are not sure)

The command above will give you a tar.gz archive, which you can unpack with

tar -xf <name of downloaded file>.tar.gz

Now we need to create a config file where we set upspotifyd to our liking.

mkdir ~/.config/spotifyd/

It may be the case that you do not have a .config folder on your Pi. If so, just create an empty one by mkdir ~/.config

and again we must create and edit this file in nano (use nano ~/.config/spotifyd/spotifyd.conf) and paste the following information into it:

[global]
#username_cmd = "jq -r .username /home/musicpi/.cache/spotifyd/credentials.json"
backend = "alsa"
#device = alsa_audio_device # Given by `aplay -L`
mixer = "PCM"
volume-controller = "alsa" # or alsa_linear, or softvol
#onevent = command_run_on_playback_event
device_name = "SpotiStation"
bitrate = 320
cache_path = "/home/musicpi/.cache/spotifyd"
volume-normalisation = true
normalisation-pregain = -10

(optional): device uncomment this line (remove #) and set a device if you want to select a specific output for audio (e.g. HDMI/Bluetooth)

If you use Facebook login for Spotify, you will need to go to Spotify's website and look at your account settings. You should be able to find a numerical username. This is the username you will want to use for spotifyd. As for the password, you will probably have to request a 'device password' somewhere in the account settings in Spotify. This takes less than 3 minutes.

If you have created your config, it would be good to check if its all working before making the daemon start up automatically. Give it a whirl by typing ~/spotifyd --no-daemon. You should get some information about the information it is using and if it managed to make a connection. If you go to Spotify on your phone or pc, the device should now be listed in playback devices (as 'SpotiStation')!

spotify device playback menu showing spotistation listed

If you managed to connect to the device as a spotify playback device and tried to play some music over it, a new file should have been created in /home/musicpi/.cache/spotifyd called credentials.json. If that file exists, you can uncomment the line with username_cmd. Next time the service is run, it will be listed as one of your speakers (rather than one that your account has never seen before).

If everything worked up to this point, it is time to set spotifyd to start when the raspberry pi is booted. That way we always have it running and ready to play! Let's make a service file for systemctl to run.

mkdir -p ~/.config/systemd/user/
nano ~/.config/systemd/user/spotifyd.service

This will open the text editor nano. You need to copy the contents of github.com/Spotifyd/spotifyd/blob/master/contrib/spotifyd.service into it. As before, use the most up-to-date version that is found at that URL. For completeness, this is the version I used:

[Unit]
Description=A spotify playing daemon
Documentation=https://github.com/Spotifyd/spotifyd
Wants=sound.target
After=sound.target
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=<path to where you unzipped spotifyd - e.g. /home/<username>/spotifyd> --no-daemon
Restart=always
RestartSec=12

[Install]
WantedBy=default.target

And then we can run systemctl --user daemon-reload. And then give the background process a test run with systemctl --user start spotifyd.service. Check in Spotify if the raspberry pi showed up in playback devices after running that command.

If it's working, all we need to do is ensure this runs on startup. This is simple with the two following commands:

sudo loginctl enable-linger <username>
systemctl --user enable spotifyd.service

Let's do one final check if its all set up right: shut down your raspberry pi (sudo shutdown -h now) and the raspberry pi should disappear from Spotify devices after a short while. Now start up the raspberry pi and see if it shows up in Spotify devices automatically!

Setup - Spotify (API control)

While spotifyd actually handles the audio streaming, it does not control playback. Playback control and playlist selection etc is done via the Spotify API. Luckily, there is a python package for this called spotipy. Let's install it

pip3 install spotipy

We need to get credentials for the api, which we can realise by making an 'app' in the spotify developer bashboard. Go to the dashboard, add a new app, and from that new app get the client id and the client secret and redirect url.

Redirect url is best set to something local; I suggest http://localhost:8888/callback. You will need to set this in the Spotify dashboard in your app under the app-specific settings.

We will put these credentials in environment variables as one would not want to have this included in the repository. In the Raspberry Pi's terminal, fill out the following statements.

export SPOTIPY_CLIENT_ID='your-spotify-client-id'
export SPOTIPY_CLIENT_SECRET='your-spotify-client-secret'
export SPOTIPY_REDIRECT_URI='your-app-redirect-url'

then navigate into the SpotiStation repository and run python /src/cache_spotipy_credentials.py and follow the instructions. If all is well, you will be shown a link. Paste that link in a browser where you are signed into Spotify. You will be asked to agree to some terms. Read the terms, agree and then you will be shown a blank/error page. This is not a mistake! The URL of the page will actually contain a code that you need to paste back into your terminal! Copy the entire url and paste it into the terminal as asked. Check that after this procedure a .cache file was generated in the current directory.

**🚧 This section is in need of revision - the cache file is currently not used.

If that went well a .creds file should have been generated. Move it into the root folder of the repository (so out of src).

Now you can use

import spotipy
from spotipy.oauth2 import SpotifyOAuth

sp = spotipy.Spotify(auth_manager=SpotifyOAuth())

and use it as you would expect

Setup - Bluetooth speaker

Apparently you cannot use Bluetooth and Wi-Fi at the same time on a RPi with the built-in system so a dongle is needed. Let's use a dongle for Bluetooth and disable the internal one in /boot/config.txt,.

dtoverlay=pi3-disable-bt-overlay

Apparently, raspbian OS lite does not come with all the bits and pieces needed to connect to Bluetooth speakers. Luckily, others have treaded before. For whatever reason, pulseaudio is required for this. Let's install it by

sudo apt install pulseaudio-module-bluetooth

We also need to change some permissions of our main user account (find it by typing who in terminal). You will have chosen this name when you generated a Raspbian OS installation image.

sudo usermod -a -G bluetooth <useraccount>

And reboot the Raspberry Pi (sudo reboot)

Now we start connecting to the speaker. First we must use the bluetoothctl command to be brought into a separate CLI. Turn on your Bluetooth device, and make sure it is in pairing mode (if connecting for the first time). In this new CLI, type

scan on

wait for your speaker to show up (your speaker should be listed by name - give it a minute to scan for devices). Once you see your speaker name, we can stop the scanning by scan off. Now we must make a note of the Bluetooth MAC address (e.g. 00:11:22:33:FF:EE). Then, with the Bluetooth speaker in pairing mode, enter

pair <MAC adress>
trust <MAC adress>

Now we are paired (but not connected) with the device - this is the one-time setup part. To actually connect, type

connect <MAC adress

Setup - run slider volume control as service

We run the volume control via the slider as a separate scrip to ensure we can always adjust volume even if the main program crashes. So, let's set that up.

nano ~/.config/systemd/user/rpi-spotiplayer-volume.service

And make the file contents:

[Unit]
Description=Volume control handler for SpotiStation

[Service]
Type=simple
WorkingDirectory=/home/musicpi/SpotiStation
ExecStart=/usr/bin/python /home/musicpi/SpotiStation/src/regulate_volume.py
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

Next, make the service runnable:

sudo chmod 644 ~/.config/systemd/user/rpi-spotiplayer-volume.service

And finally make sure it runs after system boot:

systemctl --user enable rpi-spotiplayer-volume.service

Setup - run music player as service

We need to ensure the music player runs as a service upon startup. We use the same approach as before, but specify that we want to run this as root, but still as a user.

I must admit here that I am not entirely too sure how this whole root thing works, as a normal systemctl process (in /lib/) would make more sense, but that has no access to the python environment so I am just going with what is below - which seems to work fine.

nano ~/.config/systemd/user/rpi-spotiplayer.service

We make the contents of the file the following:

[Unit]
Description=A python spotify music player service
Requisite=spotifyd.service
After=spotifyd.service

[Service]
Type=simple
WorkingDirectory=/home/musicpi/SpotiStation
ExecStart=/usr/bin/sudo -E /usr/bin/python /home/musicpi/SpotiStation/src/start_player.py
Restart=always
RestartSec=60

[Install]
WantedBy=default.target

We set it such that it will restart automatically when the python script exits (which will only happen in case of an error)

We make it active via:

 sudo chmod 644 ~/.config/systemd/user/rpi-spotiplayer.service

And then we update our systemctl process by running sudo systemctl --user daemon-reload. As before, it is good to see if it works before making it run on start-up by running systemctl --user start rpi-spotiplayer.service. That should start the player as normal after few seconds.

If that all seems to work well, stop the process and set it up for running at boot:

systemctl --user enable rpi-spotiplayer.service

.bashrc setup

Nice to have, but not needed

alias startplayer='systemctl --user start rpi-spotiplayer.service'
alias stopplayer='systemctl --user stop rpi-spotiplayer.service'
alias restartplayer='systemctl --user restart rpi-spotiplayer.service'
# in case you want to manually start the player and observe the log in terminal via SSH
# make sure the service is stopped and that you are in the repository directory
alias startplayer_manual='sudo -E python ~/SpotiStation/src/start_player.py'