04-15-2021, 04:41 PM
So I had a bit of progress, using the most overused suggestion ever.
I reinstalled moode vanilla, without any modifications, and it works without errors, it seems. So the error must be in my code , eventhough it has also worked perfectly before I enabled bluetooth, so there must be something in my code that does not play well with the bluetooth part of moode or with the package python-mpd2.
As far as I can see, I get this error from the log:
Which refers to this line in my code:
The Client object is an mpd.MPDClient object defined like this:
I have absolutely no idea why the Client.status code creates this error. It has worked before. Does anybody know how to fix this, or basically how to use python to read if mpd is playing somthing?
The complete Python code is below
I reinstalled moode vanilla, without any modifications, and it works without errors, it seems. So the error must be in my code , eventhough it has also worked perfectly before I enabled bluetooth, so there must be something in my code that does not play well with the bluetooth part of moode or with the package python-mpd2.
As far as I can see, I get this error from the log:
Code:
Apr 14 08:34:14 moode systemd[1]: Stopped Music Player Daemon.
Apr 14 08:34:14 moode systemd[1]: Started Music Player Daemon.
Apr 14 08:34:14 moode rc.local[481]: Traceback (most recent call last):
Apr 14 08:34:14 moode rc.local[481]: File "/home/pi/ampcontroller.py", line 196, in <module>
Apr 14 08:34:14 moode rc.local[481]: if Client.status()['state'] == "play": # Playing or Airplay active
Apr 14 08:34:14 moode rc.local[481]: File "/usr/local/lib/python3.7/dist-packages/mpd/base.py", line 469, in mpd_command
Apr 14 08:34:14 moode rc.local[481]: return wrapper(self, name, args, callback)
Apr 14 08:34:14 moode rc.local[481]: File "/usr/local/lib/python3.7/dist-packages/mpd/base.py", line 532, in _execute
Apr 14 08:34:14 moode rc.local[481]: return retval()
Apr 14 08:34:14 moode rc.local[481]: File "/usr/local/lib/python3.7/dist-packages/mpd/base.py", line 454, in command_callback
Apr 14 08:34:14 moode rc.local[481]: res = function(self, self._read_lines())
Apr 14 08:34:14 moode rc.local[481]: File "/usr/local/lib/python3.7/dist-packages/mpd/base.py", line 394, in _parse_object
Apr 14 08:34:14 moode rc.local[481]: objs = list(self._parse_objects(lines))
Apr 14 08:34:14 moode rc.local[481]: File "/usr/local/lib/python3.7/dist-packages/mpd/base.py", line 240, in _parse_objects
Apr 14 08:34:14 moode rc.local[481]: for key, value in self._parse_pairs(lines):
Apr 14 08:34:14 moode rc.local[481]: File "/usr/local/lib/python3.7/dist-packages/mpd/base.py", line 235, in _parse_pairs
Apr 14 08:34:14 moode rc.local[481]: for line in lines:
Apr 14 08:34:14 moode rc.local[481]: File "/usr/local/lib/python3.7/dist-packages/mpd/base.py", line 586, in _read_lines
Apr 14 08:34:14 moode rc.local[481]: line = self._read_line()
Apr 14 08:34:14 moode rc.local[481]: File "/usr/local/lib/python3.7/dist-packages/mpd/base.py", line 571, in _read_line
Apr 14 08:34:14 moode rc.local[481]: raise ConnectionError("Connection lost while reading line")
Apr 14 08:34:14 moode rc.local[481]: mpd.base.ConnectionError: Connection lost while reading line
Apr 14 08:34:14 moode systemd[1]: rc-local.service: Control process exited, code=exited, status=1/FAILURE
Apr 14 08:34:14 moode systemd[1]: Created slice system-bluealsa\x2daplay.slice.
Apr 14 08:34:14 moode systemd[1]: Started BlueAlsa-Aplay.
Apr 14 08:34:14 moode systemd[1]: rc-local.service: Failed with result 'exit-code'.
Apr 14 08:34:14 moode systemd[1]: Failed to start /etc/rc.local Compatibility.
Which refers to this line in my code:
Code:
if Client.status()['state'] == "play":
The Client object is an mpd.MPDClient object defined like this:
Code:
Client = mpd.MPDClient() # create client object
Client.timeout = None
Client.idletimeout = None
while True:
try:
Client.connect("localhost", 6600) # connect to localhost:6600
except:
continue
break
I have absolutely no idea why the Client.status code creates this error. It has worked before. Does anybody know how to fix this, or basically how to use python to read if mpd is playing somthing?
The complete Python code is below
Code:
# Import the libraries to use time delays, send os commands and access GPIO pins
import RPi.GPIO as GPIO
import time
import os
import mpd
import sys
import sqlite3 as SQLite3
# Setup Variables
PowerButtonPin = 7
KeepPoweredPin = 8 # Pin to pull high to keep the Pi Supply giving power
RedLedPin = 13 # Set pin number for "OFF" LED
RedExtLedPin = 16 # Set pin number for "OFF" LED
GreenLedPin = 15 # Set pin number for "ON" LED
GreenExtLedPin = 18 # Set pin number for "ON" LED
MainRelayPin = 11 # Set pin number for relay output
Debug = False # Set to true if you want debug from the program. Remember to set it to false if you start the script from rc.local, otherwise your promt will be junked
AmpState = "on" # Stores on/off/standby state of the player and amp
ButtonOverride = False # False except when button initiates standby.
ShutdownActive = False # True when system is shutting down.
TimeSinceActive = time.time() # Stores the time when MoOde was last active
StandbyTimeLimit = 60
OffTimeLimit = 120
# Setup GPIO pins
GPIO.setmode(GPIO.BOARD) # Set pin numbering to board numbering
GPIO.setup(MainRelayPin, GPIO.OUT, initial=GPIO.LOW) # Setup MainRelayPin as an output
#GPIO.setup(PowerButtonPin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) # Setup PowerButtonPin as an input
GPIO.setup(PowerButtonPin, GPIO.IN) # Setup PowerButtonPin as an input
GPIO.setup(RedLedPin, GPIO.OUT) # Setup RedLedPin as an output
GPIO.setup(GreenLedPin, GPIO.OUT) # Setup GreenLedPin as an output
GPIO.setup(RedExtLedPin, GPIO.OUT) # Setup RedLedPin as an output
GPIO.setup(GreenExtLedPin, GPIO.OUT) # Setup GreenLedPin as an output
GPIO.setup(KeepPoweredPin, GPIO.OUT, initial=GPIO.HIGH) #Setup KeepPoweredPin to pull high to keep the Pi Supply giving power
# Amplifier state control procedure
def SetAmpState(state):
global AmpState
GPIO.output(RedLedPin,False)
GPIO.output(RedExtLedPin,False)
GPIO.output(GreenLedPin,False)
GPIO.output(GreenExtLedPin,False)
if state == "on":
GPIO.output(GreenLedPin,True)
GPIO.output(GreenExtLedPin,True)
GPIO.output(MainRelayPin, GPIO.HIGH)
AmpState = "on"
elif state == "off":
GPIO.output(RedLedPin,True)
GPIO.output(RedExtLedPin,True)
GPIO.output(MainRelayPin, GPIO.LOW)
AmpState = "off"
#os.system("shutdown -h 0&")
os.system("sudo shutdown now")
#sys.exit("Amp was turned off")
#sys.exit(0)
elif state == "standby":
GPIO.output(GreenLedPin,True)
GPIO.output(GreenExtLedPin,True)
GPIO.output(RedLedPin,True)
GPIO.output(RedExtLedPin,True)
GPIO.output(MainRelayPin, GPIO.LOW)
Client.pause(1)
AmpState = "standby"
# Mute Moode player
#os.system("/var/www/vol.sh mute")
if (Debug): print("Amplifier state: {0}".format(AmpState))
# Airplay state check
def IsAirplayOn():
global ButtonOverride
AirplayOn = False
try:
cur = con.cursor()
cur.execute('select value from cfg_system where param=\'airplayactv\'')
data = cur.fetchone()[0]
if (Debug): print("SQL = %s" % data)
if data == "1":
AirplayOn = True
except SQLite3.Error as e:
if (Debug): print("Error %s:" % e.args[0])
if ButtonOverride:
AirplayOn = False
if Debug: print("Returning IsAirplayOn = {0}".format(AirplayOn))
return AirplayOn
def Eval_buttonpress(channel):
global ShutdownActive
global ButtonOverride
global TimeSinceActive
# only react when there is no other shutdown process running
if not ShutdownActive:
ShutdownActive = True
pressed = 1
counter = 0
while (pressed == 1):
if (GPIO.input(PowerButtonPin) == True):
# button is still pressed
counter = counter + 1
if (Debug): print(("Counter is now: {0}".format(counter)))
# break if we count beyond 20 (long-press is a shutdown)
if (counter >= 20):
pressed = 0
else:
time.sleep(0.2)
else:
# button has been released
pressed = 0
if (Debug): print(("Button was pressed for: {0} counts.".format(counter)))
# count how long the button was pressed
if (counter < 2):
# short press
pressed = 0
ShutdownActive = False
else:
if (counter < 20):
# medium length press
if (Debug): print("Muting Moode..")
if AmpState == "on":
SetAmpState("standby")
ButtonOverride = True
else:
SetAmpState("on")
ButtonOverride = False
TimeSinceActive = time.time()
pressed = 0
ShutdownActive = False
else:
# long press, initiate system shutdown
if (Debug): print("shutting down..")
SetAmpState("off")
pressed = 0
#ShutdownActive = False
pressed = 0
# Setup MDPClient and connect to MPD on localhost
Client = mpd.MPDClient() # create client object
Client.timeout = None
Client.idletimeout = None
while True:
try:
Client.connect("localhost", 6600) # connect to localhost:6600
except:
continue
break
# Connect to player database, in order to read Airplay status
try:
con = SQLite3.connect('/var/local/www/db/moode-sqlite3.db')
except SQLite3.Error as e:
if Debug: print("Error %s:" % e.args[0])
sys.exit(1)
# Set PowerButtonPin as an interrupt input
GPIO.add_event_detect(PowerButtonPin, GPIO.RISING, callback = Eval_buttonpress)
SetAmpState("on")
#TimeSinceActive = time.time()
#global ButtonOverride
#global TimeSinceActive
#global AmpState
#global ShutdownActive
time.sleep(20)
TimeSinceActive = time.time()
# main loop
while True:
ElapsedTime = time.time() - TimeSinceActive
if (Debug): print(("{0} seconds have passed since last MPD was last playing.".format(ElapsedTime)))
# if Client.status()['state'] == "play" or IsAirplayOn(): # Playing or Airplay active
if Client.status()['state'] == "play": # Playing or Airplay active
ButtonOverride = False
StandbyTimeLimit = 240
OffTimeLimit = 600
TimeSinceActive = time.time()
if not AmpState == "on" and ShutdownActive == False:
SetAmpState("on") # Set GPIO pins to ON state
if (Debug): print("MPD state = play! Entering ON state")
if (Debug): print(("Amp is on = {0}".format(GPIO.input(MainRelayPin))))
else: # Either stopped or paused
if ElapsedTime >= StandbyTimeLimit:
if AmpState == "on":
SetAmpState("standby") # Set GPIO pins to OFF state
if (Debug): print(("MPD has not been playing for {0} seconds! Entering standby!".format(ElapsedTime)))
if (Debug): print(("Amp is on = {0}".format(GPIO.input(MainRelayPin))))
if ElapsedTime > OffTimeLimit:
if AmpState == "standby":
SetAmpState("off") # Set GPIO pins to OFF state
if (Debug): print(("MPD has not been playing for {0} seconds! Shutting down!".format(ElapsedTime)))
if (Debug): print(("Amp is on = {0}".format(GPIO.input(MainRelayPin))))
time.sleep(0.1)
# Close connection to MPD (not used since the main loop never exits)
Client.close() # send the close command
Client.disconnect() # disconnect from the server
# Close connection to database
if con:
con.close()