Using an iMon Front Panel with MPD
The Soundgraph iMon panel has buttons for play, next, volume, etc and a 16 character by two line VFD.
Display
Install Components for the Display
To make use of the display with MPD as part of a music playing appliance we need to install LCDproc which is a daemon for driving displays:
sudo apt-get install LCDproc
We will also be using several python packages to drive information from MPD to LCDproc. Install the python-mpd package:
sudo apt-get install python-mpd
Install the lcdproc and mpdlcd packages from PIP
sudo pip install lcdproc mpdlcd
Configure the Display
By default LCDproc loads a configuration from /etc/LCDd.conf. Create a configuration file:
sudo nano /etc/LCDd.conf
and make it something like the following:
# LCDd.conf -- configuration file for the LCDproc server daemon LCDd # # This file contains the configuration for the LCDd server. # # The format is ini-file-like. It is divided into sections that start at # markers that look like [section]. Comments are all line-based comments, # and are lines that start with '#' or ';'. # # The server has a 'central' section named [server]. For the menu there is # a section called [menu]. Further each driver has a section which # defines how the driver acts. # # The drivers are activated by specifying them in a driver= line in the # server section, like: # # Driver=curses # # This tells LCDd to use the curses driver. # The first driver that is loaded and is capable of output defines the # size of the display. The default driver to use is curses. [server] # Soundgraph/Silverstone VFD Driver=imon DriverPath=/usr/lib/arm-linux-gnueabihf/lcdproc/ # Tells the driver to bind to the given interface # Bind=127.0.0.1 # Listen on this specified port; defaults to 13666. # Port=13666 # If yes, the the serverscreen will be rotated as a usual info screen. If no, # it will be a background screen, only visible when no other screens are # active. The special value 'blank' is similar to no, but only a blank screen # is displayed. [default: on; legal: on, off, blank] ServerScreen=no # Hello message: each entry represents a display line; default: builtin Hello=" Welcome to " Hello=" MoodeAudio " # GoodBye message: each entry represents a display line; default: builtin GoodBye="Goodbye " GoodBye="" ReportToSyslog=yes [imon] # Character map to to map ISO-8859-1 to the displays character set. # [default: none; legal: none, hd44780_euro, upd16314, hd44780_koi8_r, # hd44780_cp1251, hd44780_8859_5 ] (upd16314, hd44780_koi8_r, # hd44780_cp1251, hd44780_8859_5 are possible if compiled with additional # charmaps) CharMap=none # select the device to use Device=/dev/lcd0 # display dimensions Size=16x2
You will need to restart LCDproc when making changes. This can be done using:
sudo service LCDd restart
mpdlcd also uses a configuration file which by default is /etc/mpdlcd.conf. Create a configuration file:
sudo nano /etc/mpdlcd.conf
and enter the following:
[display] # MPD data refresh rate refresh = 0.5 # LCDd screen name for MPDlcd lcdproc_screen = MPD # When to enable backlight: # - always: always on (default) # - never: never on # - play: when playing # - playpause: when playing or in pause backlight_on = play # Settings for changing the screen priority when music is playing or not priority_playing = foreground priority_not_playing = background [patterns] # List your patterns here # You can use line continuations to simulate line breaks. pattern1 = {state} {song format="%(artist)s - %(title)s"} {elapsed} pattern2 = {song format="%(artist)s",speed=4} {elapsed} {song format="%(title)s",speed=2} {state} pattern3 = {song format="%(artist)s",speed=4} {song format="%(album)s - %(title)s",speed=2} {state} {elapsed} / {total} pattern4 = {song format="%(artist)s",speed=4} {song format="%(album)s",speed=4} {song format="%(title)s",speed=2} {elapsed} {state} {remaining} [connections] # MPD server mpd = localhost:6600 # LCDd server lcdproc = localhost:13666 [logging] # Log level - debug, info, warning, error loglevel = info # Enable syslog syslog = 1 # Log to the 'daemon' facility syslog_facility = daemon # vim:set ft=dosini et ts=4:
Lastly to make mpdlcd start automatically whenever the system restarts we need to create an init script for it:
sudo nano /etc/init.d/mpdlcd
and enter the following:
#!/bin/sh - # # mpdlcd initscript for mpdlcd # by Stefaan Verfaillie # ### BEGIN INIT INFO # Provides: mpdlcd # Required-Start: $syslog $LCDd $mpd # Required-Stop: $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: MPD client for lcdproc # Description: Display MPD status ### END INIT INFO # # # LCDPROC_SERVER=${LCDPROC_SERVER:-} MPD_SERVER=${MPD_SERVER:-} LOGLEVEL=${LOGLEVEL:-info} SYSLOG_FACILITY=${SYSLOG_FACILITY:-daemon} PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/local/bin/mpdlcd PIDFILE=/var/run/mpdlcd.pid NAME="mpdlcd" DESC="mpdlcd" DAEMON_OPTS="--lcdproc=\"${LCDPROC_SERVER}\" --mpd=\"${MPD_SERVER}\" --loglevel=\"${LOGLEVEL}\" --syslog" DAEMON_OPTS="--loglevel=${LOGLEVEL} --syslog" test -x $DAEMON || (echo "$DAEMON does not exist" && exit 0) set -e case "$1" in start) echo -n "Starting ${DESC}: " start-stop-daemon --start --background --quiet --pidfile=$PIDFILE -b --make-pidfile --exec ${DAEMON} -- ${DAEMON_OPTS} echo "${NAME}." ;; stop) echo -n "Stopping $DESC: " start-stop-daemon --stop --oknodo --pidfile=${PIDFILE} echo "$NAME." ;; restart|force-reload) echo -n "Restarting $DESC: " $0 stop sleep 1 $0 start ;; *) N=/etc/init.d/$NAME # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 echo "Usage: $N {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit 0
Note the “$LCDd $mpd” on the line “# Required-Start: “. This indicates that this service is dependent on the mpd and LCDproc services.
Make the script executable:
sudo chmod +x /etc/init.d/mpdlcd
Enable the service:
sudo systemctl enable mpdlcd.service
More information about mpdlcd can be found here.
Using the iMon Buttons
Having got the kernel module to correctly detect the iMon buttons, we will use Python to capture button presses and control MPD via the command line client, mpc.
Create our script:
nano mpdkeys.py
and add:
#!/usr/bin/python from evdev import InputDevice, list_devices import os import subprocess # set this to the string name of the device DEVICE_NAME = "iMON Panel, Knob and Mouse(15c2:ffdc)" # functions to interact with the mpc CLI client def MPD_stop(): subprocess.Popen("mpc stop", shell=True) def MPD_playpause(): subprocess.Popen("mpc toggle", shell=True) def MPD_next(): subprocess.Popen("mpc next", shell=True) def MPD_prev(): subprocess.Popen("mpc prev", shell=True) def MPD_volumeup(): subprocess.Popen("mpc volume +5", shell=True) def MPD_volumedown(): subprocess.Popen("mpc volume -5", shell=True) def SYS_halt(): os.system("halt") # function to keycode binding fun_tbl = { 128 : MPD_stop, # KEY_STOP 164 : MPD_playpause, # KEY_PLAYPAUSE 407 : MPD_next, # KEY_NEXT 412 : MPD_prev, # KEY_PREVIOUS 115 : MPD_volumeup, # KEY_VOLUMEUP 114 : MPD_volumedown,# KEY_VOLUMEDOWN 113 : MPD_playpause, # KEY_MUTE } # listen for events for dev in [ InputDevice(fn) for fn in list_devices()]: print dev.name if dev.name == DEVICE_NAME: for event in dev.read_loop(): print event.value if event.value == 1: try: fun_tbl[event.code]() except KeyError: print "Action for %d code is not defined" % (event.code)
Make it executable:
chmod +x ./mpdkeys.py
Test it:
./mpdkeys.py
Press any key on the iMon panel and the corresponding function should be called. If any button is not mapped then you will see a message in the console.
When it is working correctly copy it to a good place for user created scripts, eg:
sudo cp mpdkeys.py /usr/local/bin
To make the script run automatically when the system boots, edit the rc.local file:
sudo nano /etc/rc.local
and add the following right before the line at the end of the file that contains “exit 0”:
/usr/local/bin/mpdkeys.py > /dev/null 2>&1
References
Using Python with keyboard input: http://morethanuser.blogspot.com/2015/10/python-banana-pi-ir-event-handler.html