Der Hinweis war gold wert. Installieren mit pip3 und alles läuft wie gewünscht. Danke
Posts by skischus
-
-
-
Guten Abend,
bin mit meinem Sohn dabei ein Kinderradio zu bauen.
Angeschlossen an den Raspberry1 ist ein RFID-RC522-Reader, DAC, vier Taster und ein 16x2 Display.
Softwaremäßig läuft raspbian stretch, mpd+mpc, ein python Skript für den Reader+Buttons.
Bis auf das Display funktioniert alles wie es soll.
Angeschlossen wurde es nach folgender Anleitung:
https://www.schnatterente.net/technik/raspbe…hd44780-display
Das dort verwendete Skript funktioniert auch einwandfrei.
Mittels lcdproc und mpdlcd wollte ich Titel/Interpret auf dem Display anzeigen lassen.
Gehalten hab ich mich an diese Tutorials:
https://andypi.co.uk/2013/09/19/andypi-lcd-with-raspyfi/
https://pypi.org/project/mpdlcd/0.4.0/
lcdproc läuft, ich seh die Begrüßungsmeldung, wenn ich aber mpdlcd starte bekomme ich folgende Fehlermeldung
Pythonpi@RFIDRadio:~ $ mpdlcd Traceback (most recent call last): File "/usr/local/bin/mpdlcd", line 7, in <module> from mpdlcd import cli File "/usr/local/lib/python2.7/dist-packages/mpdlcd/cli.py", line 5, in <module> import configparser ImportError: No module named configparserwenn ich configparser via pip installiere und mpdlcd starte, erscheint das
Pythonpi@RFIDRadio:~ $ mpdlcd Traceback (most recent call last): File "/usr/local/bin/mpdlcd", line 7, in <module> from mpdlcd import cli File "/usr/local/lib/python2.7/dist-packages/mpdlcd/cli.py", line 6, in <module> import urllib.parse ImportError: No module named parseMir scheint da liegt ein grundsätzliches Problem vor, weiß jemand Rat?
-
kommt auf dein kodi an. wenn es auf osmc basiert, schau mal hier
-
-
-
-
Ich hab gute Erfahrungen mit der app BubbleUPnP gemacht. Kann Musik vom Handy und aus der Cloud (Google Music, YouTube) an Kodi senden
-
-
Thread
Music Player Daemon (MPD und MPC) auf dem Raspberry Pi
Hier das Wunsch-Tutorial von grauwolf58 zur Installation von Music Player Daemon (MPD) auf dem Raspberry Pi .
Folgendes Image dient als Grundlage: 2012-09-18-wheezy- raspbian .img
Was kann der MPD eigentlich?
Der Music Player Daemon ist ein MP3 Player auf Softwarebasis. Die Hardware ist in diesem Fall der Raspberry Pi mit seinem Audioausgang. Es können auch USB-Soundkarten angeschlossen werden oder der Sound via HDMI übertragen werden.
Der MPD ist ein kleines Programm welches .mp3 Dateien, die…
ps915October 15, 2012 at 9:17 PM -
hab mein problem mit folgendem script lösen können
Code
Display More#!/usr/bin env python import time import os import RPi.GPIO as GPIO #GPIO setup GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.IN, pull_up_down = GPIO.PUD_UP)#P11 GPIO.setup(11, GPIO.IN, pull_up_down = GPIO.PUD_UP)#P23 GPIO.setup(27, GPIO.IN, pull_up_down = GPIO.PUD_UP)#P13 GPIO.setup(22, GPIO.IN, pull_up_down = GPIO.PUD_UP)#P15 GPIO.setup(10, GPIO.IN, pull_up_down = GPIO.PUD_UP)#P19 GPIO.setup(9, GPIO.IN, pull_up_down = GPIO.PUD_UP)#P21 while True: if GPIO.input(17)==1: os.system ('mpc play') if GPIO.input(11)==1: os.system ('mpc pause') if GPIO.input(27)==1: os.system ('mpc next') if GPIO.input(22)==1: os.system ('mpc prev') if GPIO.input(10)==1: os.system ('mpc volume +5') if GPIO.input(9)==1: os.system ('mpc volume -5') time.sleep(0.1); GPIO.cleanup()gibt es auch die möglichkeit einen taster mit zwei funktionen zu belegen? in meinem fall den play button. kann ich dem die funktion zuweisen entweder 'mpc play' oder 'mpc pause', je nach status von mpc?
-
hmm,
bei mir startet mpd automatisch und spielt den zuletzt gehörten sender.
manuell kannst du eine bestimmte playlist mit folgendem befehl abspielen:mpc clear & mpc load NameDerPlaylist.m3u & mpc play
den befehl fügst du per cron zum autostart hinzu. dann sollts laufen.
-
Hmmm. Hab die Forensuche bemüht, hat mir aber nicht wirklich weitergeholfen.
Alle Threads bezogen sich auf ein Internetradio mit Touchscreen mit ellenlangen Skripten.
Mir reicht was ganz simples um MPD mit Buttons und Smartphone zu steuern. -
Guten Abend,
erstmal Danke an dieses Forum, hab hier schon einige Tipps und Anleitungen mitgenommen.
Zu meinem Anliegen: Bin dabei mir ein Internetradio mit MPD zu bauen und diesen mit Tastern zu steuern. Die (vorerst) letzten Teile sind gekommen und dank Tutorials auch richtig angeschlossen.Die hier aufgezeigten Lösungen haben bei mir nicht geklappt.
Fündig geworden bin ich dann in diesem Tutorial. Ist zwar gedacht für LCD und Buttons, das Skript läuft aber. Mit den Tastern kann ich MPD/MPC steuern.
Mein Problem ist, dass sich MPD nicht übers Handy steuern lässt, solange das python Skript läuft. Und auf diese Funktion möcht ich nicht verzichten.Bin ich übers Smartphone mit MPD verbunden und lasse das Skript starten gibts folgende Meldung:
Code
Display Moreroot@PiMusicBox:~# python buttons.py Traceback (most recent call last): File "buttons.py", line 250, in <module> if mpdConnect(client, CON_ID): File "buttons.py", line 184, in mpdConnect client.connect(**con_id) # File "/root/mpd.py", line 530, in connect self.disconnect() File "/root/mpd.py", line 536, in disconnect self._rfile.close() File "/root/mpd.py", line 75, in _dummy raise ConnectionError("Not connected") mpd.ConnectionError: Not connectedCode der Button.py
Python
Display More# -*- coding: utf-8 -*- ######### LCD DISPLAY + BUTTONS FOR RUNE AUDIO ######### # Written by: Randy Cupic (XploD) # # Contact: [email=randy2841@hotmail.com]randy2841@hotmail.com[/email] # # Schematic, details and tutorial: # ########################################################## ########## IMPORTS ########## import RPi.GPIO as GPIO from mpd import (MPDClient, CommandError) from socket import error as SocketError import sys import time import threading import urllib2 import subprocess import re import os import string import sched ############################### ############ GPIO NUMBERING MODE ############### # Change pin numbering mode for buttons and LEDs# # USE ONLY IF YOU KNOW WHAT YOU'RE DOING # gpio_numbering_mode = GPIO.BCM ################################################# ################### BUTTONS ############################################################ # Here you can specify your buttons pins # # Where your buttons are connected # # Or connect them using these default pins # # GPIO.BCM numbering mode is used by default # # You can find BCM pinout on Google # # BUTTONS ARE PULLED UP, so connect buttons to # # GROUND # BUTTON_PLAY = 23 # P16 BUTTON_NEXT = 10 # P19 BUTTON_PREV = 15 # P10 BUTTON_VUP = 24 # P18 BUTTON_VDN = 4 # P3 WARNING: If you're using RPi model B rev 2, use 2 instead 0 !!!! BUTTON_STOP = 14 # P8 bounce_time = 150 # miliseconds, time to ignore button after press ######################################################################################### ################### LCD DISPLAY ######################################################## # Here you can specify your LCD settings and pins # # Where your LCD is connected # # Or connect it to these default pins # # GPIO.BCM numbering mode is used # # You can find BCM pinout on Google # ######################################################################################### ######### MPD PARAMETERS ############## # Only if you know what you're doing! # HOST = 'localhost' # #HOST = '192.168.0.125' # PORT = '6600' # PASSWORD = False # CON_ID = {'host':HOST, 'port':PORT} # ######################################### # Set GPIO mode GPIO.setmode(gpio_numbering_mode) # We don't need warnings from GPIO GPIO.setwarnings(False) # Initialize LCD # MPD client object instance2 client = MPDClient() client_cntrl = MPDClient() # Current data # state: 0 (for stopped), 1 (for playing), 2 (for paused) # artist: artist name (for files), radio name (for radio stations) # song: song name (for files), ARTIST - SONG (for radio stations, if available) # type: 0 (for files), 1 (for radio) data = {'state': 0, 'artist': '', 'title': '', 'type': 0, 'volume': 0} data_changed = False; # Used to indicate that data has changed to LCD display thread data_changed_vol = False; # Used to indicate that volume has changed to LCD display thread #################### DECODING STRING for non unicode-characters ########################### # Currently, only ë will be replaced by e, all others will be replaced by space # # You can enable desired ones by removing the # character in front of it # def char_decode(string): # string = string.replace('À', 'A') # string = string.replace('Á', 'A') # string = string.replace('Â', 'A') # string = string.replace('Ã', 'A') # string = string.replace('Ä', 'A') # string = string.replace('Å', 'A') # string = string.replace('Æ', 'A') # string = string.replace('Ç', 'C') # string = string.replace('È', 'E') # string = string.replace('É', 'E') # string = string.replace('Ê', 'E') # string = string.replace('Ë', 'E') # string = string.replace('Ì', 'I') # string = string.replace('Í', 'I') # string = string.replace('Î', 'I') # string = string.replace('Ï', 'I') # string = string.replace('Ð', 'D') # string = string.replace('Ñ', 'N') # string = string.replace('Ò', 'O') # string = string.replace('Ó', 'O') # string = string.replace('Ô', 'O') # string = string.replace('Õ', 'O') # string = string.replace('Ö', 'O') # string = string.replace('×', 'X') # string = string.replace('Ø', 'O') # string = string.replace('Ù', 'U') # string = string.replace('Ú', 'U') # string = string.replace('Û', 'U') # string = string.replace('Ü', 'U') # string = string.replace('Ý', 'Y') # string = string.replace('à', 'a') # string = string.replace('á', 'a') # string = string.replace('â', 'a') # string = string.replace('ã', 'a') # string = string.replace('ä', 'a') # string = string.replace('å', 'a') # string = string.replace('æ', 'a') # string = string.replace('ç', 'c') # string = string.replace('è', 'e') # string = string.replace('é', 'e') # string = string.replace('ê', 'e') string = string.replace('ë', 'e') # string = string.replace('ì', 'i') # string = string.replace('í', 'i') # string = string.replace('î', 'i') # string = string.replace('ï', 'i') # string = string.replace('ð', 'd') # string = string.replace('ñ', 'n') # string = string.replace('ò', 'o') # string = string.replace('ó', 'o') # string = string.replace('ô', 'o') # string = string.replace('õ', 'o') # string = string.replace('ö', 'o') # string = string.replace('ø', 'o') # string = string.replace('ù', 'u') # string = string.replace('ú', 'u') # string = string.replace('û', 'u') # string = string.replace('ü', 'u') # string = string.replace('ý', 'y') # string = string.replace('þ', 'p') # string = string.replace('ÿ', 'y') strip_unicode = re.compile("([^-_a-zA-Z0-9!@#%&=,/'\";:~`\$\^\*\(\)\+\[\]\.\{\}\|\?\<\>\\]+|[^\s]+)") return strip_unicode.sub('', string.decode('unicode-escape')) # We have to ping MPD client for buttons to avoid losing connection # By default, MPD will close connection after 60 seconds of inactivity def mpd_ping(): while True: time.sleep(50) # We will ping it every 50 seconds #print "Pinging MPD..." client_cntrl.ping() # Ping it! ###### MPD CLIENT FUNCTIONS ####### def mpdConnect(client, con_id): # """ # Simple wrapper to connect MPD. # """ # try: # client.connect(**con_id) # except SocketError: # return False # return True # # def mpdAuth(client, secret): # """ # Authenticate # """ # try: # client.password(secret) # except CommandError: # return False # return True # ##################################### ########## CALLBACK FUNCTIONS FOR BUTTONS ########## def play_pressed(channel): # global client_cntrl # time.sleep(0.05) # if (GPIO.input(BUTTON_PLAY) == 0): # if (data['state'] == 1): # client_cntrl.pause(1) # else: # client_cntrl.play() # # def stop_pressed(channel): # global client_cntrl # time.sleep(0.05) # if (GPIO.input(BUTTON_STOP) == 0): # client_cntrl.stop() # # def prev_pressed(channel): # global client_cntrl # time.sleep(0.05) # if (GPIO.input(BUTTON_PREV) == 0): # client_cntrl.previous() # # def next_pressed(channel): # global client_cntrl # time.sleep(0.05) # if (GPIO.input(BUTTON_NEXT) == 0): # client_cntrl.next() # # def vdn_pressed(channel): # global client_cntrl, client # time.sleep(0.05) # if (GPIO.input(BUTTON_VDN) == 0): # client_cntrl.setvol(data['volume'] - 5) # # def vup_pressed(channel): # global client_cntrl, client # time.sleep(0.05) # if (GPIO.input(BUTTON_VUP) == 0): # client_cntrl.setvol(data['volume'] + 5) # ###################################################### ''' ######################################################################### ######################################################################### ===================== MAIN PROGRAM ====================================== ######################################################################### ######################################################################### ''' # First MPD client (for status) connection if mpdConnect(client, CON_ID): print('MPD Client Connected!') else: print('Fail to connect to MPD server!') sys.exit(1) # Auth if password is set non False if PASSWORD: if mpdAuth(client, PASSWORD): print('Pass auth!') else: print('Error trying to pass auth.') client.disconnect() sys.exit(2) # Second MPD client (for control) connection if mpdConnect(client_cntrl, CON_ID): print('MPD Client_Cntrl Connected!') else: print('Fail to connect to MPD server!') sys.exit(1) # Auth if password is set non False if PASSWORD: if mpdAuth(client_cntrl, PASSWORD): print('Pass auth!') else: print('Error trying to pass auth.') client_cntrl.disconnect() sys.exit(2) ''' FIRST STATUS FETCH ''' data['volume'] = int(client.status()['volume']) # Get volume # Get station try: station = client.currentsong()['name'] except KeyError: station = '' # Get title try: title = client.currentsong()['title'] except KeyError: title = '' # Get artist try: artist = client.currentsong()['artist'] except KeyError: artist = '' # Check if web radio is playing (radio station) if(station != ''): # webradio data['type'] = 1 # Set data type to radio # Get station name and current song, all first letter to uppercase lst = [word[0].upper() + word[1:] for word in station.split()] data['artist'] = " ".join(lst) lst = [word[0].upper() + word[1:] for word in title.split()] data['title'] = " ".join(lst) # Else, it's a file playing else: # file data['type'] = 0 # Set data type to file # Get artist name and current song title, all first letter to uppercase lst = [word[0].upper() + word[1:] for word in artist.split()] data['artist'] = " ".join(lst) lst = [word[0].upper() + word[1:] for word in title.split()] data['title'] = " ".join(lst) # Check whether it's playing, paused or stopped and update status accordingly if (client.status()['state'] == 'play'): data['state'] = 1 elif (client.status()['state'] == 'stop'): data['state'] = 0 elif (client.status()['state'] == 'pause'): data['state'] = 2 # MPD Ping Thread mpdping_t = threading.Thread(target=mpd_ping, args = ()) # Create thread for pinging MPD mpdping_t.daemon = True # Yep, it's a daemon, when main thread finish, this one will finish too mpdping_t.start() # Start it! data_changed = True # Notify LCD thread about change # Set button pins as input, with pull up resistor (buttons are connected to ground) GPIO.setup(BUTTON_PLAY, GPIO.IN, pull_up_down = GPIO.PUD_UP) GPIO.setup(BUTTON_NEXT, GPIO.IN, pull_up_down = GPIO.PUD_UP) GPIO.setup(BUTTON_PREV, GPIO.IN, pull_up_down = GPIO.PUD_UP) GPIO.setup(BUTTON_VUP, GPIO.IN, pull_up_down = GPIO.PUD_UP) GPIO.setup(BUTTON_VDN, GPIO.IN, pull_up_down = GPIO.PUD_UP) GPIO.setup(BUTTON_STOP, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Set interrupts: detect falling edge on buttons and run callback functions GPIO.add_event_detect(BUTTON_PLAY, GPIO.FALLING, callback=play_pressed, bouncetime=bounce_time) GPIO.add_event_detect(BUTTON_NEXT, GPIO.FALLING, callback=next_pressed, bouncetime=bounce_time) GPIO.add_event_detect(BUTTON_PREV, GPIO.FALLING, callback=prev_pressed, bouncetime=bounce_time) GPIO.add_event_detect(BUTTON_VUP, GPIO.FALLING, callback=vup_pressed, bouncetime=bounce_time) GPIO.add_event_detect(BUTTON_VDN, GPIO.FALLING, callback=vdn_pressed, bouncetime=bounce_time) GPIO.add_event_detect(BUTTON_STOP, GPIO.FALLING, callback=stop_pressed, bouncetime=bounce_time) # Wait for any changes on MPD while(1): client.send_idle() state = client.fetch_idle() # Volume has changed if (state[0] == 'mixer'): data['volume'] = int(client.status()['volume']) # Update volume data_changed_vol = True # Notify LCD thread about change # Something other has changed (song/station or state) if (state[0] == 'player'): # Get station try: station = client.currentsong()['name'] except KeyError: station = '' # Get title try: title = client.currentsong()['title'] except KeyError: title = '' # Get artist try: artist = client.currentsong()['artist'] except KeyError: artist = '' # Check if web radio is playing (radio station) if(station != ''): # webradio data['type'] = 1 # Set data type to radio # Get station name and current song, all first letter to uppercase lst = [word[0].upper() + word[1:] for word in station.split()] data['artist'] = " ".join(lst) lst = [word[0].upper() + word[1:] for word in title.split()] data['title'] = " ".join(lst) # Else, it's a file playing else: # file data['type'] = 0 # Set data type to file # Get artist name and current song title, all first letter to uppercase lst = [word[0].upper() + word[1:] for word in artist.split()] data['artist'] = " ".join(lst) lst = [word[0].upper() + word[1:] for word in title.split()] data['title'] = " ".join(lst) # Check whether it's playing, paused or stopped and update status accordingly if (client.status()['state'] == 'play'): data['state'] = 1 elif (client.status()['state'] == 'stop'): data['state'] = 0 elif (client.status()['state'] == 'pause'): data['state'] = 2 data_changed = True # Notify LCD thread about change # Disconnect MPD client client.disconnect() # Wait for LCD thread to finish lcd_t.join() # Wait for MPD ping thread to finish mpdping_t.join() # Exit sys.exit(0)Code mpd.py
Python
Display More# python-mpd2: Python MPD client library # Copyright (C) 2008-2010 J. Alexander Treuman <[email=jat@spatialrift.net]jat@spatialrift.net[/email]> # Copyright (C) 2012 J. Thalheim <[email=jthalheim@gmail.com]jthalheim@gmail.com[/email]> # # python-mpd2 is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # python-mpd2 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with python-mpd2. If not, see <[url=http://www.gnu.org/licenses/]http://www.gnu.org/licenses/[/url]>. import logging import sys import socket import warnings from collections import Callable VERSION = (0, 5, 4) HELLO_PREFIX = "OK MPD " ERROR_PREFIX = "ACK " SUCCESS = "OK" NEXT = "list_OK" IS_PYTHON2 = sys.version_info < (3, 0) if IS_PYTHON2: decode_str = lambda s: s.decode("utf-8") encode_str = lambda s: s if type(s) == str else (unicode(s)).encode("utf-8") else: decode_str = lambda s: s encode_str = lambda s: str(s) try: from logging import NullHandler except ImportError: # NullHandler was introduced in python2.7 class NullHandler(logging.Handler): def emit(self, record): pass logger = logging.getLogger(__name__) logger.addHandler(NullHandler()) class MPDError(Exception): pass class ConnectionError(MPDError): pass class ProtocolError(MPDError): pass class CommandError(MPDError): pass class CommandListError(MPDError): pass class PendingCommandError(MPDError): pass class IteratingError(MPDError): pass class _NotConnected(object): def __getattr__(self, attr): return self._dummy def _dummy(*args): raise ConnectionError("Not connected") _commands = { # Status Commands "clearerror": "_fetch_nothing", "currentsong": "_fetch_object", "idle": "_fetch_idle", "status": "_fetch_object", "stats": "_fetch_object", # Playback Option Commands "consume": "_fetch_nothing", "crossfade": "_fetch_nothing", "mixrampdb": "_fetch_nothing", "mixrampdelay": "_fetch_nothing", "random": "_fetch_nothing", "repeat": "_fetch_nothing", "setvol": "_fetch_nothing", "single": "_fetch_nothing", "replay_gain_mode": "_fetch_nothing", "replay_gain_status": "_fetch_item", # Playback Control Commands "next": "_fetch_nothing", "pause": "_fetch_nothing", "play": "_fetch_nothing", "playid": "_fetch_nothing", "previous": "_fetch_nothing", "seek": "_fetch_nothing", "seekid": "_fetch_nothing", "seekcur": "_fetch_nothing", "stop": "_fetch_nothing", # Playlist Commands "add": "_fetch_nothing", "addid": "_fetch_item", "addtagid": "_fetch_nothing", "cleartagid": "_fetch_nothing", "clear": "_fetch_nothing", "delete": "_fetch_nothing", "deleteid": "_fetch_nothing", "move": "_fetch_nothing", "moveid": "_fetch_nothing", "playlist": "_fetch_playlist", "playlistfind": "_fetch_songs", "playlistid": "_fetch_songs", "playlistinfo": "_fetch_songs", "playlistsearch": "_fetch_songs", "plchanges": "_fetch_songs", "plchangesposid": "_fetch_changes", "prio": "_fetch_nothing", "prioid": "_fetch_nothing", "rangeid": "_fetch_nothing", "shuffle": "_fetch_nothing", "swap": "_fetch_nothing", "swapid": "_fetch_nothing", # Stored Playlist Commands "listplaylist": "_fetch_list", "listplaylistinfo": "_fetch_songs", "listplaylists": "_fetch_playlists", "load": "_fetch_nothing", "playlistadd": "_fetch_nothing", "playlistclear": "_fetch_nothing", "playlistdelete": "_fetch_nothing", "playlistmove": "_fetch_nothing", "rename": "_fetch_nothing", "rm": "_fetch_nothing", "save": "_fetch_nothing", # Database Commands "count": "_fetch_object", "find": "_fetch_songs", "findadd": "_fetch_nothing", "list": "_fetch_list", "listall": "_fetch_database", "listallinfo": "_fetch_database", "listfiles": "_fetch_database", "lsinfo": "_fetch_database", "readcomments": "_fetch_object", "search": "_fetch_songs", "searchadd": "_fetch_nothing", "searchaddpl": "_fetch_nothing", "update": "_fetch_item", "rescan": "_fetch_item", # Mounts and neighbors "mount": "_fetch_nothing", "umount": "_fetch_nothing", "listmounts": "_fetch_mounts", "listneighbors": "_fetch_neighbors", # Sticker Commands "sticker get": "_fetch_sticker", "sticker set": "_fetch_nothing", "sticker delete": "_fetch_nothing", "sticker list": "_fetch_stickers", "sticker find": "_fetch_songs", # Connection Commands "close": None, "kill": None, "password": "_fetch_nothing", "ping": "_fetch_nothing", # Audio Output Commands "disableoutput": "_fetch_nothing", "enableoutput": "_fetch_nothing", "toggleoutput": "_fetch_nothing", "outputs": "_fetch_outputs", # Reflection Commands "config": "_fetch_item", "commands": "_fetch_list", "notcommands": "_fetch_list", "tagtypes": "_fetch_list", "urlhandlers": "_fetch_list", "decoders": "_fetch_plugins", # Client To Client "subscribe": "_fetch_nothing", "unsubscribe": "_fetch_nothing", "channels": "_fetch_list", "readmessages": "_fetch_messages", "sendmessage": "_fetch_nothing", } class MPDClient(object): def __init__(self, use_unicode=False): self.iterate = False self.use_unicode = use_unicode self._reset() def _send(self, command, args, retval): if self._command_list is not None: raise CommandListError("Cannot use send_%s in a command list" % command) self._write_command(command, args) if retval is not None: self._pending.append(command) def _fetch(self, command, args, retval): if self._command_list is not None: raise CommandListError("Cannot use fetch_%s in a command list" % command) if self._iterating: raise IteratingError("Cannot use fetch_%s while iterating" % command) if not self._pending: raise PendingCommandError("No pending commands to fetch") if self._pending[0] != command: raise PendingCommandError("'%s' is not the currently " "pending command" % command) del self._pending[0] if isinstance(retval, Callable): return retval() return retval def _execute(self, command, args, retval): if self._iterating: raise IteratingError("Cannot execute '%s' while iterating" % command) if self._pending: raise PendingCommandError("Cannot execute '%s' with " "pending commands" % command) if self._command_list is not None: if not isinstance(retval, Callable): raise CommandListError("'%s' not allowed in command list" % command) self._write_command(command, args) self._command_list.append(retval) else: self._write_command(command, args) if isinstance(retval, Callable): return retval() return retval def _write_line(self, line): self._wfile.write("%s\n" % line) self._wfile.flush() def _write_command(self, command, args=[]): parts = [command] for arg in args: if type(arg) is tuple: if len(arg) == 0: parts.append('":"') elif len(arg) == 1: parts.append('"%d:"' % int(arg[0])) else: parts.append('"%d:%d"' % (int(arg[0]), int(arg[1]))) else: parts.append('"%s"' % escape(encode_str(arg))) # Minimize logging cost if the logging is not activated. if logger.isEnabledFor(logging.DEBUG): if command == "password": logger.debug("Calling MPD password(******)") else: logger.debug("Calling MPD %s%r", command, args) self._write_line(" ".join(parts)) def _read_line(self): line = self._rfile.readline() if self.use_unicode: line = decode_str(line) if not line.endswith("\n"): self.disconnect() raise ConnectionError("Connection lost while reading line") line = line.rstrip("\n") if line.startswith(ERROR_PREFIX): error = line[len(ERROR_PREFIX):].strip() raise CommandError(error) if self._command_list is not None: if line == NEXT: return if line == SUCCESS: raise ProtocolError("Got unexpected '%s'" % SUCCESS) elif line == SUCCESS: return return line def _read_pair(self, separator): line = self._read_line() if line is None: return pair = line.split(separator, 1) if len(pair) < 2: raise ProtocolError("Could not parse pair: '%s'" % line) return pair def _read_pairs(self, separator=": "): pair = self._read_pair(separator) while pair: yield pair pair = self._read_pair(separator) def _read_list(self): seen = None for key, value in self._read_pairs(): if key != seen: if seen is not None: raise ProtocolError("Expected key '%s', got '%s'" % (seen, key)) seen = key yield value def _read_playlist(self): for key, value in self._read_pairs(":"): yield value def _read_objects(self, delimiters=[]): obj = {} for key, value in self._read_pairs(): key = key.lower() if obj: if key in delimiters: yield obj obj = {} elif key in obj: if not isinstance(obj[key], list): obj[key] = [obj[key], value] else: obj[key].append(value) continue obj[key] = value if obj: yield obj def _read_command_list(self): try: for retval in self._command_list: yield retval() finally: self._command_list = None self._fetch_nothing() def _read_stickers(self): for key, sticker in self._read_pairs(): value = sticker.split('=', 1) if len(value) < 2: raise ProtocolError("Could not parse sticker: %r" % sticker) yield tuple(value) def _iterator_wrapper(self, iterator): try: for item in iterator: yield item finally: self._iterating = False def _wrap_iterator(self, iterator): if not self.iterate: return list(iterator) self._iterating = True return self._iterator_wrapper(iterator) def _fetch_nothing(self): line = self._read_line() if line is not None: raise ProtocolError("Got unexpected return value: '%s'" % line) def _fetch_item(self): pairs = list(self._read_pairs()) if len(pairs) != 1: return return pairs[0][1] def _fetch_sticker(self): # Either we get one or we get an error while reading the line key, value = list(self._read_stickers())[0] return value def _fetch_stickers(self): return dict(self._read_stickers()) def _fetch_list(self): return self._wrap_iterator(self._read_list()) def _fetch_playlist(self): return self._wrap_iterator(self._read_playlist()) def _fetch_object(self): objs = list(self._read_objects()) if not objs: return {} return objs[0] def _fetch_objects(self, delimiters): return self._wrap_iterator(self._read_objects(delimiters)) def _fetch_changes(self): return self._fetch_objects(["cpos"]) def _fetch_idle(self): self._sock.settimeout(self.idletimeout) ret = self._fetch_list() self._sock.settimeout(self._timeout) return ret def _fetch_songs(self): return self._fetch_objects(["file"]) def _fetch_mounts(self): return self._fetch_objects(["mount"]) def _fetch_neighbors(self): return self._fetch_objects(["neighbor"]) def _fetch_playlists(self): return self._fetch_objects(["playlist"]) def _fetch_database(self): return self._fetch_objects(["file", "directory", "playlist"]) def _fetch_messages(self): return self._fetch_objects(["channel"]) def _fetch_outputs(self): return self._fetch_objects(["outputid"]) def _fetch_plugins(self): return self._fetch_objects(["plugin"]) def _fetch_command_list(self): return self._wrap_iterator(self._read_command_list()) def noidle(self): if not self._pending or self._pending[0] != 'idle': raise CommandError('cannot send noidle if send_idle was not called') del self._pending[0] self._write_command("noidle") return self._fetch_list() def _hello(self): line = self._rfile.readline() if not line.endswith("\n"): self.disconnect() raise ConnectionError("Connection lost while reading MPD hello") line = line.rstrip("\n") if not line.startswith(HELLO_PREFIX): raise ProtocolError("Got invalid MPD hello: '%s'" % line) self.mpd_version = line[len(HELLO_PREFIX):].strip() def _reset(self): self.mpd_version = None self._iterating = False self._pending = [] self._command_list = None self._sock = None self._rfile = _NotConnected() self._wfile = _NotConnected() def _connect_unix(self, path): if not hasattr(socket, "AF_UNIX"): raise ConnectionError("Unix domain sockets not supported " "on this platform") sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.settimeout(self.timeout) sock.connect(path) return sock def _connect_tcp(self, host, port): try: flags = socket.AI_ADDRCONFIG except AttributeError: flags = 0 err = None for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, socket.IPPROTO_TCP, flags): af, socktype, proto, canonname, sa = res sock = None try: sock = socket.socket(af, socktype, proto) sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.settimeout(self.timeout) sock.connect(sa) return sock except socket.error as e: err = e if sock is not None: sock.close() if err is not None: raise err else: raise ConnectionError("getaddrinfo returns an empty list") def _settimeout(self, timeout): self._timeout = timeout if self._sock != None: self._sock.settimeout(timeout) def _gettimeout(self): return self._timeout timeout = property(_gettimeout, _settimeout) _timeout = None idletimeout = None def connect(self, host, port, timeout=None): logger.info("Calling MPD connect(%r, %r, timeout=%r)", host, port, timeout) if self._sock is not None: raise ConnectionError("Already connected") if timeout != None: warnings.warn("The timeout parameter in connect() is deprecated! " "Use MPDClient.timeout = yourtimeout instead.", DeprecationWarning) self.timeout = timeout if host.startswith("/"): self._sock = self._connect_unix(host) else: self._sock = self._connect_tcp(host, port) if IS_PYTHON2: self._rfile = self._sock.makefile("r") self._wfile = self._sock.makefile("w") else: # Force UTF-8 encoding, since this is dependant from the LC_CTYPE # locale. self._rfile = self._sock.makefile("r", encoding="utf-8") self._wfile = self._sock.makefile("w", encoding="utf-8") try: self._hello() except: self.disconnect() raise def disconnect(self): logger.info("Calling MPD disconnect()") if not self._rfile is None: self._rfile.close() if not self._wfile is None: self._wfile.close() if not self._sock is None: self._sock.close() self._reset() def fileno(self): if self._sock is None: raise ConnectionError("Not connected") return self._sock.fileno() def command_list_ok_begin(self): if self._command_list is not None: raise CommandListError("Already in command list") if self._iterating: raise IteratingError("Cannot begin command list while iterating") if self._pending: raise PendingCommandError("Cannot begin command list " "with pending commands") self._write_command("command_list_ok_begin") self._command_list = [] def command_list_end(self): if self._command_list is None: raise CommandListError("Not in command list") if self._iterating: raise IteratingError("Already iterating over a command list") self._write_command("command_list_end") return self._fetch_command_list() @classmethod def add_command(cls, name, callback): method = newFunction(cls._execute, name, callback) send_method = newFunction(cls._send, name, callback) fetch_method = newFunction(cls._fetch, name, callback) # create new mpd commands as function in three flavors: # normal, with "send_"-prefix and with "fetch_"-prefix escaped_name = name.replace(" ", "_") setattr(cls, escaped_name, method) setattr(cls, "send_"+escaped_name, send_method) setattr(cls, "fetch_"+escaped_name, fetch_method) @classmethod def remove_command(cls, name): if not hasattr(cls, name): raise ValueError("Can't remove not existent '%s' command" % name) name = name.replace(" ", "_") delattr(cls, str(name)) delattr(cls, str("send_" + name)) delattr(cls, str("fetch_" + name)) def bound_decorator(self, function): """ bind decorator to self """ if not isinstance(function, Callable): return None def decorator(*args, **kwargs): return function(self, *args, **kwargs) return decorator def newFunction(wrapper, name, returnValue): def decorator(self, *args): return wrapper(self, name, args, bound_decorator(self, returnValue)) return decorator for key, value in _commands.items(): returnValue = None if value is None else MPDClient.__dict__[value] MPDClient.add_command(key, returnValue) def escape(text): return text.replace("\\", "\\\\").replace('"', '\\"') # vim: set expandtab shiftwidth=4 softtabstop=4 textwidth=79:Hab in der Buttons.py wild alles rausgelöscht, was nach LCD aussah und die GPIOs angepasst. Mehr hab ich aber auch nicht drauf. Hab auch mal alles mit HOST, CON_ID gelöscht, dann ging aber nix mehr.
Gibts noch Hoffnung, dass ich MPD sowohl per Buttons als auch per Smartphone bedienen kann? Oder brauchts ein ganz anderes Skript?Das Ganze läuft mit DietPi+HifiPaket.
YMPD ist über den Browser erreich- und bedienbar wenn das python Skript aktiv ist. Liegt wohl daran, dass es lokal auf MPD zugreift?? -
Guten Morgen,
habe PowerPi installiert, das hat meiner Meinung nach auch funktioniert.
Rufe ich jedoch IP-Pi/index.php auf, erscheint immer die Meldung "504 Gateway Time-out".
Habe mich an folgende Anleitung gehalten http://raspberrypiguide.de/howtos/powerpi…-haussteuerung/, weiß jemand einen Rat?Vielen Dank