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:

  1. If non-existent settings/rfid_trigger_play.conf create one from settings/rfid_trigger_play.conf.sample
  2. 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
  3. 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:

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 of settings/Latest_Folder_Played
  • Fill variable LASTPLAYLIST with content of settings/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)
  • RECURSIVE:
    • Unique name needed: different playlist name for recursive
      • Var PLAYLISTNAME is folder name (FOLDER) + “-%RCRSV%.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}" (see below for explanation of this script)

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):

  1. 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

  2. Check if the second swipe happened: The same playlist is cued up (“LASTPLAYLIST” == “PLAYLISTNAME”) If so, start figuring out what to do:

    1. 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
    2. “$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
    3. “$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
      • NOTE: cancelling playlist is done, because this script would change the saved position in the playlist
    4. “$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 song
        • mpc current returns the current song if available to MPD
        • IF currentSong does not exist or empty: PLAYPLAYLIST=yes
    5. “$SECONDSWIPE” == “SKIPNEXT”
      • PLAYPLAYLIST=skipnext (this will be taken into account below)
    6. For “RESTART => Re-start playlist” we don’t need to do anything, this is default behaviour
  3. 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
  4. Alternative option: “$PLAYPLAYLIST” == “skipnext”

    • playout_controls.sh -c=playernext
    • (Actually, this could also be added above, I think, as in “$SECONDSWIPE” == “PLAY”)