Ankündigung

Einklappen
Keine Ankündigung bisher.

MPD mit mehreren Instanzen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #16
    Klingt beruhigend. Ich dachte nur, dass der Datenverkehr auch so existiert - und ich ihn mit DEBUG nur sichtbar mache.

    Kommentar


      #17
      Naja Du kannst schon noch tiefer in Python einsteigen. Auch das aufrufen des Logging Moduls kostet Rechenzeit. Dort wird dann geprüft ob der aktuelle Logger auch einem Level entspricht der für eine Aufzeichnung passen könnte. Der Handler prüft dann wiederum ob für seinen Level eine Aufzeichnung stattfinden soll.
      Wenn man zeitkritischen Code ausführt, dann kann es unter Umständen besser sein sich am Anfang der Methode den aktuellen Loglevel vom Logger zu holen und dann den Logger nur aufzurufen, wenn der Logging Level auch dem geforderten Mindestlevel entspricht.
      Aber wenn Du nicht gerade mit einem Raspi 1 unterwegs bist, kann man das wohl vernachlässigen.

      Kommentar


        #18
        Danke für die ausführliche Antwort - auch wenn ich leider nur einen kleinen Teil davon verstehe.

        Kommentar


          #19
          Du kannst - wenn Interesse besteht - noch mal unter der offiziellen Python Doku schauen zum Thema Logging - HowTo

          Kommentar


            #20
            Dank verschiedener Hilfen habe ich es mittlerweile geschafft vier MPD Instanzen auf einer Soundkarte auszugeben - soweit bin ich schonmal total zufrieden. Gelegentlich tritt aber noch ein Problem, dass eventuell vom Client verursacht wird:
            Nach der Initialisierung der Instanzen mit systemctl start mpd/mpd2/... erscheint im Log die Meldung:
            Feb 25 21:11 : avahi: Service 'mpd1 @ shserver' successfully established.
            Feb 25 21:11 : client: [0] opened from 127.0.0.1:45658
            Soweit so gut. Ich kann Musik aus verschiedenen Quellen abspielen. Wird die Musikwiedergabe aber beendet, tritt manchmal das Problem auf, dass die Instanz überhaupt nicht mehr ansprechbar ist. Im Log steht dazu:
            Feb 25 21:13 : client: [0] closed
            Ein Neustart der Instanz mit systemctl stop und start führt nicht weiter. Nur nach einem komplettern Neustart des Systems funktioniert die Instanz wieder. Das Problem tritt leider unregelmäßig bei verschiedenen Instanzen auf.

            Eventuell ist diese Zeile in der init dafür verantwortlich:
            Code:
                def stop(self):
                    self.alive = False
                    # added to effect better cleanup on stop
                    if self.scheduler_get('update_status'):
                        self.scheduler_remove('update_status')
                    self._client.close()
            Ist es möglich im Code des Plugins eine Zeile einzubauen, dass sich das Plugin nach einem Disconnect oder closed (durch Stop) automatisch wieder verbindet?

            Ich will nicht ausschließen, dass das Problem auch an der mpd.conf liegt - hier forsche noch weiter.
            Zuletzt geändert von MarcoKa; 25.02.2022, 23:32.

            Kommentar


              #21
              So wie Du es beschreibst, klingt das nach einem Ketten Problem.

              mpd beendet sich (Problem 1). Du machst mit systemctl zwar einen Neustart, aber das mpd Plugin macht keine Reconnect, weil es den Neustart gar nicht mitbekommen hat (Problem 2). Das ist eine reine Hypothese von mir, aber nicht unwahrscheinlich.

              Problem 1 könnte man evtl. über die Definition des Service in systemctl lösen, so dass der Service neu startet, falls er abstürtzt.

              Problem 2 müsste dann über eine Modifikation des Plugins beseitigt werden. Es gibt leider einige Plugons, die auf Berbindungsabbrüche nicht gut reagieren.

              Am besten wäre natürlich, der Service würde sich gar nicht beenden.
              Viele Grüße
              Martin

              There is no cloud. It's only someone else's computer.

              Kommentar


                #22
                Ich denke das wird ähnlich gelagert sein wie aktuell das knx plugin. Wenn Beispielsweise im laufenden Betrieb der knxd nicht verfügbar ist (warum auch immer) dann versucht die lib.network einen reconnect. Aber es kann sein, das sich der Thread irgendwann beendet und dann nicht wieder aktiviert wird.
                Morg hat dazu einen Fix in develop gepusht der bei ihm das Problem anscheinend beseitigt. Ich habe aktuell noch nicht versucht den Fehler nachzustellen.
                Aktuell hat Morg aber einige Überlegungen wie der Plugin Neustart mit deregistrieren und neuem init besser gehandelt werden kann. Das wird aber eher was für die nächste Release denke ich.
                Es könnte höchstens sein das Msinn nochmal ein Service Release 1.9.2 rausbringt.

                Kommentar


                  #23
                  Ein guter Ansatz. Ist die Verbindung geschlossen und starte ich mpd über systemctl neu, steht im Log folgendes:
                  Feb 25 23:53 : client: [0] closed
                  Feb 25 23:57 : avahi: Service 'mpd1 @ shserver' successfully established.
                  Was fehlt ist nach dem Neustart über systemctl ein Logeintrag wie "client: [0] opened from 127.0.0.1:xxxxx"
                  Auch nach dem Neustart über systemctl ist die Instanz nicht ansprechbar. Ich verstehe die Meldung so, dass MPD zwar neustartet. Der Client dies aber nicht registriert und die Verbindung daher auch nicht öffnet.
                  In der init (ich hoffe, dass ist die richtige Stelle zum Suchen?!) steht folgender Absatz:
                  Code:
                      def run(self):
                          if not self._client.connect():
                              self.logger.error(f'Connection to {self.host}:{self.port} not possible. Plugin deactivated.')
                              return
                  
                          self.alive = True
                          self.scheduler_add('update_status', self.update_status, cycle=self._cycle)
                  Wenn ich dich richtig verstanden habe, müsste in der Schleife "if not self._client.connect()" jetzt ein Code zum Verbinden eingefügt werden. Wie du schon sagtest, wäre es am besten, wenn die Verbindung gar nicht erst beendet wird. Vielleicht sollte man daher in der Stop-Definition zusätzlich die Zeile:
                  Code:
                      def stop(self):
                          [...]
                         self._client.close()
                  auskommentieren.
                  Da ich aber den Code nicht ganz verstehe bzw. nicht weiß, was "self.client.close" bewirkt, frage ich lieber erstmal Euch um Rat. Jeder Codeteil hat ja einen bestimmten Zweck.

                  Kommentar


                    #24
                    Ich bin jetzt schon ein gutes Stück weiter. Das oben beschriebene Problem, dass sich der Client verabschiedet und nicht wiederkommt, trat bei genauerer Analyse vor allem dann auf, wenn per rawcommand ein stop-Signal gesendet wurde. Seitdem ich den rawcommand-Befehl umgehe läuft es sehr gut. Sehr selten verabschiedet sich noch eine Instanz, wenn lange nicht darauf zugegriffen wird - dieses Problem lässt sich mit der mpd.conf lösen. Der Befehl
                    Code:
                    connection_timeout "6000"
                    schaffte Abhilfe.
                    Mittlerweile schreibe ich die Logiken, um die einzelnen Instanzen zu steuern. Dabei habe ich ein paar grundsätzliche Fragen/Probleme. Die Lautstärke steuere ich Beispielsweise mit dem Code:
                    Code:
                    sh.KG.Bad.Audio.volumeMPD1.aendern(int(sh.KG.Bad.Audio.volumeTaster.aendern()/2.55))
                    Als watch-Item ist "sh.KG.Bad.Audio.volumeTaster.aendern ()" gesetzt.
                    Die dazugehörigen Items sehen wie folgt aus:
                    Code:
                                volumeMPD1:
                                    aendern:
                                        type: num
                                        mpd_status@kgbad: volume
                                        mpd_command@kgbad: setvol
                                        enforce_updates: true
                                volumeTaster:
                                    aendern:
                                        type: num
                                        knx_dpt: 5
                                        knx_listen: 9/1/9
                                        knx_status: 9/1/18
                                        enforce_updates: true
                    Zur Erläuterung: Ich drücke auf den Taster (Datentyp 5.005) und will die Lautstärke ändern. Auf dem Diesplay sehe ich die aktuelle Lautstärke in Prozent (Datentyp 5.001). Der Tasterwert (Datentyp 5.005) wird für die MPD-Instanz umgewandelt.
                    Nun mein Problem: Gebe ich per GUI im Item-Baum einen Wert für "sh.KG.Bad.Audio.volumeTaster.aendern" ein, erfolgt die Änderung sofort sichtbar (% Angabe auf Tasterdisplay) als auch hörbar. Nutze ich aber den Taster, erfolgt die sichtbare Änderung sofort, während die hörbare Änderung teilweise 3 Sekunden hinterher hinkt. Mitunter dauert die Ausführung eines Befehls sogar 10 Sekunden und länger.
                    Dieses Phänom habe ich auch wenn ich die Playlist oder das Lied wechsle. Selbst der Aus-Befehl wird verzögert ausgeführt.
                    Der Logikbefehl kommt zwar sehr schnell auf dem Bus (dies kann ich im Gruppenmonitor sehen), die hörbare Ausführung ist aber stark verzögert.
                    Ich kann mir dieses Phänomen nicht erklären.
                    Hat jemand schon mal mit ähnlichen Problemen zu kämpfen gehabt?
                    Zuletzt geändert von MarcoKa; 03.03.2022, 07:55.

                    Kommentar


                      #25
                      Ein kurzes Update: Mittlerweile laufen bei mir 9 Instanzen (vorerst) fehlerfrei. Dass Problem mit der Verzögerung liegt meines Erachtens am MPD-Plugin. Ich konnte die Fehlerstelle zwar nicht genau lokalisieren, wenn ich das Plugin aber umgehe, dann höre ich sofort nach Tastendruck die Veränderung.
                      Ich habe daher meine Logiken ohne Verwendung des MPD-Plugins geschrieben.
                      Zum Starten einer MPD-Instanz sieht meine Logik wie folgt aus:
                      Code:
                      import os
                      mpdport = 6605
                      mpdvolumestart = 50
                      
                      if sh.EG.Esszimmer.Audio.MPD5.schalten() == 1:
                          os.system ("mpc -p %s clear" %mpdport)
                          os.system ("mpc -p %s update NAS/Playlists" %mpdport)
                          sh.EG.Esszimmer.Audio.Playlist.Status(1)
                          sh.EG.Esszimmer.Audio.Verstaerker.schalten(1)
                          sh.EG.Esszimmer.Audio.Playlist.Name('Radio')
                          os.system ("mpc -p %s load radio" %mpdport)
                          os.system ("mpc -p %s volume %s" % (mpdport, mpdvolumestart))
                          os.system ("mpc -p %s play" %mpdport)
                          sh.EG.Esszimmer.Audio.volumeTaster.status(mpdvolumestart)
                      if sh.EG.Esszimmer.Audio.MPD5.schalten() == 0:
                          os.system ("mpc -p %s stop" %mpdport)
                          sh.EG.Esszimmer.Audio.Verstaerker.schalten(0)
                          sh.EG.Esszimmer.Audio.volumeTaster.status(mpdvolumestart)
                      Ich habe weitere Logiken zum Steuern der Lautstärke, der Playlist und der Trackwahl.
                      Für jede Instanz also 4 Logiken. Dies ist sicherlich nicht die eleganteste Lösung, aber für mich die einfachste. Ich hoffe einfach mal das SHNG mit so vielen Logiken kein Problem bekommt.

                      Vielen Dank an alle, die mir bei meinen Problem geholfen haben - ohne euren Support hätte ich sicherlich schon aufgegeben.
                      Beste Grüße
                      Marco

                      Kommentar

                      Lädt...
                      X