Files
2018-05-14 09:39:37 +02:00

932 lines
26 KiB
Python
Executable File

#!/usr/bin/env python
#
# Raspberry Pi Internet Radio
# using an HD44780 LCD display
# $Id: radio4.py,v 1.111 2016/08/07 13:33:49 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 socket
import string
import datetime
from time import strftime
import shutil
import atexit
import traceback
import requests
# Class imports
from radio_daemon import Daemon
from radio_class import Radio
from lcd_class import Lcd
from log_class import Log
from rss_class import Rss
from config_class import Configuration # for configuration read (Pecus)
from translate_class import Translate
from display_model import ModelInfo
# 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()
rss = Rss()
config = Configuration() # for configuration read (Pecus)
translate = Translate()
ModelInfo = ModelInfo()
# 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
radio.execCommand("modprobe snd-aloop")
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)
# Display daemon pid on the LCD
message = "Radio pid " + str(os.getpid())
lcd.line2(message)
lcd.line3("Waiting for network")
IPwait = 10 # Wait max 10s. for network
while IPwait > 0:
IPwait = IPwait - 1
ipaddr = exec_cmd('hostname -I')
if ipaddr is "":
time.sleep(1)
else:
IPwait = 0
lcd.line4("IP " + ipaddr)
hostname = exec_cmd('hostname -s')
log.message("IP " + ipaddr, log.INFO)
lcd.line3("Starting MPD")
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")
mpd_version = 'mpd version: ' + exec_cmd('mpd -V | grep Daemon | cut -c21-')
log.message(mpd_version, log.INFO)
lcd.line3(mpd_version)
lcd.line4("GPIO: " + str(GPIO.VERSION) + " cores:"+str(radio.cores))
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 = "m"
elif input_source == radio.PANDORA:
msg = "p"
# sprawdzamy czy minal czas na potwierdzenie z Pandory i jesli tak to zerujemy flage potwierdzenia
if radio.pandora_watchdog_time <= int(time.time()):
radio.setReload(True)
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.line2(msg) # in sleep mode time and date in second line of LCD (Pecus)
display_sleep(lcd,radio)
if config.rss: # RSS in standby only if on in config file (Pecus)
display_rss(lcd,rss)
else:
lcd.line3('')
# 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)
radio.streamingWakeup()
# Toggle line 2 & 3 scrolling
if toggleScrolling:
toggleScrolling = False
else:
toggleScrolling = True
if display_mode == radio.MODE_SLEEP:
if config.rss:
time.sleep(0.1)
else:
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.getDisplayMode() != radio.MODE_SLEEP and radio.getDisplayMode() != radio.MODE_IP:
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
if radio.getDisplayMode() == radio.MODE_IP and not interrupt: # ten manewr umozliwia przerwanie przewijania RSSa i przejscie do ekranu info bez czekania
interrupt = checkState(radio) or radio.getInterrupt()
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)
# 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 display_mode == radio.MODE_SLEEP:
# Send remote code (simulate IR remote key)
udpSend('KEY_WAKEUP')
else:
if radio.muted():
unmuteRadio(lcd,radio)
# Send remote code (simulate IR remote key)
udpSend('KEY_OK')
elif switch == up_switch:
log.message("UP switch display_mode " + str(display_mode), log.DEBUG)
if display_mode != radio.MODE_SLEEP:
if display_mode == radio.MODE_TIME:
# Send remote code (simulate IR remote key)
udpSend('KEY_CHANNELUP')
else:
# Send remote code (simulate IR remote key)
udpSend('KEY_UP')
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 display_mode == radio.MODE_TIME:
# Send remote code (simulate IR remote key)
udpSend('KEY_CHANNELDOWN')
else:
# Send remote code (simulate IR remote key)
udpSend('KEY_DOWN')
else:
DisplayExitMessage(lcd)
elif switch == left_switch:
log.message("LEFT switch" ,log.DEBUG)
if display_mode != radio.MODE_SLEEP:
if display_mode == radio.MODE_TIME:
if GPIO.input(right_switch):
# Send remote code (simulate IR remote key)
udpSend('KEY_MUTE')
else:
# Send remote code (simulate IR remote key)
udpSend('KEY_VOLUMEDOWN')
else:
# Send remote code (simulate IR remote key)
udpSend('KEY_LEFT')
else:
DisplayExitMessage(lcd)
elif switch == right_switch:
log.message("RIGHT switch" ,log.DEBUG)
if display_mode != radio.MODE_SLEEP:
if display_mode == radio.MODE_TIME:
if GPIO.input(left_switch):
# Send remote code (simulate IR remote key)
udpSend('KEY_MUTE')
else:
# Send remote code (simulate IR remote key)
udpSend('KEY_VOLUMEUP')
else:
# Send remote code (simulate IR remote key)
udpSend('KEY_RIGHT')
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
# 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 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()
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()
streeamname = ''
# 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:
streamname = '[' + station + '] - ' + title
if len(title) < 1:
streamname = '[' + station + ']'
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:
streamname = title
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)
streamname = current_artist + ' - ' + title
# Send metadata to icecast server
if radio.streaming:
if radio.streammetadata != streamname:
radio.streammetadata = streamname
metadataFormatted = translate.toLCD(streamname)
metadataFormatted = metadataFormatted.replace("%","%25")
metadataFormatted = metadataFormatted.replace("&","%26")
metadataFormatted = metadataFormatted.replace("@","%40")
metadataFormatted = metadataFormatted.replace(" ","+") #add "+" instead of " " for icecast2
# metadataFormatted = "Test+characters+x"
try:
requestToSend = ("http://localhost:8001/admin/metadata?mount=/mpd&mode=updinfo&song=") +(metadataFormatted)
r = requests.get((requestToSend), auth=("admin","mympd"))
except:
log.message("Send metadata do icacast server problem - metadata: " + metadataFormatted, log.ERROR)
# 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 = '' # 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)
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(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")
return
# Display search (Station or Track)
def display_search(lcd,radio):
index = radio.getSearchIndex()
source = radio.getSource()
current_id = radio.getCurrentID()
if source == radio.PLAYER:
lcd.line1("Search:" + str(index + 1))
current_artist = radio.getArtistName(index)
lcd.scroll2(current_artist[0:160],interrupt)
lcd.scroll3(radio.getTrackNameByIndex(index),interrupt)
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.line2(" ")
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)
if ipaddr is "":
lcd.line4(" No IP network!")
else:
lcd.line4("IP "+ ipaddr)
lcd.scroll1("Raspberry PI Model " + ModelInfo.model + " rev." + ModelInfo.revision + " (" + str(ModelInfo.ram_mb) + "MB RAM, cores:" + str(radio.cores) + ") manufactured by " + ModelInfo.maker + ". GPIO version " + GPIO.VERSION,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)
radio.streamingSleep()
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
# Send button data to radio program
def udpSend(button):
udpport = config.getRemoteUdpPort()
udphost = config.getRemoteUdpHost()
data = ''
log.message("radio4.udpSend " + button, log.DEBUG)
try:
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
clientsocket.settimeout(3)
clientsocket.sendto(button, (udphost, udpport))
data = clientsocket.recv(100).strip()
except socket.error, e:
err = e.args[0]
if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
log.message("radio4.udpSend no data" + e, log.ERROR)
else:
# Errors such as timeout
log.message("radio4.udpSend " + str(e), log.ERROR)
if len(data) > 0:
log.message("radio4.udpSend server sent: " + data, log.DEBUG)
return data
### 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