Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*~
*.pyc
5 changes: 5 additions & 0 deletions SnakeberryService/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

.PHONY: clean

clean:
@rm -f *.pyc
18 changes: 18 additions & 0 deletions SnakeberryService/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
This directory contains the Snakeberry Service. It is written in Python using
[Tornado web server](http://www.tornadoweb.org/).

## Development

The Snakeberry Service requires Python package `tornado`. To install, run

pip tornadoweb

if familiar with the Python package management system, or

sudo apt-get install python-tornado

to on a Debian based Linux distribution. To start the service, call it as

python snakeberry.py

and locate your browser to <http://localhost:8888>.
22 changes: 12 additions & 10 deletions SnakeberryService/audioSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,48 @@
from common import *

#Webservice requesthandler to set system volume on raspberry pi as root
#Author: Bruno Hautzenberger
#Author: Bruno Hautzenberger
class SetVolume(tornado.web.RequestHandler):
def get(self,volume):
rObject = None
errNum = errNumOk
errMsg = errMsgOk

try:
subprocess.call(['sudo', 'amixer', 'set', 'PCM', '--', volume]) #ROOT CALL
#subprocess.call(['amixer', 'cset', 'numid=3', '--', volume]) #USER CALL
except Exception, err:
errMsg = str(err)
errNum = errNumSetVolumeFailed

self.write(SnakeberryJSON().encode(Response(errNum, errMsg, rObject)))
self.set_header('Content-Type','application/json')

#Webservice requesthandler to retrieve system volume from raspberry pi as root
#Author: Bruno Hautzenberger
#Author: Bruno Hautzenberger
class GetVolume(tornado.web.RequestHandler):
def get(self):
rObject = None
errNum = errNumOk
errMsg = errMsgOk

try:
p = subprocess.Popen(['sudo', 'amixer'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
volume = ""
while(True):
retcode = p.poll() #returns None while subprocess is running
line = p.stdout.readline()

if(line.find("Mono") != -1):
volume = line.split()[2]

if(retcode is not None):
break

rObject = int(volume)
except Exception, err:
errMsg = str(err)
errNum = errNumGetVolumeFailed

self.write(SnakeberryJSON().encode(Response(errNum, errMsg, rObject)))

self.write(SnakeberryJSON().encode(Response(errNum, errMsg, rObject)))
self.set_header('Content-Type','application/json')
4 changes: 0 additions & 4 deletions SnakeberryService/radio.csv~

This file was deleted.

47 changes: 27 additions & 20 deletions SnakeberryService/radio.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,59 @@
from common import *
from mplayerInterface import *

base_dir = os.path.dirname(__file__) # should better be relative to config file

#Representing a radio station
#Author: Bruno Hautzenberger
class Radio:
def __init__(self, radioId, displayName, streamUrl):
self.RadioId = radioId
self.DisplayName = displayName
self.StreamUrl = streamUrl

#Representing a list of radio stations
#Author: Bruno Hautzenberger
#Author: Bruno Hautzenberger
class Radios:
def __init__(self):
self.Radios = []
self.loadRadios()

def loadRadios(self):
with open('/home/pi/snakeberry/radio.csv', 'rb') as csvfile:

def loadRadios(self):
filename = os.path.join(base_dir,'radio.csv')
with open(filename, 'rb') as csvfile:
radioreader = csv.reader(csvfile, delimiter=';', quotechar='\"')

count = 0
for row in radioreader:
self.Radios.append(Radio(str(count), row[0], row[1]))
count = count + 1

#Webservice requesthandler to recieve list radio stations
#Author: Bruno Hautzenberger
#Author: Bruno Hautzenberger
class ListRadios(tornado.web.RequestHandler):
def get(self):
rObject = None
errNum = errNumOk
errMsg = errMsgOk

try:
radios = Radios()
rObject = radios
except Exception, err:
errMsg = str(err)
errNum = errNumListRadioStationsFailed

self.write(SnakeberryJSON().encode(Response(errNum, errMsg, rObject)))
self.set_header('Content-Type','application/json')

#Webservice requesthandler to play radio station with given id
#Author: Bruno Hautzenberger
#Author: Bruno Hautzenberger
class PlayRadio(tornado.web.RequestHandler):
def get(self, radioId):
rObject = None
errNum = errNumOk
errMsg = errMsgOk

try:
streamUrl = None
description = None
Expand All @@ -65,7 +69,7 @@ def get(self, radioId):
streamUrl = radio.StreamUrl
description = radio.DisplayName
break

if(streamUrl == None):
errNum = errNumRadioStationIdDoesNotExist
errMsg = errMsgRadioStationIdDoesNotExist
Expand All @@ -75,39 +79,42 @@ def get(self, radioId):
except Exception, err:
errMsg = str(err)
errNum = errNumPlayRadioStationFailed

self.write(SnakeberryJSON().encode(Response(errNum, errMsg, rObject)))
self.set_header('Content-Type','application/json')

#Webservice requesthandler to stop radio
#Author: Bruno Hautzenberger
#Author: Bruno Hautzenberger
class StopRadio(tornado.web.RequestHandler):
def get(self):
rObject = None
errNum = errNumOk
errMsg = errMsgOk

try:
Mplayer.stop()
except Exception, err:
errMsg = str(err)
errNum = errNumStopRadioStationFailed

self.write(SnakeberryJSON().encode(Response(errNum, errMsg, rObject)))
self.set_header('Content-Type','application/json')

#Webservice requesthandler to recieve what information about what the radio is playing
#Author: Bruno Hautzenberger
#Author: Bruno Hautzenberger
class RadioNowPlaying(tornado.web.RequestHandler):
def get(self):
rObject = None
errNum = errNumOk
errMsg = errMsgOk

try:
rObject = Mplayer.currentProcess
if(rObject == None):
rObject = MplayerProcess("Radio", "---", "")
except Exception, err:
errMsg = str(err)
errNum = errNumStopRadioStationFailed

self.write(SnakeberryJSON().encode(Response(errNum, errMsg, rObject)))

self.write(SnakeberryJSON().encode(Response(errNum, errMsg, rObject)))
self.set_header('Content-Type','application/json')
60 changes: 60 additions & 0 deletions SnakeberryService/snakeberry
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/sh
#Install this script with:
# sudo cp snakeberry /etc/init.d/snakeberry
# sudo update-rc.d snakeberry defaults

set -e

NAME=snakeberry
PIDFILE=/var/run/$NAME.pid
LOGFILE=/var/log/$NAME.log

DAEMON_PATH=/home/pi/snakeberry
DAEMON_RUN="python snakeberry.py"

case $1 in
start)
printf "%-50s" "Starting $NAME..."
cd $DAEMON_PATH
PID=`$DAEMON_RUN > $LOGFILE 2>&1 & echo $!`
echo "Saving PID" $PID " to " $PIDFILE
if [ -z $PID ]; then
printf "%s\n" "Fail"
else
echo $PID > $PIDFILE
printf "%s\n" "Ok"
fi
;;
status)
printf "%-50s" "Checking $NAME..."
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
printf "%s\n" "Process dead but pidfile exists"
else
echo "Running"
fi
else
printf "%s\n" "Service not running"
fi
;;
stop)
printf "%-50s" "Stopping $NAME"
PID=`cat $PIDFILE`
cd $DAEMON_PATH
if [ -f $PIDFILE ]; then
kill -HUP $PID
printf "%s\n" "Ok"
rm -f $PIDFILE
else
printf "%s\n" "pidfile not found"
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {status|start|stop|restart}"
exit 1
esac
3 changes: 3 additions & 0 deletions SnakeberryService/snakeberry.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
from audioSystem import *
from services import *

static_path = os.path.join(os.path.dirname(__file__), 'static')

#Main loop
#Generates all service endpoints
#Author: Bruno Hautzenberger
if __name__ == "__main__":
application = tornado.web.Application([
(r"/(.*\.(html|css|js|png|ico))", tornado.web.StaticFileHandler, {'path': static_path}),
(r"/", ListServices),
(r"/radios", ListRadios),
(r"/radio/play/(.*)", PlayRadio),
Expand Down
9 changes: 9 additions & 0 deletions SnakeberryService/static/bootstrap-responsive.min.css

Large diffs are not rendered by default.

Loading