Phoniebox Version 2.x - from boot to playout
This document explains the functionality of the
Phoniebox
code base.
1. Boot - this is what happens when you fire up your Phoniebox
After booting, the Phoniebox runs the file startup-scripts.sh
via the systemd
System and Service Manager phoniebox-startup-scripts.service.stretch-default.sample
.
Links:
1.1 Read global configuration file (and create is non-existent)
The file settings/global.conf
contains all settings in
one place so that the Phoniebox only needs to access the SD-card once
when in operation and e.g. a RFID card is swiped to start playout. If
there is no settings/global.conf
file, it will be created
first. This is necessary for the first boot process.
The shell script scripts/inc.writeGlobalConfig.sh
was
introduced as a swiss army knife to create this file. It was also
created to make sure that the configuration file is complete - in case
somebody updates from git
. It operates as such:
- If non-existent
settings/rfid_trigger_play.conf
create one fromsettings/rfid_trigger_play.conf.sample
- Run through all possible individual files, like
settings/Audio_Folders_Path
(containing the path to audio files)- Create file with a default value, if non-existent.
- Read value from file
- Write
settings/global.conf
, now that we have all values (either available from exisiting files or created default values)
Links:
1.2 Make all folders accessible for reading and writing
The folders in question are:
- folders and subfolders where the audio files are
- all the shortcuts (meaning the connections between RFID tags and audio folders, podcasts, etc.)
- the folder containing the playlists for MPD
This step was introduced, because some manual installations resulted in in-adequate read/write access.
1.3 Wait until mopidy/MPD server is running
STATUS=0
while [ "$STATUS" != "ACTIVE" ]; do STATUS=$(echo -e status\\nclose | nc -w 1 localhost 6600 | grep 'OK MPD'| sed 's/^.*$/ACTIVE/'); done
1.4 Set system volume on startup
1.5 Play startup sound
1.6 Re-scan MPD music library
1.7 Read out wifi config
This was introduced, because if the Phoniebox gets a dynamic IP in a new WiFi and you want to control it over the WebApp, you need to know the IP address.
1.8 Default audio output to speakers (instead of bluetooth device) irrespective of setting at shutdown
If you had a bluetooth device connected, this connection will be lost after a reboot. Default to the built in speakers.
2. Starting playout with an RFID card
A swiped RFID card is caught by the systemd
System and
Service Manager phoniebox-rfid-reader.service.stretch-default.sample
.
The daemon waiting in the background is scripts/daemon_rfid_reader.py
.
The ID of the RFID card is then handed over to the shell script scripts/rfid_trigger_play.sh
Links:
phoniebox-rfid-reader.service.stretch-default.sample
scripts/daemon_rfid_reader.py
scripts/rfid_trigger_play.sh
2.1
Variables passed on to scripts/rfid_trigger_play.sh
The variables that can be passed on are:
- Card ID as -i=* or –cardid=* which will be stored in the variable CARDID
- Command as -c=* or –command=* which will be stored in the variable COMMAND
- Directory (containing audio files) as -d=* or –dir=* which will be stored in the variable FOLDER
- Value (e.g. volume changes) as -v=* or –value=* which will be stored in the variable VALUE
Links:
2.2 Decide Action for Card ID
Write Card ID to file settings/Latest_RFID
for later use
(e.g. WebApp to link card ID to action of folder)
2.2.1 Check: card ID triggers system command (e.g. shutdown or volume up)
- Assigned system command IDs are loaded by reading
settings/rfid_trigger_play.conf
- If ID matches system command:
- execute command (with optional variables)
- and EXIT
2.2.2 (else) Check: card ID matches existing shortcut
Check if card ID matches name of existing file in folder
shared/shortcuts/
YES:
- Read content from shortcut file into variable
FOLDER
NO:
- Create shortcut file with card ID as name AND card ID is also content
- Assign card ID to variable
FOLDER
(will be played later, if folder exists!)
2.3
Check if we now have a valid folder name in variable
FOLDER
.
Required conditions for FOLDER
:
- is set
- is not empty
- points to existing directory (AUDIOFOLDERSPATH/FOLDER)
2.3.1 Check: folder has config file?
If Folder config file is non-existent run
scripts/inc.writeFolderConfig.sh
to create and fill with
default values (a similar procedure to
scripts/inc.writeGlobalConfig.sh
explained above):
- Fill all possible folder config variables with default values
(e.g.
SHUFFLE="OFF"
) - Write
folder.conf
from default values
Links:
2.3.2 Creating
playlist from FOLDER
linked to card ID
A playlist is a plain text file listing individual paths and files.
Before we make playlists, we need to keep in mind these two variables for later decisions:
- Fill variable
LASTFOLDER
with content ofsettings/Latest_Folder_Played
- Fill variable
LASTPLAYLIST
with content ofsettings/Latest_Playlist_Played
Is our playlist normal (play files in folder) or recursive (play content of folder and subfolders)?
- NORMAL:
- Var
PLAYLISTNAME
is identical folder name (FOLDER
) + “.m3u” - Note:
FOLDER
might contain slashes, whitespaces or other special characters. This might need char replacements. - Create playlist with script
scripts/playlist_recursive_by_folder.php --folder "${FOLDER}" --list 'recursive'
(see below for explanation of this script)
- Var
- RECURSIVE:
- Unique name needed: different playlist name for recursive
- Var
PLAYLISTNAME
is folder name (FOLDER
) + “-%RCRSV%.m3u”
- Var
- Note:
FOLDER
might contain slashes, whitespaces or other special characters. This might need char replacements. - Create playlist with script
scripts/playlist_recursive_by_folder.php --folder "${FOLDER}"
(see below for explanation of this script)
- Unique name needed: different playlist name for recursive
2.4 Second Swipe (what happens if the same card is swiped twice?)
What is the second swipe?
When you swipe the same RFID a second time, what happens? Start the playlist again? Toggle pause/play? Available options are:
- RESTART => Re-start playlist
- SKIPNEXT => Skip to next track
- PAUSE => Toggle pause / play
- PLAY => Resume playback
- NOAUDIOPLAY => Ignore audio playout triggers, only system commands
To figure out what to do is not straight forward (it might be more straight forward than I think, but this is how it is at the moment):
First: assume the best: Setting a VAR to play playlist from start This will be changed in the following checks, if this is the second swipe
PLAYPLAYLIST=yes
Check if the second swipe happened: The same playlist is cued up (“LASTPLAYLIST” == “PLAYLISTNAME”) If so, start figuring out what to do:
- After reboot: play playlist from start, no matter what
- After reboot: playlist length which we get from
MPD
is 0 (zero) - Ignore the following checks, jump straight to the point below where we play the playlist
- After reboot: playlist length which we get from
- “$SECONDSWIPE” == “PAUSE” (AND playlist length >
0 meaning we have actually something played)
- Get
MPD
state (is it actually playing?) - IF state is playing (“play”):
- MPD playing, pausing the player
- ELSE (all other possible states)
- MPD not playing, start playing
- Get
- “$SECONDSWIPE” == “PLAY” (AND playlist length >
0 meaning we have actually something played)
- This option means “resume play”, so we are:
- cancelling the playlist playout further below
PLAYPLAYLIST=no
- give the command to play
playout_controls.sh -c=playerplay
- cancelling the playlist playout further below
- NOTE: cancelling playlist is done, because this script would change the saved position in the playlist
- This option means “resume play”, so we are:
- “$SECONDSWIPE” == “NOAUDIOPLAY”
- this means: don’t change the current playout, ignore the card:
PLAYPLAYLIST=no
- … with one exception: if the playlist has been finished, meaning
MPD
does not know a current songmpc current
returns the current song if available toMPD
- IF
currentSong
does not exist or empty:PLAYPLAYLIST=yes
- this means: don’t change the current playout, ignore the card:
- “$SECONDSWIPE” == “SKIPNEXT”
PLAYPLAYLIST=skipnext
(this will be taken into account below)
- For “RESTART => Re-start playlist” we don’t need to do anything, this is default behaviour
- After reboot: play playlist from start, no matter what
Check if we play the playlist! “$PLAYPLAYLIST” == “yes”
- Save position of the current song:
playout_controls.sh -c=playerstop
- play playlist
- the variable passed on to play is the playlist name -v (NOT the folder name) because (see above) a folder can be played recursively (including subfolders) or flat (only containing files)
playout_controls.sh -c=playlistaddplay -v="${PLAYLISTNAME}" -d="${FOLDER}"
- Save latest playlist name to
settings/Latest_Playlist_Played
- Save position of the current song:
Alternative option: “$PLAYPLAYLIST” == “skipnext”
playout_controls.sh -c=playernext
- (Actually, this could also be added above, I think, as in “$SECONDSWIPE” == “PLAY”)