From e766fd9bdc086066576ebb7b4e4aa3032d1271d8 Mon Sep 17 00:00:00 2001 From: Otto123 Date: Wed, 3 Mar 2021 09:19:25 +0000 Subject: [PATCH] 99_sonos2mqttUtils:bugfixes and subroutines for userReadings git-svn-id: https://svn.fhem.de/fhem/trunk@23883 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- .../AttrTemplate/99_sonos2mqttUtils.pm | 86 ++++++++++++++++--- 1 file changed, 72 insertions(+), 14 deletions(-) diff --git a/fhem/contrib/AttrTemplate/99_sonos2mqttUtils.pm b/fhem/contrib/AttrTemplate/99_sonos2mqttUtils.pm index 7603cf32d..18caa3ed3 100644 --- a/fhem/contrib/AttrTemplate/99_sonos2mqttUtils.pm +++ b/fhem/contrib/AttrTemplate/99_sonos2mqttUtils.pm @@ -40,7 +40,7 @@ if ($NAME eq $bridge){ if($cmd eq 'Favorites') {return "$devicetopic/".ReadingsVal((devspec2array('a:model=sonos2mqtt_speaker'))[0],'uuid','').q(/control {"command": "adv-command","input": {"cmd": "GetFavorites","reply": "Favorites"}})} if($cmd eq 'setplayFav') {sonos2mqtt_mod_list('a:model=sonos2mqtt_speaker','setList','playFav:'.ReadingsVal($NAME,'favlist','').' {sonos2mqtt($NAME,$EVENT)}')} if($cmd eq 'setjoinGroup') {sonos2mqtt_mod_list('a:model=sonos2mqtt_speaker','setList','joinGroup:'.ReadingsVal($NAME,'grouplist','').' {sonos2mqtt($NAME,$EVENT)}')} - return undef + return '' } # from here cmds for speaker if($cmd eq 'sayText') { ($cmd,$text) = split(' ', $EVENT,2)} @@ -49,6 +49,12 @@ my $topic = "$devicetopic/$uuid/control"; my $payload = $EVENT; if (@arr == 1){$payload = "leer"} else {$payload =~ s/$cmd //} +# if Radio next Station +my $Input = ReadingsVal($NAME,'Input',''); +if($cmd eq 'next' and $Input eq 'Radio') { + fhem("set $NAME playFav {(Each('$bridge',ReadingsVal('$bridge','favlist','')))}"); + return '' +} my @easycmd = ('stop','play','pause','toggle','volumeUp','volumeDown','next','previous'); if (grep { $_ eq $cmd } @easycmd) {return lc( qq($topic { "command": "$cmd" }) )} @@ -101,8 +107,8 @@ if($cmd eq 'sleep') { } if($cmd eq 'test') {Log 1, "Das Device $NAME hat ausgeloest, die uuid ist >$uuid< der Befehl war >$cmd< der Teil danach sah so aus: $payload"} if($cmd eq 'x_raw_payload') {return qq($topic $payload)} -# if return for other reasons, the response had to be undef -return undef; +# if return for other reasons, the response had to be '' 0 or undef +return ''; } ####### devStateIcon sub sonos2mqtt_devStateIcon @@ -138,7 +144,7 @@ if ($isMaster and $mystate eq 'PLAYING') {$line2 = $Input =~ /LineIn|TV/ ? $Inpu elsif ($inGroup and !$isMaster or $inCouple) {$line2 .= $inCouple ? "Stereopaar":"Steuerung: $master"} my $style = 'display:inline-block;margin-right:5px;border:1px solid lightgray;height:4.00em;width:4.00em;background-size:contain;background-image:'; my $style2 ='background-repeat: no-repeat; background-size: contain; background-position: center center'; -"
+return "
@@ -155,11 +161,13 @@ my @devlist = devspec2array($devspec); my ($first,$sec)=split(':',$item,2); $first=~s/^\s+//; for (@devlist) { - my @arr = grep {$_ !~ $first} split("\n",AttrVal($_,$attr,'')); + my @arr = grep {$_ !~ /\Q$first\E/} split("\n",AttrVal($_,$attr,'')); # grep searches exactly for the string between \Q...\E push @arr,$item; my $val = join "\n",sort @arr; $val =~ s/;/;;/g; - fhem("attr $_ $attr $val")} + fhem("attr $_ $attr $val") + } +return '' } #### Setup some additional features in speaker and bridge @@ -167,6 +175,15 @@ sub sonos2mqtt_setup { my $devspec = shift @_ // 'a:model=sonos2mqtt_speaker'; my $bridge = (devspec2array('a:model=sonos2mqtt_bridge'))[0]; + +if ($devspec eq 'a:model=sonos2mqtt_bridge'){ + sonos2mqtt_mod_list($devspec,'setList','notifyall:textField'.q( {sonos2mqtt($NAME,$EVENT)})); + sonos2mqtt_mod_list($devspec,'setList','announcementall:textField'.q( {sonos2mqtt($NAME,$EVENT)})); + sonos2mqtt_mod_list($devspec,'readingList',AttrVal($bridge,"devicetopic",'sonos').'/RINCON_([0-9A-Z]+)/Favorites:.* Favorites'); + sonos2mqtt_mod_list($devspec,'readingList',AttrVal($bridge,"devicetopic",'sonos').'/RINCON_([0-9A-Z]+)/Reply:.* Reply'); + return undef +} + fhem("attr $devspec".q( devStateIcon {sonos2mqtt($name,'devStateIcon')})); for ('stop:noArg','play:noArg','pause:noArg','toggle:noArg','volume:slider,0,1,100','volumeUp:noArg','volumeDown:noArg', 'mute:true,false','next:noArg','previous:noArg','leaveGroup:noArg','setAVTUri:textField','playUri:textField', @@ -181,11 +198,12 @@ if (!ReadingsVal($bridge,'favlist',0)) {my $fav = fhem("get $bridge Favorites")} for (devspec2array($devspec)) { my $mn = ReadingsVal($_,'modelNumber',''); fhem("set $_ volume ".ReadingsVal($_,'volume','10')); # trick to initiate the userReadings - if (grep(/$mn/, @tv)) {sonos2mqtt_mod_list($_,'setList','input:Queue,TV'.q( {sonos2mqtt($NAME,$EVENT)}))} - if (grep(/$mn/, @line)) {sonos2mqtt_mod_list($_,'setList','input:Queue,Line_In'.q( {sonos2mqtt($NAME,$EVENT)}))} + if (grep {/$mn/} @tv) {sonos2mqtt_mod_list($_,'setList','input:Queue,TV'.q( {sonos2mqtt($NAME,$EVENT)}))} + if (grep {/$mn/} @line) {sonos2mqtt_mod_list($_,'setList','input:Queue,Line_In'.q( {sonos2mqtt($NAME,$EVENT)}))} sonos2mqtt_mod_list($_,'setList','joinGroup:'.ReadingsVal($bridge,'grouplist','').q( {sonos2mqtt($NAME,$EVENT)})); sonos2mqtt_mod_list($_,'setList','playFav:'.ReadingsVal($bridge,'favlist','').q( {sonos2mqtt($NAME,$EVENT)})); } +return '' } #### code for notify for two different triggers: defined and IPAddress is responded @@ -211,15 +229,55 @@ if ($NAME eq 'global'){ fhem("attr $NAME icon $icon;sleep 4 WI;set WEB rereadicons"); sonos2mqtt_setup($NAME); } +return '' } -# could be removed later only for temporary compatibitility -# setplayFav, setjoinGroup not working well from inside setList Bridge -# from commandline could used like {sonos2mqtt_bridge('SonosBridge','setplayFav')} -# joinGroup does'nt working with spaces in "Player Rooms" -sub sonos2mqtt_bridge +#### sub for userReadings +# +sub sonos2mqtt_ur { -sonos2mqtt(@_); +my $name = shift @_ // 'name'; +my $reading = shift @_ // 'reading'; +my @out; + +if ($reading eq 'grouplist'){ + for (devspec2array('a:model=sonos2mqtt_speaker')) { + if (ReadingsVal($_,'isMaster','')) { + push @out,ReadingsVal($_,'name','') + } + } + return join(',', sort @out) +} +if ($reading eq 'favlist'){ + use JSON; + use HTML::Entities; + use Encode qw(encode decode); + my $enc = 'UTF8'; + my $decoded = decode_json(ReadingsVal($name,'Favorites','')); + my @arr = @{$decoded->{'Result'}}; + for (@arr) { + my $dec = encode($enc, decode_entities($_->{'Title'})); + $dec =~ s/\s/./g; + if ($_->{'TrackUri'} =~ /x-sonosapi-stream/) {push @out,$dec} + } + return join ',', sort @out +} + +if ($reading eq 'Input') { + my $currentTrack_TrackUri = ReadingsVal($name,'currentTrack_TrackUri',''); + return $currentTrack_TrackUri =~ 'x-rincon-stream' + ? 'LineIn': $currentTrack_TrackUri =~ 'spdif' + ? 'TV' : ReadingsVal($name,'enqueuedMetadata_UpnpClass','') eq 'object.item.audioItem.audioBroadcast' + ? 'Radio' : 'Playlist' + } } 1; +=pod +=begin html +Some Subroutines for generic MQTT2 Sonos Devices based on sonos2mqtt. +=end html +=begin html_DE +Enthaelt einige Subroutinen fuer generische MQTT2 Sonos Geraete auf Basis von sonos2mqtt. +=end html_DE +=cut
$linePic
$line2