Thank you for your donation!


Cloudsmith graciously provides open-source package management and distribution for our project.


Problem: Bootup/shutdown issues, how to debug
#16
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:
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()
Reply


Messages In This Thread
RE: Bootup/shutdown issues, how to debug - by Max Schmeling - 04-15-2021, 04:41 PM

Forum Jump: