2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-08 13:24:56 +00:00

37_plex.pm: added first support for remote clients, fixed embeded images, fixed utf8 encoding

git-svn-id: https://svn.fhem.de/fhem/trunk@12576 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
justme-1968 2016-11-14 21:04:44 +00:00
parent d83a9b5257
commit 657e8fb13b

View File

@ -13,6 +13,9 @@ use Sys::Hostname;
use IO::Socket::INET;
#use Net::Address::IP::Local;
#use MIME::Base64;
use JSON;
use Encode qw(encode);
use XML::Simple qw(:strict);
@ -45,7 +48,7 @@ plex_Initialize($)
$hash->{GetFn} = "plex_Get";
$hash->{AttrFn} = "plex_Attr";
$hash->{AttrList} = "disable:1,0"
. " httpPort ignoredClients ignoredServers"
. " fhemIP httpPort ignoredClients ignoredServers"
. " removeUnusedReadings:1,0 responder:1,0"
. " user password "
. $readingFnAttributes;
@ -137,8 +140,8 @@ plex_Define($$)
plex_sendApiCmd( $hash, "http://$hash->{server}:$hash->{port}/servers", "servers" ) if( $hash->{server} );
} elsif( $hash->{STATE} ne "???" ) {
$hash->{STATE} = "Initialized";
} else {
readingsSingleUpdate($hash, 'state', 'initialized', 1 );
}
@ -407,6 +410,7 @@ plex_startDiscovery($)
#}
}
readingsSingleUpdate($hash, 'state', 'running', 1 );
}
sub
plex_stopDiscovery($)
@ -755,7 +759,7 @@ plex_startTimelineListener($)
plex_refreshSubscriptions($chash);
} else {
Log3 $name, 3, "$name: failed to start timeline listener started: $@";
Log3 $name, 3, "$name: failed to start timeline listener on port $port $@";
InternalTimer(gettimeofday()+10, "plex_startTimelineListener", $hash, 0);
}
@ -796,6 +800,7 @@ plex_Undefine($$)
my ($hash, $arg) = @_;
plex_stopTimelineListener($hash);
plex_stopWebsockets($hash);
plex_stopDiscovery($hash);
delete $modules{plex}{defptr}{MASTER} if( $modules{plex}{defptr}{MASTER} == $hash ) ;
@ -1222,6 +1227,22 @@ plex_makeLink($$$$;$)
return "<a style=\"cursor:pointer\" onClick=\"FW_cmd(\\\'$FW_ME$FW_subdir?XHR=1&cmd=$cmd\\\')\">$txt</a>";
}
sub
plex_makeImage($$$$)
{
my ($hash, $server, $url, $size) = @_;
return '' if( !$url );
my $token = $server->{accessToken};
$token = $hash->{token} if( !$token );
my $ret .= "<img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?X-Plex-Token=$token&url=".
urlEncode("127.0.0.1:32400$url?X-Plex-Token=$token")
."&width=$size&height=$size\">\n";
return $ret;
}
sub
@ -1248,7 +1269,7 @@ plex_mediaList2($$$$)
$ret .= sprintf( "%-35s %-10s %s\n", 'key', 'type', 'title' );
foreach my $item (@{$items}) {
$item->{type} = '' if( !$item->{type} );
$item->{title} = encode('UTF-8', $item->{title});
$ret .= plex_makeLink($hash, 'ls', $xml->{parentSection}, $item->{key}, sprintf( "%-35s %-10s %s", $item->{key}, $item->{type}, $item->{title} ) );
$ret .= " ($item->{year})" if( $item->{year} );
$ret .= "\n";
@ -1262,8 +1283,9 @@ plex_mediaList2($$$$)
$ret .= sprintf( "%-35s %-10s %s\n", 'key', 'type', 'title' );
foreach my $item (@{$items}) {
$item->{type} = '' if( !$item->{type} );
$item->{title} = encode('UTF-8', $item->{title});
$ret .= plex_makeLink($hash, 'ls', $xml->{parentSection}, $item->{key}, sprintf( "%-35s %-10s %s\n", $item->{key}, $item->{type}, $item->{title} ) );
#$ret .= " <img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?url=". urlEncode("127.0.0.1:32400$item->{composite}") ."&width=100&height=100\">\n" if( $item->{composite} );
#$ret .= plex_makeImage($hash, $server, $xml->{composite}, 100);
}
}
@ -1273,6 +1295,7 @@ plex_mediaList2($$$$)
$ret .= "$type\n";
$ret .= sprintf( "%-35s %-10s nr %s\n", 'key', 'type', 'title' );
foreach my $item (@{$items}) {
$item->{title} = encode('UTF-8', $item->{title});
if( defined($item->{index}) ) {
$ret .= plex_makeLink($hash, 'detail', $xml->{parentSection}, $item->{key}, sprintf( "%-35s %-10s %3i %s", $item->{key}, $item->{type}, $item->{index}, $item->{title} ) );
$ret .= plex_makeLink($hash,'detail', undef, $item->{grandparentKey}, " ($item->{grandparentTitle}" ) if( $item->{grandparentTitle} );
@ -1292,6 +1315,7 @@ plex_mediaList2($$$$)
$ret .= "$type\n";
$ret .= sprintf( "%-35s %-10s nr %s\n", 'key', 'type', 'title' );
foreach my $item (@{$items}) {
$item->{title} = encode('UTF-8', $item->{title});
$ret .= sprintf( "%-35s %-10s %3i %s\n", $item->{key}, $item->{type}, $item->{index}, $item->{title} );
}
}
@ -1307,9 +1331,19 @@ plex_mediaList($$$)
#Log 1, Dumper $xml;
return $xml if( ref($xml) ne 'HASH' );
my $token = $server->{accessToken};
$token = $hash->{token} if( !$token );
$xml->{librarySectionTitle} = encode('UTF-8', $xml->{librarySectionTitle}) if( $xml->{librarySectionTitle} );
$xml->{title} = encode('UTF-8', $xml->{title}) if( $xml->{title} );
$xml->{title1} = encode('UTF-8', $xml->{title1}) if( $xml->{title1} );
$xml->{title2} = encode('UTF-8', $xml->{title2}) if( $xml->{title2} );
$xml->{title3} = encode('UTF-8', $xml->{title3}) if( $xml->{title3} );
my $ret = '';
$ret .= "<img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?url=". urlEncode("127.0.0.1:32400$xml->{thumb}") ."&width=100&height=100\">\n" if( $xml->{thumb} );
$ret .= "<img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?url=". urlEncode("127.0.0.1:32400$xml->{composite}") ."&width=100&height=100\">\n" if( $xml->{composite} );
$ret .= plex_makeImage($hash, $server, $xml->{thumb}, 100);
$ret .= plex_makeImage($hash, $server, $xml->{composite}, 100);
$ret .= "$xml->{librarySectionTitle}: " if( $xml->{librarySectionTitle} );
$ret .= plex_makeLink($hash, 'detail', undef, $xml->{ratingKey}, "$xml->{title} ") if( $xml->{title} );
$ret .= plex_makeLink($hash, 'detail', undef, $xml->{grandparentRatingKey}, "$xml->{title1} ") if( $xml->{title1} );
@ -1335,6 +1369,10 @@ sub
plex_mediaDetail2($$$$)
{
my ($hash, $server, $xml, $items) = @_;
my $token = $server->{accessToken};
$token = $hash->{token} if( !$token );
#Log 1, Dumper $xml;
if( $items ) {
@ -1345,13 +1383,20 @@ plex_mediaDetail2($$$$)
}
}
$xml->{viewGroup} = encode('UTF-8', $xml->{viewGroup}) if( $xml->{viewGroup} );
my $ret = '';
foreach my $item (@{$items}) {
$item->{grandparentTitle} = encode('UTF-8', $item->{grandparentTitle}) if( $item->{grandparentTitle} );
$item->{parentTitle} = encode('UTF-8', $item->{parentTitle}) if( $item->{parentTitle} );
$item->{title} = encode('UTF-8', $item->{title}) if( $item->{title} );
$item->{summary} = encode('UTF-8', $item->{summary}) if( $item->{summary} );
$ret .= "\n" if( $ret && (!$xml->{viewGroup} || ($xml->{viewGroup} ne 'track' && $xml->{viewGroup} ne 'secondary') ) );
if( $item->{type} eq 'playlist' ) {
$ret .= sprintf( "%s ", $item->{title} ) if( $item->{title} );
$ret .= "\n";
$ret .= "<img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?url=". urlEncode("127.0.0.1:32400$item->{composite}") ."&width=250&height=250\">" if( $item->{composite} );
$ret .= plex_makeImage($hash, $server, $item->{composite}, 250);
$ret .= "\n";
$ret .= sprintf( "%s ", $item->{playlistType} ) if( $item->{playlistType} );
$ret .= sprintf( "%s ", plex_timestamp2date($item->{addedAt}) ) if( $item->{addedAt} );
@ -1366,7 +1411,7 @@ plex_mediaDetail2($$$$)
$ret .= sprintf("(S%02iE%02i)",$item->{parentIndex}, $item->{index} ) if( $item->{parentIndex} && $item->{type} ne 'season' );
#$ret .= sprintf("(S%02i)", $item->{index} ) if( $item->{index} && $item->{type} eq 'season' );
$ret .= "\n";
$ret .= "<img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?url=". urlEncode("127.0.0.1:32400$item->{thumb}") ."&width=250&height=250\">" if( $item->{thumb} );
$ret .= plex_makeImage($hash, $server, $item->{thumb}, 250);
$ret .= "\n";
if( $item->{Genre} ) {
foreach my $genre ( @{$item->{Genre}}) {
@ -1392,7 +1437,7 @@ plex_mediaDetail2($$$$)
$ret .= sprintf( "%s ", $item->{title} ) if( $item->{title} );
#$ret .= "\n";
$ret .= "\n";
$ret .= "<img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?url=". urlEncode("127.0.0.1:32400$item->{thumb}") ."&width=250&height=250\">" if( !$xml->{thumb} && $item->{thumb} );
$ret .= plex_makeImage($hash, $server, $item->{thumb}, 250);
#$ret .= "\n";
$ret .= sprintf( "%s ", $item->{contentRating} ) if( $item->{contentRating} );
$ret .= sprintf( "%i ", $item->{year} ) if( $item->{year} );
@ -1409,7 +1454,7 @@ plex_mediaDetail2($$$$)
$ret .= " ";
$ret .= plex_sec2hms($item->{duration}/1000);
$ret .= "\n";
$ret .= "<img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?url=". urlEncode("127.0.0.1:32400$item->{thumb}") ."&width=250&height=250\">" if( $item->{thumb} );
$ret .= plex_makeImage($hash, $server, $item->{thumb}, 250);
$ret .= "\n";
$ret .= sprintf( "%s ", $item->{contentRating} ) if( $item->{contentRating} );
$ret .= sprintf( "%s ", $item->{rating} ) if( $item->{rating} );
@ -1456,9 +1501,17 @@ plex_mediaDetail($$$)
return $xml if( ref($xml) ne 'HASH' );
my $token = $server->{accessToken};
$token = $hash->{token} if( !$token );
$xml->{title} = encode('UTF-8', $xml->{title}) if( $xml->{title} );
$xml->{title1} = encode('UTF-8', $xml->{title1}) if( $xml->{title1} );
$xml->{title2} = encode('UTF-8', $xml->{title2}) if( $xml->{title2} );
$xml->{summary} = encode('UTF-8', $xml->{summary}) if( $xml->{summary} );
#Log 1, Dumper $xml;
my $ret = '';
$ret .= "<img src=\"http://$server->{address}:$server->{port}/photo/:/transcode?url=". urlEncode("127.0.0.1:32400$xml->{thumb}") ."&width=250&height=250\">\n" if( $xml->{thumb} );
$ret .= plex_makeImage($hash, $server, $xml->{thumb}, 250);
$ret .= plex_makeLink($hash, 'detail', undef, $xml->{ratingKey}, "$xml->{title} ") if( $xml->{title} );
$ret .= sprintf( "%s: ", $xml->{title1} ) if( $xml->{title1} );
$ret .= sprintf( "%s: ", $xml->{title2} ) if( $xml->{title2} );
@ -1564,6 +1617,11 @@ plex_Get($$@)
return undef if( !$xml );
return Dumper $xml;
} elsif( $cmd eq 'identity' ) {
my $xml = plex_sendApiCmd( $hash, "http://$ip:$entry->{port}/identity", 'identity', 1 );
return undef if( !$xml );
return Dumper $xml;
} elsif( $cmd eq 'detail' ) {
return "usage: detail <key>" if( !$param );
my $ret = plex_sendApiCmd( $hash, "http://$ip:$entry->{port}$param", 'detail', $hash->{CL} || 1 );
@ -1598,7 +1656,7 @@ plex_Get($$@)
}
$list .= 'ls search sessions:noArg detail onDeck:noArg recentlyAdded:noArg playlists:noArg ';
$list .= 'identity:noArg ls search sessions:noArg detail onDeck:noArg recentlyAdded:noArg playlists:noArg ';
$list .= 'servers:noArg pin:noArg ' if( $list !~ m/\bservers\b/ );
}
@ -1694,11 +1752,14 @@ plex_Attr($$$)
if( $attrName eq 'disable' ) {
if( $cmd eq "set" && $attrVal ) {
plex_stopTimelineListener($hash);
plex_stopWebsockets($hash);
plex_stopDiscovery($hash);
foreach my $ip ( keys %{$hash->{clients}} ) {
$hash->{clients}{$ip}{online} = 0;
}
readingsSingleUpdate($hash, 'state', 'disabled', 1 );
} else {
readingsSingleUpdate($hash, 'state', 'running', 1 );
$attr{$name}{$attrName} = 0;
plex_startDiscovery($hash);
plex_startTimelineListener($hash);
@ -1737,7 +1798,13 @@ plex_Attr($$$)
delete $hash->{token};
plex_getToken($hash);
}
}
} elsif( $attrName eq 'fhemIP' ) {
if( $cmd eq "set" && $attrVal ) {
$hash->{fhemIP} = $attrVal;
} else {
$hash->{fhemIP} = plex_getLocalIP();
}
}
@ -2115,6 +2182,7 @@ plex_entryOfIP($$$)
$hash->{$type.'s'} = {} if( !$hash->{$type.'s'} );
my $entries = $hash->{$type.'s'};
foreach my $key ( keys %{$entries} ) {
return $entries->{$key} if( $entries->{$key}{address} eq $ip );
}
@ -2144,9 +2212,9 @@ plex_serverOf($$;$)
my $entry;
$entry = plex_entryOfID($hash, 'server', $hash->{currentServer} ) if( $hash->{currentServer} );
$entry = plex_entryOfIP($hash, 'server', $server) if( $server =~ m/^\d+\.\d+\.\d+\.\d+$/ );
$entry = plex_entryOfIP($hash, 'server', $server) if( $server && $server =~ m/^\d+\.\d+\.\d+\.\d+$/ );
$entry = plex_entryOfID($hash, 'server', $server) if( !$entry );
$entry = plex_entryOfID($hash, 'server', $server) if( $server && !$entry );
$entry = plex_entryOfIP($hash, 'server', $hash->{server} ) if( !$entry );
@ -2319,6 +2387,8 @@ plex_discovered($$$$)
plex_sendApiCmd( $hash, "http://$ip:$entry->{port}/clients", "clients" );
}
plex_requestNotifications( $hash, $entry );
} elsif( $type eq 'client' ) {
Log3 $name, 3, "$name: $type discovered: $ip" if( $new );
@ -2390,6 +2460,76 @@ plex_disappeared($$$)
}
}
sub
plex_requestNotifications($$)
{
my ($hash,$server) = @_;
my $name = $hash->{NAME};
return if( $hash->{helper}{websockets}{$server->{machineIdentifier}} );
if( my $socket = IO::Socket::INET->new(PeerAddr=>"$server->{address}:$server->{port}", Timeout=>2, Blocking=>1, ReuseAddr=>1, ReusePort=>defined(&ReusePort)?1:0) ) {
my $chash = plex_newChash( $hash, $socket,
{NAME=>"$name:websocket:$server->{machineIdentifier}", STATE=>'listening', websocket=>0} );
$chash->{address} = $server->{address};
$chash->{machineIdentifier} = $server->{machineIdentifier};
Log3 $name, 3, "$name: notification websocket opened to $server->{address}";
$hash->{helper}{websockets}{$server->{machineIdentifier}} = $chash;
my $ret = "GET /:/websockets/notifications HTTP/1.1\r\n";
$ret .= plex_hash2header( { 'Host' => "$server->{address}:$server->{port}",
'X-Plex-Token' => $hash->{token},
'Upgrade' => 'websocket',
'Connection' => 'Upgrade',
'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Sec-WebSocket-Key' => 'RkhFTQ==',
'Sec-WebSocket-Version' => '13',
} );
$ret .= "\r\n";
#Log 1, $ret;
syswrite($chash->{CD}, $ret );
} else {
Log3 $name, 2, "$name: failed to open notification websocket to $server->{address}";
}
}
sub
plex_closeNotifications($)
{
my ($hash,$server) = @_;
my $name = $hash->{NAME};
}
sub
plex_stopWebsockets($)
{
my ($hash,$server) = @_;
my $name = $hash->{NAME};
return if( !$hash->{helper}{websockets} );
foreach my $key ( keys %{$hash->{helper}{websockets}} ) {
my $chash = $hash->{helper}{websockets}{$key};
my $cname = $chash->{NAME};
plex_closeSocket($chash);
delete($hash->{servers}{$chash->{address}}{sessions});
delete($hash->{helper}{websockets}{$key});
delete($defs{$cname});
}
Log3 $name, 3, "$name: websockets stoped";
}
sub
plex_readingsBulkUpdateIfChanged($$$)
{
@ -2438,15 +2578,16 @@ plex_parseTimeline($$$)
foreach my $entry (@{$xml->{Timeline}}) {
next if( !$entry->{state} );
if( $entry->{key} && $entry->{key} ne ReadingsVal($chash->{NAME}, 'key', '') ) {
my $key = $entry->{key};
if( $key && $key ne ReadingsVal($chash->{NAME}, 'key', '') ) {
$chash->{currentServer} = $entry->{machineIdentifier};
readingsBulkUpdate($chash, 'key', $entry->{key} );
readingsBulkUpdate($chash, 'key', $key );
readingsBulkUpdate($chash, 'server', $entry->{machineIdentifier} );
my $server = plex_entryOfID($hash, 'server', $entry->{machineIdentifier} );
$server = $entry if( !$server );
plex_sendApiCmd( $hash, "http://$server->{address}:$server->{port}$entry->{key}", "#update:$chash->{NAME}" );
plex_sendApiCmd( $hash, "http://$server->{address}:$server->{port}$key", "#update:$chash->{NAME}" );
}
plex_readingsBulkUpdateIfChanged($chash, 'volume', $entry->{volume} ) if( $entry->{controllable} && $entry->{controllable} =~ m/\bvolume\b/ );
@ -2457,13 +2598,14 @@ plex_parseTimeline($$$)
$entries->{ $entry->{type} } = $entry;
}
if( $entry->{time} ) {
# if( !$chash->{helper}{time} || abs($entry->{time} - $chash->{helper}{time}) > 2000 ) {
# plex_readingsBulkUpdateIfChanged($chash, 'time', plex_sec2hms($entry->{time}/1000) );
my $time = $entry->{time};
if( defined($time) ) {
# if( !$chash->{helper}{time} || abs($time - $chash->{helper}{time}) > 2000 ) {
# plex_readingsBulkUpdateIfChanged($chash, 'time', plex_sec2hms($time/1000) );
#
# $chash->{helper}{time} = $entry->{time};
# $chash->{helper}{time} = $time;
# }
$chash->{time} = $entry->{time};
$chash->{time} = $time;
}
$chash->{seekRange} = $entry->{seekRange} if( $entry->{seekRange} && $entry->{seekRange} ne "0-0" );
@ -3631,6 +3773,8 @@ plex_parseHttpAnswer($$$)
my $chash = $defs{$1};
return undef if( !$chash );
#Log 1, Dumper $xml;
#Log 1, Dumper $param;
if( $xml->{librarySectionTitle} ne ReadingsVal($chash->{NAME}, 'section', '' ) ) {
CommandDeleteReading( undef, "$chash->{NAME} currentAlbum|currentArtist|episode|series|track" );
}
@ -3720,6 +3864,20 @@ plex_parseHttpAnswer($$$)
}
} elsif( $param->{key} eq 'sessions' ) {
$handled = 1;
if( my $server = plex_serverOf($hash, $param->{host}) ) {
delete $server->{sessions};
foreach my $type ( keys %{$xml} ) {
next if( ref($xml->{$type}) ne 'ARRAY' );
foreach my $item (@{$xml->{$type}}) {
$server->{sessions}{$item->{sessionKey}} = $item;
}
}
}
} elsif( $param->{key} =~ m/#m3u:(.*)/ ) {
my $entry = plex_entryOfID($hash, 'server', $1);
@ -3869,6 +4027,156 @@ Log 1, "!!!!!!!!!!";
return undef;
} elsif( defined($hash->{websocket}) ) {
my $pname = $hash->{PNAME} || $name;
$len = sysread($hash->{CD}, $buf, 10240);
#Log 1, "2:$len: $buf";
my $peerhost = $hash->{CD}->peerhost;
my $peerport = $hash->{CD}->peerport;
my $close = 0;
if( !defined($len) || !$len ) {
$close = 1;
} elsif( $hash->{websocket} ) {
$hash->{buf} .= $buf;
do {
my $fin = (ord(substr($hash->{buf},0,1)) & 0x80)?1:0;
my $op = (ord(substr($hash->{buf},0,1)) & 0x0F);
my $mask = (ord(substr($hash->{buf},1,1)) & 0x80)?1:0;
my $len = (ord(substr($hash->{buf},1,1)) & 0x7F);
my $i = 2;
if( $len == 126 ) {
$len = unpack( 'n', substr($hash->{buf},$i,2) );
$i += 2;
} elsif( $len == 127 ) {
$len = unpack( 'q', substr($hash->{buf},$i,8) );
$i += 8;
}
if( $mask ) {
$i += 4;
}
#Log 1, "$fin $op $mask $len";
#FIXME: hande !$fin
return if( $len > length($hash->{buf})-$i );
my $data = substr($hash->{buf}, $i, $len);
$hash->{buf} = substr($hash->{buf},$i+$len);
if( $op == 0x01 ) {
my $obj = eval { from_json($data) };
if( $obj ) {
my $phash = $hash->{phash};
my $handled = 0;
if( $obj->{_elementType} eq 'NotificationContainer' ) {
if( $obj->{type} eq 'playing' ) {
$handled = 1;
my $cname;
my $session_info_requested;
if( my $session = $obj->{_children}[0]{sessionKey} ) {
if( my $server = plex_serverOf($phash, $peerhost) ) {
if( my $session = $server->{sessions}{$session} ) {
if( my $chash = $modules{plex}{defptr}{$session->{Player}[0]{machineIdentifier}} ) {
$cname = $chash->{NAME};
#Log 1, Dumper $obj;
readingsBeginUpdate($chash);
my $key = $obj->{_children}[0]{key};
if( $key && $key ne ReadingsVal($chash->{NAME}, 'key', '') ) {
$chash->{currentServer} = $server->{machineIdentifier};
readingsBulkUpdate($chash, 'key', $key );
readingsBulkUpdate($chash, 'server', $server->{machineIdentifier} );
plex_sendApiCmd( $phash, "http://$server->{address}:$server->{port}$key", "#update:$chash->{NAME}" );
}
my $time = $obj->{_children}[0]{viewOffset};
if( defined($time) ) {
# if( !$chash->{helper}{time} || abs($time - $chash->{helper}{time}) > 2000 ) {
# plex_readingsBulkUpdateIfChanged($chash, 'time', plex_sec2hms($time/1000) );
#
# $chash->{helper}{time} = $time;
# }
$chash->{time} = $time;
}
plex_readingsBulkUpdateIfChanged($chash, 'state', $obj->{_children}[0]{state} );
readingsEndUpdate($chash, 1);
} else {
Log3 $pname, 3, "$pname: unknown player: $session->{Player}[0]{machineIdentifier}";
}
} else {
Log3 $pname, 3, "$pname: new session $obj->{_children}[0]{sessionKey}";
$session_info_requested = 1;
plex_sendApiCmd( $phash, "http://$server->{address}:$server->{port}/status/sessions", 'sessions' );
}
}
} else {
Log3 $pname, 3, "$pname: no session in notifcation ";
}
if( !$session_info_requested ) {
if( $obj->{_children}[0]{state} eq 'playing'
|| $obj->{_children}[0]{state} eq 'stopped' ) {
if( !$cname || $obj->{_children}[0]{key} ne ReadingsVal($cname, 'key', '' ) ) {
if( my $server = plex_serverOf($phash, $peerhost) ) {
plex_sendApiCmd( $phash, "http://$server->{address}:$server->{port}/status/sessions", 'sessions' );
}
}
}
}
} elsif( $obj->{type} eq 'status' ) {
$handled = 1;
#Log 1, Dumper $obj;
DoTrigger( $pname, "$obj->{_children}[0]{notificationName}: $obj->{_children}[0]{title}" );
}
}
Log3 $pname, 4, "$pname: unhandled websocket text type: $obj->{type}: $data" if( !$handled );
} else {
Log3 $pname, 2, "$pname: unhandled websocket text $data";
}
} else {
Log3 $pname, 2, "$pname: unhandled websocket data: $data";
}
} while( $hash->{buf} && !$close );
} elsif( $buf =~ m'^HTTP/1.1 101 Switching Protocols'i ) {
$hash->{websocket} = 1;
my $buf = plex_msg2hash($buf, 1);
Log3 $pname, 3, "$pname: notification websocket: Switching Protocols ok";
} else {
$close = 1;
Log3 $pname, 2, "$pname: notification websocket: Switching Protocols failed";
}
if( $close ) {
my $phash = $hash->{phash};
plex_closeSocket( $hash );
delete($phash->{helper}{websockets}{$hash->{machineIdentifier}});
delete($phash->{servers}{$hash->{address}}{sessions});
delete($defs{$name});
}
return undef;
} elsif ( $hash->{phash} ) {
my $phash = $hash->{phash};
my $pname = $hash->{PNAME};