2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-15 16:19:11 +00:00

73_MPD: Maintainer update; include events from newer mpd versions, #130801

git-svn-id: https://svn.fhem.de/fhem/trunk@27027 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2023-01-11 19:11:55 +00:00
parent 84cf72774b
commit 4f39f2dd52
3 changed files with 117 additions and 38 deletions

View File

@ -2,6 +2,7 @@
# Do not insert empty lines here, update check depends on it.
- change: 93_DbRep: write TYPE uppercase with writeToDB option,
Commandref edited
- bugfix: 73_MPD: adopt to newer mpd versions with more events
- bugfix: 59_Weather: fix DarkSky API wrong funtion call
- feature: 72_FRITZBOX: merged old 72_FRITZBOX with last Fork Version
- bugfix: 59_Weather: bugfix function WeatherAsHtmlD not working

View File

@ -48,7 +48,7 @@ use strict;
use warnings;
use Time::HiRes qw(gettimeofday);
use URI::Escape;
use POSIX;
#use POSIX;
use Blocking; # http://www.fhemwiki.de/wiki/Blocking_Call
use IO::Socket;
use Getopt::Std;
@ -161,7 +161,7 @@ sub MPD_updateConfig($)
$hash->{helper}{playlistcollection}{val} = -1;
$hash->{".password"} = AttrVal($name, "password", "");
$hash->{TIMEOUT} = AttrVal($name, "timeout", 2);
$hash->{TIMEOUT} = AttrVal($name, 'timeout', 0.7);
$hash->{".sMusicL"} = AttrVal($name, "stateMusic", 1);
$hash->{".sPlayL"} = AttrVal($name, "statePlaylists", 1);
$hash->{".apikey"} = AttrVal($name, "lastfm_api_key", "f3a26c7c8b4c4306bc382557d5c04ad5");
@ -202,7 +202,7 @@ sub MPD_updateConfig($)
readingsEndUpdate($hash,0);
MPD_Outputs_Status($hash);
mpd_cmd($hash, clb.cle);
mpd_cmd($hash, clb.cle) if ReadingsVal($name,'presence','none') ne 'absent';
if ($hash->{".volume"} eq "0")
{ # ist Mute aktiv oder soll sie mit Absicht 0 sein ?
@ -233,7 +233,7 @@ sub MPD_updateConfig($)
{
# Playlisten und Musik Dir laden ?
# nicht bei Player mopidy, listall wird von ihm nicht unterstützt !
if ((AttrVal($name, "loadMusic", "1") eq "1") && !$error && ($hash->{".player"} ne "mopidy"))
if ((AttrVal($name, 'loadMusic', '0') eq '1') && !$error && ($hash->{'.player'} ne 'mopidy')) # Beta-User: listall is deprecated on the MPD side, see docu at https://mpd.readthedocs.io/en/latest/protocol.html#the-music-database
{
$error = mpd_cmd($hash, "i|listall|music");
Log3 $name,3,"$name, error loading music -> $error" if ($error);
@ -330,6 +330,7 @@ sub MPD_Attr (@)
}
elsif (($attrName eq "disable") && ($attrVal == 0))
{
return if !$init_done;
$attr{$name}{disable} = $attrVal;
readingsSingleUpdate($hash,"state","reset",1);
$hash->{".reset"} = 1;
@ -383,7 +384,7 @@ sub MPD_Attr (@)
$attr{$name}{disable} = 0;
readingsSingleUpdate($hash,"state","reset",1);
$hash->{".reset"}=1;
MPD_updateConfig($hash);
MPD_updateConfig($hash);
}
elsif ($attrName eq "statePlaylists") { $hash->{".sPlayL"} = 1; }
elsif ($attrName eq "stateMusic") { $hash->{".sMusicL"} = 1; }
@ -455,8 +456,9 @@ sub MPD_Set($@)
my $subcmd = (defined($a[2])) ? $a[2] : "";
return undef if ($subcmd eq '---'); # erster Eintrag im select Feld ignorieren
my $step = int(AttrVal($name, "volumeStep", 5)); # vllt runtersetzen auf default = 2 ?
my $vol_now = int($hash->{".volume"});
my $step = int(AttrVal($name, 'volumeStep', 5)); # vllt runtersetzen auf default = 2 ?
my $vol_now = $hash->{'.volume'} // 0;
$vol_now = int($vol_now);
my $vol_new;
if ($cmd eq "reset") { $hash->{".reset"} = 1; MPD_updateConfig($hash); return undef;}
@ -966,6 +968,7 @@ sub MPD_Outputs_Status($)
{
my ($hash)= @_;
my $name = $hash->{NAME};
return if ReadingsVal($name,'presence','none') eq 'absent';
$hash->{".outputs"} = mpd_cmd($hash, "i|outputs|x");
my @outp = split("\n" , $hash->{".outputs"});
readingsBeginUpdate($hash);
@ -973,6 +976,7 @@ sub MPD_Outputs_Status($)
foreach (@outp)
{
my @val = split(": " , $_);
next if !defined $val[1];
Log3 $name, 4 ,"$name, MPD_Outputs_Status -> $val[0] = $val[1]";
$outpid = ($val[0] eq "outputid") ? $val[1] : $outpid;
readingsBulkUpdate($hash,$val[0].$outpid,$val[1]) if ($val[0] ne "outputid");
@ -1020,8 +1024,24 @@ sub mpd_cmd($$)
return $!;
}
while (<$sock>) # MPD rede mit mir , egal was ;)
{ last if $_ ; } # end of output.
# my $read = new IO::Select() || return 'Error in calling IO::Select!\n';
# $read->add($sock);
# my @count = $read->can_read($hash->{TIMEOUT});
# return 'error - no data received from MPD!\n' if @count < 1;
if ( !eval {
$SIG{ALRM} = sub {Carp::carp 'timeout';};
alarm(1);
while (<$sock>) # MPD rede mit mir , egal was ;)
{ last if $_ ; } # end of output.
alarm(0);
1; }
) {
return $@ if $@;
}
# while (<$sock>) # MPD rede mit mir , egal was ;)
# { last if $_ ; } # end of output.
chomp $_;
@ -1207,6 +1227,10 @@ sub MPD_IdleStart($)
return $name."|IdleStart: $!" if (!$sock);
my $read = new IO::Select() || return 'Fehler beim Aufruf von IO::Select!\n';
$read->add($sock);
my @count = $read->can_read($hash->{TIMEOUT});
return "Fehler - keine Daten vom MPD!\n" if @count < 1;
while (<$sock>) { last if $_ ; }
chomp $_;
@ -1248,7 +1272,7 @@ sub MPD_IdleStart($)
$_ =~s/changed: //g;
if (($_ ne $old_event) && ($_ ne "OK") && (index($_,": ") == -1))
if (($_ ne $old_event) && ($_ ne "OK") && (index($_,": ") == -1) )
{
$output .= ($old_event eq "") ? $_ : "+".$_;
$old_event = $_;
@ -1257,7 +1281,16 @@ sub MPD_IdleStart($)
elsif (index($_,": ") > -1){
$output .= "|".$_;
$step=1;
}
}
elsif ($_ !~ m{\Aplayer|playlist|mixer|options|update\z}x){
print $sock "idle\n";
$step=1;
readingsSingleUpdate($hash,'last_error',$_,1);
}
elsif ($_ eq 'update'){ #might be extended for other new message types w/o further action to FHEM
print $sock "idle\n";
$step=1;
}
else #if ($_ eq "OK")
{
print $sock "idle\n" if($step) ;
@ -2225,13 +2258,17 @@ sub MPD_SaveBookmark($)
1;
__END__
=pod
=encoding utf8
=item device
=item summary controls MPD or Mopidy music server
=item summary_DE steuert den MPD oder Mopidy Musik Server
=begin html
<a name="MPD"></a>
<a id="MPD"></a>
<h3>MPD</h3>
FHEM module to control a MPD (or Mopidy) like the MPC (MPC = Music Player Command, the command line interface to the <a href='http://en.wikipedia.org/wiki/Music_Player_Daemon'>Music Player Daemon</a> )<br>
To install a MPD on a Raspberry Pi you will find a lot of documentation at the web e.g. http://www.forum-raspberrypi.de/Thread-tutorial-music-player-daemon-mpd-und-mpc-auf-dem-raspberry-pi in german<br>
@ -2239,8 +2276,8 @@ FHEM Forum : <a href='http://forum.fhem.de/index.php/topic,18517.0.html'>Modul f
Modul requires JSON -> sudo apt-get install libjson-perl <br>
If you are using Mopidy with Spotify support you may also need LWP::UserAgent -> sudo apt-get install libwww-perl<br>
<ul>
<a name="MPDdefine"></a>
<b>Define</b>
<a id="MPD-define"></a>
<h4>Define</h4>
<ul>
define &lt;name&gt; MPD &lt;IP MPD Server | default localhost&gt; &lt;Port MPD Server | default 6600&gt;<br>
Example:<br>
@ -2253,8 +2290,8 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
</pre>
</ul>
<br>
<a name="MPDset"></a>
<b>Set</b><ul>
<a id="MPD-set"></a>
<h4>Set</h4><ul>
<code>set &lt;name&gt; &lt;what&gt;</code>
<br>&nbsp;<br>
Currently, the following commands are defined.<br>
@ -2290,8 +2327,8 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
load_bookmark <name> => resumes the previously saved state of the currently loaded playlist and jumps to the associated tracknumber and position inside the track<br>
</ul>
<br>
<a name="MPDget"></a>
<b>Get</b><ul>
<a id="MPD-get"></a>
<h4>Get</h4><ul>
<code>get &lt;name&gt; &lt;what&gt;</code>
<br>&nbsp;<br>
Currently, the following commands are defined.<br>
@ -2309,41 +2346,63 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
bookmarks => list all stored bookmarks<br>
</ul>
<br>
<a name="MPDattr"></a>
<b>Attributes</b>
<a id="MPD-attr"></a>
<h4>Attributes</h4>
<ul>
<a id="MPD-attr-password"></a>
<li>password <pwd>, if password in mpd.conf is set</li>
<li>loadMusic 1|0 => load titles from MPD database at startup (not supported by modipy)</li>
<a id="MPD-attr-loadMusic"></a>
<li>loadMusic 1|0 => load titles from MPD database at startup (not supported by modipy, no longer recommended for activation!)</li>
<a id="MPD-attr-loadPlaylists"></a>
<li>loadPlaylists 1|0 => load playlist names from MPD database at startup</li>
<a id="MPD-attr-volumeStep"></a>
<li>volumeStep 1|2|5|10 => Step size for Volume +/- (default 5)</li>
<a id="MPD-attr-titleSplit"></a>
<li>titleSplit 1|0 => split title to artist and title if no artist is given in songinfo (e.g. radio-stream default 1)</li>
<a id="MPD-attr-timeout"></a>
<li>timeout (default 1) => timeout in seconds for TCP connection timeout</li>
<a id="MPD-attr-waits"></a>
<li>waits (default 60) => if idle process ends with error, seconds to wait</li>
<a id="MPD-attr-stateMusic"></a>
<li>stateMusic 1|0 => show Music DropDown box in web frontend</li>
<a id="MPD-attr-statePlaylists"></a>
<li>statePlaylists 1|0 => show Playlists DropDown box in web frontend</li>
<a id="MPD-attr-player"></a>
<li>player mpd|mopidy|forked-daapd => which player is controlled by the module</li>
<li>Cover Art functions from <a href="http://www.last.fm/"><b>Last.fm</b></a> :</li>
<a id="MPD-attr-image_size"></a>
<li>image_size -1|0|1|2|3 (default -1 = don't use artist images and album cover from Last.fm)<br>
Last.fm is using diffrent image sizes :<br>
0 = 32x32 , 1 = 64x64 , 2 = 174x174 , 3 = 300x300</li>
<a id="MPD-attr-artist_content"></a>
<li>artist_content 0|1 => store artist informations in Reading artist_content</li>
<li>artist_summary 0|1 => stote more artist informations in Reading artist_summary<br>
<a id="MPD-attr-artist_summary"></a>
<li>artist_summary 0|1 => store more artist informations in Reading artist_summary<br>
Example with readingsGroup :<br>
<pre>
define rg_artist readingsGroup &ltMPD name&gt:artist,artist_image_html,artist_summary
attr rg_artist room MPD
</pre></li>
<a id="MPD-attr-cache"></a>
<li>cache (default lfm => /fhem/www/lfm) store artist image and album cover in a local directory</li>
<a id="MPD-attr-unknown_artist_image"></a>
<li>unknown_artist_image => show this image if no other image is avalible (default : /fhem/icons/1px-spacer)</li>
<a id="MPD-attr-bookmarkDir"></a>
<li>bookmarkDir => set a writeable directory here to enable saving and restoring of playlist states using the set bookmark and get bookmark commands</li>
<a id="MPD-attr-autoBookmark"></a>
<li>autoBookmark => set this to 1 to enable automatic loading and saving of playlist states whenever the playlist is changed using this module</li>
<a id="MPD-attr-seekStep"></a>
<li>seekStep => set this to define how far the forward and rewind commands jump in the current track. Defaults to 7 if not set</li>
<a id="MPD-attr-seekStepSmall"></a>
<li>seekStepSmall (default 1) => set this on top of seekStep to define a smaller step size, if the current playing position is below seekStepThreshold percent. This is useful to skip intro music, e.g. in radio plays or audiobooks.</li>
<a id="MPD-attr-seekStepSmallThreshold"></a>
<li>seekStepSmallThreshold (default 0) => used to define when seekStep or seekStepSmall is applied. Defaults to 0. If set e.g. to 10, then during the first 10% of a track, forward and rewind are using the seekStepSmall value.</li>
<a id="MPD-attr-no_playlistcollection"></a>
<li>no_playlistcollection (default 0) => if set to 1 , dont create reading playlistcollection</li>
</ul>
<br>
<b>Readings</b>
<a id="MPD-readings"></a>
<h4>Readings</h4>
<ul>
all MPD internal values<br>
artist_image : (if using Last.fm)<br>
@ -2365,7 +2424,7 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
=begin html_DE
<a name="MPD"></a>
<a id="MPD"></a>
<h3>MPD</h3>
<ul>
FHEM Modul zur Steuerung des MPD (oder Mopidy) &auml;hnlich dem MPC (MPC = Music Player Command, das Kommando Zeilen Interface f&uuml;r den
@ -2374,8 +2433,8 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
z.B. <a href="http://www.forum-raspberrypi.de/Thread-tutorial-music-player-daemon-mpd-und-mpc-auf-dem-raspberry-pi"><b>hier</b></a><br>
Thread im FHEM Forum : <a href='http://forum.fhem.de/index.php/topic,18517.0.html'>Modul f&uuml;r MPD</a><br>
Das Modul ben&ouml;tigt zwingend JSON, installation z.B. mit <i>sudo apt-get install libjson-perl</i><br>
<a name="MPDdefine"></a>
<b>Define</b>
<a id="MPD-define"></a>
<h4>Define</h4>
<ul>
define &lt;name&gt; MPD &lt;IP MPD Server | default localhost&gt; &lt;Port MPD Server | default 6600&gt;<br>
Beispiel :<br>
@ -2389,8 +2448,8 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
</ul>
</ul>
<br>
<a name="MPDset"></a>
<b>Set</b><ul>
<a id="MPD-set"></a>
<h4>Set</h4><ul>
<code>set &lt;name&gt; &lt;was&gt;</code>
<br>&nbsp;<br>
z.Z. unterst&uuml;tzte Kommandos<br>
@ -2428,8 +2487,8 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
wird <name> zusätzlich mit übergeben wird zuvor die entsprechend Playliste geladen<br>
</ul>
<br>
<a name="MPDget"></a>
<b>Get</b><ul>
<a id="MPD-get"></a>
<h4>Get</h4><ul>
<code>get &lt;name&gt; &lt;was&gt;</code>
<br>&nbsp;<br>
z.Z. unterst&uuml;tzte Kommandos<br>
@ -2447,48 +2506,70 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
bookmarks => zeigt eine Liste aller bisher gespeicherten Bookmarks<br>
</ul>
<br>
<a name="MPDattr"></a>
<b>Attribute</b>
<a id="MPD-attr"></a>
<h4>Attribute</h4>
<ul>
<a id="MPD-attr-password"></a>
<li>password <pwd> => Password falls in der mpd.conf definiert</li>
<li>loadMusic 1|0 => lade die MPD Titel beim FHEM Start : mpd.conf - music_directory</li>
<a id="MPD-attr-loadMusic"></a>
<li>loadMusic 1|0 => lade die MPD Titel beim FHEM Start : mpd.conf - music_directory. Achtung: funktioniert nicht mit modipy und ist allgemein nicht mehr zu empfehlen!</li>
<a id="MPD-attr-loadPlaylists"></a>
<li>loadPlaylists 1|0 => lade die MPD Playlisten beim FHEM Start : mpd.conf - playlist_directory</li>
<a id="MPD-attr-volumeStep"></a>
<li>volumeStep x => Schrittweite f&uuml;r Volume +/-</li>
<a id="MPD-attr-titleSplit"></a>
<li>titleSplit 1|0 => zerlegt die aktuelle Titelangabe am ersten Vorkommen von - (BlankMinusBlank) in die zwei Felder Artist und Titel,<br>
wenn im abgespielten Titel die Interpreten Information nicht verf&uuml;gbar ist (sehr oft bei Radio-Streams default 1)<br>
Liegen keine Titelangaben vor wird die Ausgabe durch den Namen der Radiostation ersetzt</li>
<a id="MPD-attr-timeout"></a>
<li>timeout (default 1) => Timeoutwert in Sekunden für die Verbindung fhem-mpd</li>
<a id="MPD-attr-waits"></a>
<li>waits (default 60) => &Uuml;berwachungszeit in Sekunden f&uuml;r den Idle Prozess. In Verbindung mit refresh_song der Aktualisierungs Intervall für die aktuellen Songparamter,<br>
(z.B. um den Fortschrittsbalken bei TabletUI aktuell zu halten) </li>
<a id="MPD-attr-stateMusic"></a>
<li>stateMusic 1|0 => zeige Musikliste als DropDown im Webfrontend</li>
<a id="MPD-attr-statePlaylists"></a>
<li>statePlaylists 1|0 => zeige Playlisten als DropDown im Webfrontend</li>
<a id="MPD-attr-player"></a>
<li>player mpd|mopidy|forked-daapd (default mpd) => welcher Player wird gesteuert<br>
<b>ACHTUNG</b> : Mopidy unterst&uuml;tzt nicht alle Kommandos des echten MPD ! (siehe <a href="https://docs.mopidy.com/en/latest/ext/mpd/">Mopidy Dokumentation</a>)</li>
<li>Cover Art Funktionen von <a href="http://www.last.fm/"><b>last.fm</b></a> :</li>
<a id="MPD-attr-image_size"></a>
<li>image_size -1|0|1|2|3 (default -1 = keine Interpretenbilder und Infos von last.fm verwenden)<br>
last.fm stellt verschiedene Bildgroessen zur Verfügung :<br>
0 = 32x32 , 1 = 64x64 , 2 = 174x174 , 3 = 300x300</li>
<a id="MPD-attr-artist_content"></a>
<li>artist_content 0|1 => stellt Interpreteninformation im Reading artist_content zur Verf&uuml;gung</li>
<a id="MPD-attr-artist_summary"></a>
<li>artist_summary 0|1 => stellt weitere Interpreteninformation im Reading artist_summary zur Verf&uuml;gung<br>
Beispiel Anzeige mittels readingsGroup :<br>
<pre>
define rg_artist readingsGroup &ltMPD name&gt:artist,artist_image_html,artist_summary
attr rg_artist room MPD
</pre></li>
<a id="MPD-attr-cache"></a>
<li>cache (default lfm => /fhem/www/lfm) Zwischenspeicher für die JSON und PNG Dateien<br>
<b>Wichtig</b> : Der User unter dem der fhem Prozess ausgef&uuml;hrt wird (default fhem) muss Lese und Schreibrechte in diesem Verzeichniss haben !<br>
Das Verzeichnis sollte auch unterhalb von www liegen, damit der fhem Webserver direkten Zugriff auf die Bilder hat.</li>
<a id="MPD-attr-unknown_artist_image"></a>
<li>unknown_artist_image => Ersatzimage wenn kein anderes Image zur Verf&uuml;gung steht (default : /fhem/icons/1px-spacer)</li>
<a id="MPD-attr-bookmarkDir"></a>
<li>bookmarkDir => ein vom FHEM User les- und beschreibbares Verzeichnis. Wennn dieses definiert wird, ist das Speichern und Wiederherstellen von Playlistzust&auml;nden mit Hilfe von set/get bookmark m&ouml;glich</li>
<a id="MPD-attr-autoBookmark"></a>
<li>autoBookmark => wenn dies auf 1 gesetzt wird, dann werden automatisch Playlistenzust&auml;nde geladen und gespeichert, immer wenn die Playliste mit diesem Modul gewechselt wird</li>
<a id="MPD-attr-seekStep"></a>
<li>seekStep => wenn definiert, wird dadurch die Sprungweite von forward und rewind gesetzt. Der Wert gilt als Prozentwert. default: 7</li>
<a id="MPD-attr-seekStepSmall"></a>
<li>seekStepSmall => Wenn diesem Attribut kann für den Anfang eines Tracks innerhalb der ersten per seekStepSmall definierten Prozent eine kleinere Sprungweite definiert werden,<br>
um so z.B. die Intromusik von H&ouml;rspielen oder H&ouml;rb&uuml;chern &uuml;berspringen zu k&ouml;nnen. default: 1</li>
<a id="MPD-attr-seekStepSmallThreshold"></a>
<li>seekStepSmallThreshold => unterhalb dieses Wertes wird seekStepSmall benutzt, oberhalb seekStep default: 0 (ohne Funktion)</li>
<a id="MPD-attr-no_playlistcollection"></a>
<li>no_playlistcollection (default 0) => wenn auf 1 gesetzt wird das Reading playlistcollection nicht erzeugt</li>
</ul>
<br>
<b>Readings</b>
<a id="MPD-readings"></a>
<h4>Readings</h4>
<ul>
- alle MPD internen Werte<br>
- vom Modul direkt erzeugte Readings :<br>
@ -2515,6 +2596,3 @@ If you are using Mopidy with Spotify support you may also need LWP::UserAgent ->
=cut

View File

@ -399,7 +399,7 @@ FHEM/73_ElectricityCalculator.pm Sailor Unterstützende Dienste https:
FHEM/73_GardenaSmartBridge.pm CoolTux Sonstige Systeme
FHEM/73_GasCalculator Sailor Unterstützende Dienste https://forum.fhem.de/index.php/topic,47909.0.html
FHEM/73_km200.pm Sailor Heizungssteuerung/Raumklima https://forum.fhem.de/index.php/topic,25540.0.html
FHEM/73_MPD.pm Wzut Multimedia
FHEM/73_MPD.pm Wzut/Beta-User Multimedia
FHEM/73_NUKIBridge.pm CoolTux Sonstige Systeme
FHEM/73_PRESENCE.pm JoWiemann Unterstützende Dienste
FHEM/73_WaterCalculator Sailor Unterstützende Dienste https://forum.fhem.de/index.php/topic,58579.0.html