What is the most efficient method in a script to probe if MC is Playing/Paused/Stopped?
Hi,
Seen some amazing projects on the forum and curios about all PI projects you are baking.
Therefore sharing my results so far. Keep in mind I am a python NOOB and this is the first scripting/coding project in 20 years: So don't laugh but appreciate the effort.
This was the starting point:
#!/usr/bin/python
# First rude MC20 control Script in python 2.7
# there are 3 pull down bottons: volume_up, volume_down and toggle (witch toggles between Play and Pause)
# imports
from time import sleep
import RPi.GPIO as GPIO
import urllib
# setup variables
toggle_pin = 13
toggle = False
volume_up = False
volume_up_pin = 19
volume_down = False
volume_down_pin = 6
# set up the pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(toggle_pin, GPIO.IN) # TOGGLE PLAY/PAUSE
GPIO.setup(volume_up_pin, GPIO.IN) # VOLUME UP
GPIO.setup(volume_down_pin, GPIO.IN) # VOLUME DOWN
# main
# a pin-down gets once detected in a sort of flip-flop;
# a "hold-down-timer" would be nicer
while(True):
# Toggle Play/Pause
if(toggle == True):
if(GPIO.input(toggle_pin) == False):
urllib.urlopen('http://localhost:52199/MCWS/v1/Playback/PlayPause?Zone=-1&ZoneType=ID')
print('Toggle Play/Pause') #for testing feed back
toggle = GPIO.input(toggle_pin)
# VOLUME UP
if(volume_up == True):
if(GPIO.input(volume_up_pin) == False):
urllib.urlopen('http://localhost:52199/MCWS/v1/Playback/Volume?Level=0.05&Relative=1')
print('Volume up by 5%')
volume_up = GPIO.input(volume_up_pin)
# VOLUME DOWN
if(volume_down == True):
if(GPIO.input(volume_down_pin) == False):
urllib.urlopen('http://localhost:52199/MCWS/v1/Playback/Volume?Level=-0.05&Relative=1')
print ('Volume down by 5%')
volume_down = GPIO.input(volume_down_pin)
sleep(.1)
Version 3a:
#!/usr/bin/python
# MC20 control Script in python 2.7 - Script Version 3a
# Connects to the Media Center Web Service (MCWS) on the localhost
# There are 3 (pull down) buttons for control and 3 leds (red, green, blue) for feedback.
#
# Functionality:
# Commands/Query's target current playback zone in MC on localhost, this can be any DLNA-Render on the network
# Feedback leds:
# red = not connected to MC20/MCWS
# green = connected and not playing
# blue = playing <= 480000 kHz
# blue + red = playing > 480000 kHz
# Control Buttons :
# volume_up
# volume_down
# toggle = toggles between Play and Pause (Play if Playback stopped)
#Modules
from time import sleep
import RPi.GPIO as GPIO
import urllib
#Setup Variables
MCurl ='http://localhost:52199/MCWS/v1/'
connected = False
led_red_pin = 27
led_green_pin = 17
led_blue_pin = 22
toggle_pin = 13
toggle = False
volume_up_pin = 19
volume_up = False
volume_down_pin = 6
volume_down = False
#Set up Pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_red_pin, GPIO.OUT)
GPIO.setup(led_green_pin, GPIO.OUT)
GPIO.setup(led_blue_pin, GPIO.OUT)
GPIO.setup(toggle_pin, GPIO.IN)
GPIO.setup(volume_up_pin, GPIO.IN)
GPIO.setup(volume_down_pin, GPIO.IN)
#Functions
def MCinfo():
# gets the playback info of the current zone (ID=-1)
global connected
response = {}
try:
response_xml = urllib.urlopen(MCurl+'Playback/Info?Zone=-1')
response = Parse_response(response_xml)
except:
connected = False
response['Response Status'] = 'Fa' # Probably need this for error handling
# print response # for testing, spams terminal!
return response
#end def
def MCvol_up():
global connected
try:
response_xml = urllib.urlopen(MCurl+'Playback/Volume?Level=0.05&Relative=1')
print 'New Volume is', Parse_response(response_xml)['Display'] # for testing, will break on bad response
except:
connected = False
#end def
def MCvol_down():
global connected
try:
response_xml = urllib.urlopen(MCurl+'Playback/Volume?Level=-0.05&Relative=1')
print 'New Volume is', Parse_response(response_xml)['Display'] # for testing, will break on bad response
except:
connected = False
#end def
def MCtogglePlayback():
urllib.urlopen (MCurl+'Playback/PlayPause?Zone=-1&ZoneType=ID')
print 'Toglle Play/Pause' # for testing, MCWS has no use full response
#end def
def Parse_response(raw_XML):
# This returns the XML response of MCWS in a dictionary (array)
# There probably are more sophisticated way's to parse the XML response;
# this does the job (for now); the format of MCWS response is pretty predictable.
# It has to been seen if a full blown XML parser(module) does it more efficient.
response = (raw_XML.read()).splitlines() #read the XML resonse of MCWS and put it in a list of lines,
fdict = {} #and put the clean data in a dictionary:
fline = response[1] #Get "Response Status" on the 2nd line,
fkey = fline[1:16]
fvalue = fline[18:20] #"Failure".... gets truncated to 'Fa'
fdict[fkey] = fvalue
for fline in response [2:-1]: #Get remaning response
fpos = fline.find('">')
fkey = fline[12:fpos]
fvalue = fline[fpos+2:-7]
fdict[fkey] = fvalue
#end for
return fdict
#end def
#Main
# 2 nested loops:
# Outerloop try to connect to MCWS
# Innerloop connected to MCWS and do stuff
while connected == False:
## blink = not(GPIO.output(led_red_pin)) # tried to blink red led as in red_led = not(red_led).....
GPIO.output(led_red_pin, True)
GPIO.output(led_green_pin, False)
GPIO.output(led_blue_pin, False)
try: # adding some delay if used on boot is probably better
urllib.urlopen(MCurl+'Alive')
connected = True
GPIO.output(led_green_pin, True)
GPIO.output(led_red_pin, False)
GPIO.output(led_blue_pin, False)
except:
pass
# Innerloop, do Stuff
while connected == True:
info = MCinfo()
# doing this often takes too much horsepower, looking for improvement....
if info['Response Status'] == 'OK':
if info ['State'] == '2':
GPIO.output(led_blue_pin, True)
GPIO.output(led_red_pin, False)
GPIO.output(led_green_pin, False)
if int(info ['SampleRate']) > 48000:
GPIO.output(led_red_pin, True)
else:
GPIO.output(led_green_pin, True)
GPIO.output(led_red_pin, False)
GPIO.output(led_blue_pin, False)
# Future functionality : switch off amplifier after x min idle.
# loop to keep buttons responsive while tempering consumed horsepower
t = 0
while t < 20:
t = t + 1
# Toggle Play/Pause
if(toggle == True):
if(GPIO.input(toggle_pin) == False):
MCtogglePlayback()
toggle = GPIO.input(toggle_pin)
# VOLUME UP
if(volume_up == True):
if(GPIO.input(volume_up_pin) == False):
MCvol_up()
volume_up = GPIO.input(volume_up_pin)
# VOLUME DOWN
if(volume_down == True):
if(GPIO.input(volume_down_pin) == False):
MCvol_down()
volume_down = GPIO.input(volume_down_pin)
# Future functionality :
# toggle + volume_down = close MC, poweroff
# toggle + volume_up = close MC, reboot
sleep (.2)
#end t < n times
#end connected is True
sleep (1)
#end connected is False
Post your Suggestions and Optimization's