Files
2016-12-01 00:16:11 +01:00

1123 lines
29 KiB
Python
Executable File

#!/usr/bin/env python
#
# Raspberry Pi Internet Radio
# using an HD44780 LCD display
# $Id: radio4.py,v 1.108 2016/01/31 13:34:22 bob Exp $
#
# Author : Bob Rathbone
# Site : http://www.bobrathbone.com
#
# This program uses Music Player Daemon 'mpd'and it's client 'mpc'
# See http://mpd.wikia.com/wiki/Music_Player_Daemon_Wiki
#
# 4 x 20 character LCD version
#
# License: GNU V3, See https://www.gnu.org/copyleft/gpl.html
#
# Disclaimer: Software is provided as is and absolutly no warranties are implied or given.
# The authors shall not be liable for any loss or damage however caused.
#
import os
import RPi.GPIO as GPIO
import signal
import subprocess
import sys
import time
import string
import datetime
from time import strftime
import shutil
import atexit
import traceback
# Class imports
from radio_daemon import Daemon
from radio_class import Radio
from lcd_lcdproc_class import Lcd_lcdproc
from log_class import Log
from rss_class import Rss
from config_class import Configuration # for configuration read (Pecus)
# To use GPIO 14 and 15 (Serial RX/TX)
# Remove references to /dev/ttyAMA0 from /boot/cmdline.txt and /etc/inittab
UP = 0
DOWN = 1
CurrentStationFile = "/var/lib/radiod/current_station"
CurrentTrackFile = "/var/lib/radiod/current_track"
CurrentFile = CurrentStationFile
PlaylistsDirectory = "/var/lib/mpd/playlists/"
log = Log()
radio = Radio()
lcd = Lcd_lcdproc()
rss = Rss()
config = Configuration() # for configuration read (Pecus)
# Signal SIGTERM handler
def signalHandler(signal,frame):
global lcd
global log
radio.execCommand("umount /media > /dev/null 2>&1")
radio.execCommand("umount /share > /dev/null 2>&1")
pid = os.getpid()
log.message("Radio stopped, PID " + str(pid), log.INFO)
lcd.line1(" Radio stopped") # center alignment (Pecus)
lcd.line2("")
lcd.line3("")
lcd.line4("")
lcd.setBright(False) # LCD backlight brightness to low (Pecus)
GPIO.cleanup()
sys.exit(0)
# Daemon class
class MyDaemon(Daemon):
def run(self):
global CurrentFile
GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers
GPIO.setwarnings(False) # Ignore warnings
# Get switches configuration
up_switch = radio.getSwitchGpio("up_switch")
down_switch = radio.getSwitchGpio("down_switch")
left_switch = radio.getSwitchGpio("left_switch")
right_switch = radio.getSwitchGpio("right_switch")
menu_switch = radio.getSwitchGpio("menu_switch")
boardrevision = radio.getBoardRevision()
if boardrevision == 1:
# For rev 1 boards with no inbuilt pull-up/down resistors
# Wire the GPIO inputs to ground via a 10K resistor
GPIO.setup(menu_switch, GPIO.IN)
GPIO.setup(up_switch, GPIO.IN)
GPIO.setup(down_switch, GPIO.IN)
GPIO.setup(left_switch, GPIO.IN)
GPIO.setup(right_switch, GPIO.IN)
else:
# For rev 2 boards with inbuilt pull-up/down resistors
# there is no need to physically wire the 10k resistors
GPIO.setup(menu_switch, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(up_switch, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(down_switch, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(left_switch, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(right_switch, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
# Initialise radio
log.init('radio')
signal.signal(signal.SIGTERM,signalHandler)
progcall = str(sys.argv)
log.message('Radio running pid ' + str(os.getpid()), log.INFO)
log.message("Radio " + progcall + " daemon version " + radio.getVersion(), log.INFO)
log.message("GPIO version " + str(GPIO.VERSION), log.INFO)
lcd.init(boardrevision)
lcd.setWidth(20)
lcd.line1("Radio version " + radio.getVersion())
time.sleep(0.5)
ipaddr = exec_cmd('hostname -I')
hostname = exec_cmd('hostname -s')
log.message("IP " + ipaddr, log.INFO)
# Display daemon pid on the LCD
message = "Radio pid " + str(os.getpid())
lcd.line2(message)
lcd.line3("Starting MPD")
lcd.line4("IP " + ipaddr)
radio.start()
log.message("MPD started", log.INFO)
time.sleep(0.5)
if config.bright: # LCD brightnes to high only if on in config file (Pecus)
lcd.setBright(True) # LCD backlight brightness to high (Pecus)
mpd_version = radio.execMpcCommand("version")
log.message(mpd_version, log.INFO)
lcd.line3(mpd_version)
lcd.line4("GPIO version " + str(GPIO.VERSION))
time.sleep(2.0)
reload(lcd,radio)
radio.play(get_stored_id(CurrentFile))
log.message("Current ID = " + str(radio.getCurrentID()), log.INFO)
lcd.line3("Radio Station " + str(radio.getCurrentID()))
# Set up switch event processing
GPIO.add_event_detect(menu_switch, GPIO.RISING, callback=switch_event, bouncetime=200)
GPIO.add_event_detect(left_switch, GPIO.RISING, callback=switch_event, bouncetime=200)
GPIO.add_event_detect(right_switch, GPIO.RISING, callback=switch_event, bouncetime=200)
GPIO.add_event_detect(up_switch, GPIO.RISING, callback=switch_event, bouncetime=200)
GPIO.add_event_detect(down_switch, GPIO.RISING, callback=switch_event, bouncetime=200)
# Main processing loop
count = 0
toggleScrolling = True # Toggle scrolling between Line 2 and 3
while True:
# See if we have had an interrupt
switch = radio.getSwitch()
if switch > 0:
get_switch_states(lcd,radio,rss)
radio.setSwitch(0)
display_mode = radio.getDisplayMode()
lcd.setScrollSpeed(0.3) # Scroll speed normal
dateFormat = radio.getDateFormat()
todaysdate = strftime(dateFormat)
ipaddr = exec_cmd('hostname -I')
# Shutdown command issued
if display_mode == radio.MODE_SHUTDOWN:
displayShutdown(lcd)
while True:
time.sleep(1)
elif ipaddr is "":
lcd.line3("No IP network")
elif display_mode == radio.MODE_TIME:
if config.bright: # LCD brightnes to high only if on in config file (Pecus)
lcd.setBright(True) # LCD backlight brightness to high (Pecus)
if radio.getReload():
log.message("Reload ", log.DEBUG)
reload(lcd,radio)
radio.setReload(False)
input_source = radio.getSource()
if input_source == radio.RADIO:
msg = "r"
elif input_source == radio.PLAYER:
msg = "o"
elif input_source == radio.PANDORA:
msg = "p"
msg = msg + ' ' + todaysdate # extra space before time (Pecus)
if radio.getStreaming():
msg = msg + ' *'
lcd.line1(msg)
display_current(lcd,radio,toggleScrolling)
elif display_mode == radio.MODE_SEARCH:
display_search(lcd,radio)
elif display_mode == radio.MODE_SOURCE:
display_source_select(lcd,radio)
elif display_mode == radio.MODE_OPTIONS:
display_options(lcd,radio)
elif display_mode == radio.MODE_IP:
displayInfo(lcd,ipaddr,mpd_version)
elif display_mode == radio.MODE_RSS:
msg = todaysdate + ' RSS' # extra RSS mode info (Pecus)
lcd.line1(msg)
input_source = radio.getSource()
current_id = radio.getCurrentID()
if input_source == radio.RADIO or input_source == radio.PANDORA:
station = radio.getRadioStation()
lcd.line2(station)
else:
lcd.line2(radio.getCurrentArtist())
display_rss(lcd,rss)
elif display_mode == radio.MODE_SLEEP:
msg = ' ' + todaysdate # extra 2 spaces before time (Pecus)
#lcd.line1(msg) # (Pecus)
lcd.line2(msg) # in sleep mode time and date in second line of LCD (Pecus)
display_sleep(lcd,radio)
# Timer function
checkTimer(radio)
# Check state (pause or play)
checkState(radio)
# Alarm wakeup function
if display_mode == radio.MODE_SLEEP and radio.alarmFired():
log.message("Alarm fired", log.INFO)
radio.unmute()
displayWakeUpMessage(lcd)
radio.setDisplayMode(radio.MODE_TIME)
# Toggle line 2 & 3 scrolling
if toggleScrolling:
toggleScrolling = False
else:
toggleScrolling = True
if display_mode == radio.MODE_SLEEP:
time.sleep(1)
else:
time.sleep(0.1)
# End of main processing loop
def status(self):
# Get the pid from the pidfile
try:
pf = file(self.pidfile,'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if not pid:
message = "radiod status: not running"
log.message(message, log.INFO)
print message
else:
message = "radiod running pid " + str(pid)
log.message(message, log.INFO)
print message
return
# End of class overrides
# Scrolling LCD display interrupt routine
def interrupt():
global lcd
global radio
global rss
interrupt = False
switch = radio.getSwitch()
if switch > 0:
interrupt = get_switch_states(lcd,radio,rss)
radio.setSwitch(0)
# Rapid display of track play status
if radio.getSource() == radio.PLAYER or radio.getSource() == radio.PANDORA:
if radio.volumeChanged():
displayVolume(lcd,radio)
time.sleep(0.5)
else:
displayProgress(lcd,radio)
elif (radio.getTimer() and not interrupt) or radio.volumeChanged():
displayVolume(lcd,radio)
interrupt = checkTimer(radio)
if not interrupt:
interrupt = checkState(radio) or radio.getInterrupt()
# sprawdzamy czy minal czas na potwierdzenie z Pandory i jesli tak to zerujemy flage potwierdzenia
if radio.pandora_decision_time <= int(time.time()):
radio.pandora_decision = radio.OK
return interrupt
def no_interrupt():
return False
# Call back routine called by switch events
def switch_event(switch):
global radio
radio.setSwitch(switch)
return
# Check switch states
def get_switch_states(lcd,radio,rss):
interrupt = False # Interrupt display
switch = radio.getSwitch()
display_mode = radio.getDisplayMode()
input_source = radio.getSource()
option = radio.getOption()
# Get switches configuration
up_switch = radio.getSwitchGpio("up_switch")
down_switch = radio.getSwitchGpio("down_switch")
left_switch = radio.getSwitchGpio("left_switch")
right_switch = radio.getSwitchGpio("right_switch")
menu_switch = radio.getSwitchGpio("menu_switch")
if switch == menu_switch:
log.message("MENU switch", log.DEBUG)
if radio.muted():
unmuteRadio(lcd,radio)
display_mode = display_mode + 1
# Skip RSS mode if not available
if display_mode == radio.MODE_RSS:
if rss.isAvailable() and not radio.optionChanged():
lcd.line3("Getting RSS feed")
else:
display_mode = display_mode + 1
if display_mode > radio.mode_last:
boardrevision = radio.getBoardRevision()
lcd.init(boardrevision) # Recover corrupted display
display_mode = radio.MODE_TIME
radio.setDisplayMode(display_mode)
log.message("New mode " + radio.getDisplayModeString()+
"(" + str(display_mode) + ")", log.DEBUG)
# Shutdown if menu button held for > 3 seconds
MenuSwitch = GPIO.input(menu_switch)
count = 15
while MenuSwitch:
time.sleep(0.2)
MenuSwitch = GPIO.input(menu_switch)
count = count - 1
if count < 0:
log.message("Shutdown", log.DEBUG)
MenuSwitch = False
radio.setDisplayMode(radio.MODE_SHUTDOWN)
# if radio.getUpdateLibrary(): # It does not work so... out (Pecus)
# update_library(lcd,radio) # (Pecus)
# radio.setDisplayMode(radio.MODE_TIME) # (Pecys)
#
# elif radio.getReload(): # (Pecus)
if radio.getReload(): # (Pecus)
source = radio.getSource()
log.message("Reload " + str(source), log.INFO)
lcd.line2("Reloading ")
reload(lcd,radio)
radio.setReload(False)
radio.setDisplayMode(radio.MODE_TIME)
elif radio.optionChanged():
log.message("optionChanged", log.DEBUG)
if radio.alarmActive() and not radio.getTimer() \
and (option == radio.ALARMSETHOURS or option == radio.ALARMSETMINS):
radio.setDisplayMode(radio.MODE_SLEEP)
radio.mute()
else:
radio.setDisplayMode(radio.MODE_TIME)
radio.optionChangedFalse()
elif radio.loadNew():
log.message("Load new search=" + str(radio.getSearchIndex()), log.DEBUG)
radio.playNew(radio.getSearchIndex())
radio.setDisplayMode(radio.MODE_TIME)
interrupt = True
elif switch == up_switch:
log.message("UP switch display_mode " + str(display_mode), log.DEBUG)
if display_mode != radio.MODE_SLEEP:
if radio.muted():
unmuteRadio(lcd,radio)
if display_mode == radio.MODE_SOURCE:
radio.toggleSource()
#radio.setReload(True)
elif display_mode == radio.MODE_SEARCH:
wait = 0.5
while GPIO.input(up_switch):
radio.getNext(UP)
display_search(lcd,radio)
time.sleep(wait)
wait = 0.1
elif display_mode == radio.MODE_OPTIONS:
cycle_options(radio,UP)
else:
radio.channelUp()
interrupt = True
else:
DisplayExitMessage(lcd)
elif switch == down_switch:
log.message("DOWN switch display_mode " + str(display_mode), log.DEBUG)
if display_mode != radio.MODE_SLEEP:
if radio.muted():
unmuteRadio(lcd,radio)
if display_mode == radio.MODE_SOURCE:
radio.toggleSource()
#radio.setReload(True)
elif display_mode == radio.MODE_SEARCH:
wait = 0.5
while GPIO.input(down_switch):
radio.getNext(DOWN)
display_search(lcd,radio)
time.sleep(wait)
wait = 0.1
elif display_mode == radio.MODE_OPTIONS:
cycle_options(radio,DOWN)
else:
radio.channelDown()
interrupt = True
else:
DisplayExitMessage(lcd)
elif switch == left_switch:
log.message("LEFT switch" ,log.DEBUG)
if display_mode != radio.MODE_SLEEP:
if display_mode == radio.MODE_OPTIONS:
toggle_option(radio,lcd,DOWN)
interrupt = True
elif display_mode == radio.MODE_SEARCH and input_source == radio.PLAYER:
wait = 0.5
while GPIO.input(left_switch):
radio.findNextArtist(DOWN)
display_search(lcd,radio)
time.sleep(wait)
wait = 0.1
interrupt = True
elif display_mode == radio.MODE_OPTIONS:
interrupt = True
else:
# Decrease volume
volChange = True
while volChange:
# Mute function (Both buttons depressed)
if GPIO.input(right_switch):
radio.mute()
if radio.alarmActive():
radio.setDisplayMode(radio.MODE_SLEEP)
interrupt = True
displayVolume(lcd,radio)
time.sleep(2)
volChange = False
interrupt = True
else:
volume = radio.decreaseVolume()
displayVolume(lcd,radio)
volChange = GPIO.input(left_switch)
if volume <= 0:
volChange = False
time.sleep(0.1)
else:
DisplayExitMessage(lcd)
elif switch == right_switch:
log.message("RIGHT switch" ,log.DEBUG)
if display_mode != radio.MODE_SLEEP:
if display_mode == radio.MODE_OPTIONS:
toggle_option(radio,lcd,UP)
interrupt = True
elif display_mode == radio.MODE_SEARCH and input_source == radio.PLAYER:
wait = 0.5
while GPIO.input(right_switch):
radio.findNextArtist(UP)
display_search(lcd,radio)
time.sleep(wait)
wait = 0.1
interrupt = True
elif display_mode == radio.MODE_OPTIONS:
interrupt = True
else:
# Increase volume
volChange = True
while volChange:
# Mute function (Both buttons depressed)
if GPIO.input(left_switch):
radio.mute()
if radio.alarmActive():
radio.setDisplayMode(radio.MODE_SLEEP)
interrupt = True
displayVolume(lcd,radio)
time.sleep(2)
volChange = False
interrupt = True
else:
volume = radio.increaseVolume()
displayVolume(lcd,radio)
volChange = GPIO.input(right_switch)
if volume >= 100:
volChange = False
time.sleep(0.1)
else:
DisplayExitMessage(lcd)
return interrupt
# Sleep exit message
def DisplayExitMessage(lcd):
lcd.line3("Press menu button to")
lcd.line4("exit sleep mode")
time.sleep(1)
lcd.line3("")
lcd.line4("")
return
# Cycle through the options
# Only display reload the library if in PLAYER mode
def cycle_options(radio,direction):
option = radio.getOption()
log.message("cycle_options direction:" + str(direction)
+ " option: " + str(option), log.DEBUG)
if direction == UP:
option += 1
else:
option -= 1
# Don't display reload if not player mode
source = radio.getSource()
if option == radio.RELOADLIB:
if source != radio.PLAYER:
if direction == UP:
option = option+1
else:
option = option-1
if option == radio.STREAMING:
if not radio.streamingAvailable():
if direction == UP:
option = option+1
else:
option = option-1
if option > radio.OPTION_LAST:
option = radio.RANDOM
elif option < 0:
if source == radio.PLAYER:
option = radio.OPTION_LAST
else:
option = radio.OPTION_LAST-1
radio.setOption(option)
radio.optionChangedTrue()
return
# Toggle random mode (Certain options not allowed if RADIO)
def toggle_option(radio,lcd,direction):
option = radio.getOption()
log.message("toggle_option option="+ str(option), log.DEBUG)
if option == radio.RANDOM:
if radio.getRandom():
radio.randomOff()
else:
radio.randomOn()
elif option == radio.CONSUME:
if radio.getSource() == radio.PLAYER:
if radio.getConsume():
radio.consumeOff()
else:
radio.consumeOn()
else:
lcd.line2("Not allowed")
time.sleep(2)
elif option == radio.REPEAT:
if radio.getRepeat():
radio.repeatOff()
else:
radio.repeatOn()
elif option == radio.TIMER:
TimerChange = True
# Buttons held in
if radio.getTimer():
while TimerChange:
if direction == UP:
radio.incrementTimer(1)
lcd.line2("Timer " + radio.getTimerString())
TimerChange = GPIO.input(right_switch)
else:
radio.decrementTimer(1)
lcd.line2("Timer " + radio.getTimerString())
TimerChange = GPIO.input(left_switch)
time.sleep(0.1)
else:
radio.timerOn()
elif option == radio.ALARM:
log.message("toggle_option radio.ALARM", log.DEBUG)
radio.alarmCycle(direction)
elif option == radio.ALARMSETHOURS or option == radio.ALARMSETMINS:
# Buttons held in
AlarmChange = True
twait = 0.4
value = 1
unit = " mins"
if option == radio.ALARMSETHOURS:
value = 60
unit = " hours"
while AlarmChange:
if direction == UP:
radio.incrementAlarm(value)
lcd.line2("Alarm " + radio.getAlarmTime() + unit)
time.sleep(twait)
AlarmChange = GPIO.input(right_switch)
else:
radio.decrementAlarm(value)
lcd.line2("Alarm " + radio.getAlarmTime() + unit)
time.sleep(twait)
AlarmChange = GPIO.input(left_switch)
twait = 0.1
elif option == radio.STREAMING:
radio.toggleStreaming()
elif option == radio.RELOADLIB:
if radio.getUpdateLibrary():
radio.setUpdateLibOff()
else:
radio.setUpdateLibOn()
radio.optionChangedTrue()
return
# Update music library
def update_library(lcd,radio):
log.message("Updating library", log.INFO)
lcd.line1("Updating library")
lcd.line2("Please wait")
radio.updateLibrary()
return
# Reload if new source selected (RADIO or PLAYER)
def reload(lcd,radio):
lcd.line1("Loading:")
lcd.line3("Wait...")
lcd.line4("")
source = radio.getSource()
if source == radio.RADIO:
lcd.line2("Radio Stations")
dirList=os.listdir(PlaylistsDirectory)
for fname in dirList:
if os.path.isfile(fname):
continue
log.message("Loading " + fname, log.DEBUG)
lcd.line2(fname)
time.sleep(0.1)
radio.loadStations()
elif source == radio.PLAYER:
lcd.line2("Media library")
radio.loadMedia()
current = radio.execMpcCommand("current")
# if len(current) < 1: # (Pecus)
if len(current) < 1 or radio.getUpdateLibrary() or config.media_update: # If uptade flags set, update library on source switch (Pecus)
update_library(lcd,radio)
elif source == radio.PANDORA:
lcd.line2("Pandora radio")
radio.loadPandora()
#current = radio.execMpcCommand("current")
return
# Display the RSS feed
def display_rss(lcd,rss):
rss_line = rss.getFeed()
lcd.setScrollSpeed(0.2) # Scroll RSS a bit faster
lcd.scroll3(rss_line,interrupt)
return
# Display the currently playing station or track
def display_current(lcd,radio,toggleScrolling):
station = radio.getRadioStation()
title = radio.getCurrentTitle()
current_id = radio.getCurrentID()
source = radio.getSource()
# Display progress of the currently playing track
if radio.muted():
displayVolume(lcd,radio)
else:
if source == radio.PLAYER or source == radio.PANDORA:
displayProgress(lcd,radio)
else:
displayVolume(lcd,radio)
if source == radio.RADIO:
if len(title) < 1:
bitrate = radio.getBitRate()
if bitrate > 0:
title = "Station " + str(current_id) + ' ' + str(bitrate) +'k'
if current_id <= 0:
lcd.line2("No stations found")
else:
if toggleScrolling:
lcd.line3(title)
lcd.scroll2(station, interrupt)
else:
lcd.line2(station)
elif source == radio.PANDORA:
if toggleScrolling:
lcd.line3(title)
lcd.scroll2(station, interrupt)
else:
lcd.line2(station)
else:
index = radio.getSearchIndex()
playlist = radio.getPlayList()
current_artist = radio.getCurrentArtist()
lcd.line2(current_artist)
# Display stream error
if radio.gotError():
errorStr = radio.getErrorString()
lcd.scroll3(errorStr,interrupt)
radio.clearError()
else:
leng = len(title)
if leng > 20:
if toggleScrolling:
lcd.line3(title)
else:
lcd.scroll3(title[0:160],interrupt)
else:
lcd.line3(title)
return
# Display if in sleep
def display_sleep(lcd,radio):
#message = 'Sleep mode' # (Pecus)
message = '' # I don't like text "Sleep mode" in sleep mode (Pecus)
lcd.setBright(False) # LCD backlight brightness to low (Pecus)
lcd.line1('') # time is now in second line, therefore we clean first line (Pecus)
if radio.alarmActive():
message = "Alarm " + radio.getAlarmTime()
lcd.line4(message)
#lcd.line2('') # (Pecus)
#lcd.line3('') # in line 3 RSS (Pecus)
if config.rss: # RSS in standby only if on in config file (Pecus)
rss_line = rss.getFeed() # (Pecus)
lcd.setScrollSpeed(0.2) # Scroll RSS a bit faster # (Pecus)
lcd.scroll3(rss_line,interrupt) # (Pecus)
else: # (Pecus)
lcd.line3('') # (Pecus)
return
# Get the last ID stored in /var/lib/radiod
def get_stored_id(current_file):
current_id = 5
if os.path.isfile(current_file):
# current_id = int(exec_cmd("cat " + current_file) ) # (Pecus)
current_id = int(readFromFile(current_file) ) # (Pecus)
return current_id
# Execute system command
def exec_cmd(cmd):
p = os.popen(cmd)
result = p.readline().rstrip('\n')
return result
# Read text line from file (Pecus)
def readFromFile(fname): # (Pecus)
file = open(fname, "r") # (Pecus)
text = file.readline() # (Pecus)
file.close() # (Pecus)
return text # (Pecus)
# Get list of tracks or stations
def get_mpc_list(cmd):
list = []
line = ""
p = os.popen("/usr/bin/mpc " + cmd)
while True:
line = p.readline().strip('\n')
if line.__len__() < 1:
break
list.append(line)
return list
# Source selection display
def display_source_select(lcd,radio):
lcd.line1("Input Source:")
source = radio.getSource()
if source == radio.RADIO:
lcd.line2("Internet Radio")
elif source == radio.PLAYER:
lcd.line2("Music Player")
elif source == radio.PANDORA:
lcd.line2("Pandora Radio")
# progress = radio.getProgress()
# if radio.muted():
# lcd.line4('Sound muted')
# else:
# # Is the radio actually playing ?
# if progress.find('/0:00') > 0:
# lcd.line4("Volume " + str(radio.getVolume()))
# else:
# lcd.line4(radio.getProgress())
# lcd.line4("") # bo sie zmieniaja wartosci w zaleznosci od wybieranego zrodla
return
# Display search (Station or Track)
def display_search(lcd,radio):
index = radio.getSearchIndex()
source = radio.getSource()
current_id = radio.getCurrentID()
#lcd.line1("Search:" + str(index + 1))
if source == radio.PLAYER:
current_artist = radio.getArtistName(index)
lcd.line2(current_artist[0:19])
lcd.line3(radio.getTrackNameByIndex(index))
lcd.line4(radio.getProgress())
elif source == radio.PANDORA:
lcd.line1("Search:" + str(radio.pandora_search_index + 1))
current_station = radio.getPandoraStationName(radio.pandora_search_index)
lcd.line3("Current station:" + str(radio.current_pandora_id))
lcd.scroll2(current_station[0:160],interrupt)
lcd.line4(radio.getProgress())
pass
else:
lcd.line1("Search:" + str(index + 1))
current_station = radio.getStationName(index)
lcd.line3("Current station:" + str(radio.getCurrentID()))
lcd.scroll2(current_station[0:160],interrupt)
return
# Unmute radio and get stored volume
def unmuteRadio(lcd,radio):
radio.unmute()
volume = radio.getVolume()
lcd.line4("Volume " + str(VolumeToDisplay(volume)))
radio.setDisplayMode(radio.MODE_TIME)
return
# Options menu
def display_options(lcd,radio):
option = radio.getOption()
if option != radio.TIMER and option != radio.ALARM \
and option != radio.ALARMSETHOURS and option != radio.ALARMSETMINS :
lcd.line1("Menu selection:")
if option == radio.RANDOM:
if radio.getRandom():
lcd.line2("Random on")
else:
lcd.line2("Random off")
elif option == radio.CONSUME:
if radio.getConsume():
lcd.line2("Consume on")
else:
lcd.line2("Consume off")
elif option == radio.REPEAT:
if radio.getRepeat():
lcd.line2("Repeat on")
else:
lcd.line2("Repeat off")
elif option == radio.TIMER:
lcd.line1("Set timer function:")
if radio.getTimer():
lcd.line2("Timer " + radio.getTimerString())
else:
lcd.line2("Timer off")
elif option == radio.ALARM:
alarmString = "off"
lcd.line1("Set alarm function:")
alarmType = radio.getAlarmType()
if alarmType == radio.ALARM_ON:
alarmString = "on"
elif alarmType == radio.ALARM_REPEAT:
alarmString = "repeat"
elif alarmType == radio.ALARM_WEEKDAYS:
alarmString = "weekdays only"
lcd.line2("Alarm " + alarmString)
elif option == radio.ALARMSETHOURS:
lcd.line1("Set alarm time:")
lcd.line2("Alarm " + radio.getAlarmTime() + " hours")
elif option == radio.ALARMSETMINS:
lcd.line1("Set alarm time:")
lcd.line2("Alarm " + radio.getAlarmTime() + " mins")
elif option == radio.STREAMING:
if radio.getStreaming():
lcd.line2("Streaming on")
else:
lcd.line2("Streaming off")
elif option == radio.RELOADLIB:
if radio.getUpdateLibrary():
lcd.line2("Update playlist: Yes")
else:
lcd.line2("Update playlist: No")
if radio.getSource() == radio.PLAYER or radio.getSource() == radio.PANDORA:
lcd.line4(radio.getProgress())
return
# Display volume and timer
def displayVolume(lcd,radio):
if radio.muted():
msg = "Sound muted"
else:
msg = "Volume " + str(VolumeToDisplay(radio.getVolume()))
if radio.getTimer():
msg = msg + " " + radio.getTimerString()
if radio.alarmActive():
msg = msg + ' ' + radio.getAlarmTime()
lcd.line4(msg)
return
# Display progress and timer
def displayProgress(lcd,radio):
if radio.muted():
msg = "Sound muted"
else:
msg = str(radio.getProgress())
if radio.getTimer():
msg = msg + " " + radio.getTimerString()
if radio.alarmActive():
msg = msg + ' ' + radio.getAlarmTime()
if radio.getSource() == radio.PANDORA and radio.pandora_decision != radio.OK:
# jesli czekamy na potwierdzenie decyzji w Pandorze to zamiast progresu wyswietlamy rodzaj decyzji
if radio.pandora_decision == radio.UP:
msg = "Like this track. OK?"
elif radio.pandora_decision == radio.DOWN:
msg = "Ban this track. OK?"
elif radio.pandora_decision == radio.LEFT:
msg = "Tired this track.OK?"
lcd.line4(msg)
return
# Display wake up message
def displayWakeUpMessage(lcd):
message = 'Good day'
t = datetime.datetime.now()
if t.hour >= 0 and t.hour < 12:
message = 'Good morning'
if t.hour >= 12 and t.hour < 18:
message = 'Good afternoon'
if t.hour >= 16 and t.hour <= 23:
message = 'Good evening'
lcd.line4(message)
time.sleep(3)
return
def displayShutdown(lcd):
lcd.setBright(False) # LCD backlight brightness to low (Pecus)
lcd.line1("Stopping radio")
radio.execCommand("service mpd stop")
radio.pandora_stop()
lcd.line3(" ")
lcd.line4(" ")
radio.execCommand("shutdown -h now")
lcd.line2("Shutdown issued")
time.sleep(3)
lcd.line1("Radio stopped")
lcd.line2("Power off radio")
return
def displayInfo(lcd,ipaddr,mpd_version):
lcd.line2("Radio version " + radio.getVersion())
lcd.line3(mpd_version)
lcd.line4("GPIO version " + GPIO.VERSION)
if ipaddr is "":
lcd.line1("No IP network")
else:
lcd.scroll1("IP "+ ipaddr,interrupt)
return
def VolumeToDisplay(volume):
volume = (volume - config.getVolumeMin()) * 100
tym = (config.getVolumeMax() - config.getVolumeMin())
volume = volume / tym
return volume
# Check Timer fired
def checkTimer(radio):
interrupt = False
if radio.fireTimer():
log.message("Timer fired", log.INFO)
radio.mute()
if radio.getSource() == radio.PANDORA: # Jesli gra pandora to nie pauzujemy (mutujemy) tylko stopujemy
radio.pandora_stop()
radio.setDisplayMode(radio.MODE_SLEEP)
interrupt = True
return interrupt
# Check state (pause or play)
# If external client such as mpc or MPDroid issue a pause or play command
# Returns paused True if paused
def checkState(radio):
paused = False
display_mode = radio.getDisplayMode()
state = radio.getState()
radio.getVolume()
if state == 'pause':
paused = True
if not radio.muted():
if radio.alarmActive() and not radio.getTimer():
radio.setDisplayMode(radio.MODE_SLEEP)
radio.mute()
elif state == 'play':
if radio.muted():
unmuteRadio(lcd,radio)
radio.setDisplayMode(radio.MODE_TIME)
return paused
### Main routine ###
if __name__ == "__main__":
daemon = MyDaemon('/var/run/radiod.pid')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
os.system("service mpd stop")
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
elif 'status' == sys.argv[1]:
daemon.status()
elif 'nodaemon' == sys.argv[1]:
daemon.nodaemon()
elif 'version' == sys.argv[1]:
print "Version " + radio.getVersion()
else:
print "Unknown command: " + sys.argv[1]
sys.exit(2)
sys.exit(0)
else:
print "usage: %s start|stop|restart|status|version|nodaemon" % sys.argv[0]
sys.exit(2)
# End of script