From 428761e14b48a8965baa36902786639ec35b5115 Mon Sep 17 00:00:00 2001 From: vbs2 <> Date: Fri, 6 Nov 2015 18:22:17 +0000 Subject: [PATCH] 70_XBMC: - bugfix: 70_XBMC: reworked RPC ID generation - feature: 70_XBMC: added openchannelid to switch TV channels git-svn-id: https://svn.fhem.de/fhem/trunk@9799 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 ++ fhem/FHEM/70_XBMC.pm | 57 ++++++++++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index e3f45e398..5580b946d 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - bugfix: 70_XBMC: reworked RPC ID generation + - feature: 70_XBMC: added openchannelid to switch TV channels - bugfix: 74_AMAD: Bessere Variante zur HTTP Headeranalyse, Code aufgerÀumt - bugfix: 74_AMAD: AMADCommBridge communication problem with automagic 1.29 - feature: fhem_codemirror: Added DOIF autocomplete-keywords. Added feature diff --git a/fhem/FHEM/70_XBMC.pm b/fhem/FHEM/70_XBMC.pm index 991c4581a..2f2dcb386 100644 --- a/fhem/FHEM/70_XBMC.pm +++ b/fhem/FHEM/70_XBMC.pm @@ -46,6 +46,7 @@ sub XBMC_Define($$) } my ($name, $type, $addr, $protocol, $username, $password) = @args; $hash->{Protocol} = $protocol; + $hash->{NextID} = 1; $addr =~ /^(.*?)(:([0-9]+))?$/; $hash->{Host} = $1; if(defined($3)) { @@ -98,6 +99,14 @@ sub XBMC_Attr($$$$) return undef; } +sub XBMC_CreateId($) +{ + my ($hash) = @_; + my $res = $hash->{NextID}; + $hash->{NextID} = ($res >= 1000000) ? 1 : $res + 1; + return $res; +} + # Force a connection attempt to XBMC as soon as possible # (e.g. you know you just started it and want to connect immediately without waiting up to 60 s) sub XBMC_Connect($) @@ -397,7 +406,9 @@ sub XBMC_ProcessRead($$) } #otherwise it is a answer of a request else { - XBMC_ProcessResponse($hash,$obj); + if (XBMC_ProcessResponse($hash,$obj) == -1) { + Log3($name, 2, "XBMC_ProcessRead: Faulty message: $msg"); + } } ($msg,$tail) = XBMC_ParseMsg($hash, $tail); } @@ -457,7 +468,7 @@ sub XBMC_PlayerOnPlay($$) { my ($hash,$obj) = @_; my $name = $hash->{NAME}; - my $id = XBMC_CreateId(); + my $id = XBMC_CreateId($hash); my $type = $obj->{params}->{data}->{item}->{type}; if(AttrVal($hash->{NAME},'compatibilityMode','xbmc') eq 'plex' || !defined($obj->{params}->{data}->{item}->{id}) || $type eq "picture" || $type eq "unknown") { # we either got unknown or picture OR an item not in the library (id not existing) @@ -617,6 +628,7 @@ sub XBMC_ProcessNotification($$) sub XBMC_ProcessResponse($$) { my ($hash,$obj) = @_; + my $name = $hash->{NAME}; my $id = $obj->{id}; #check if the id of the answer matches the id of a pending event if(defined($hash->{PendingEvents}{$id})) { @@ -641,15 +653,25 @@ sub XBMC_ProcessResponse($$) } $hash->{PendingEvents}{$id} = undef; } - elsif(defined($hash->{PendingPlayerCMDs}{$id})) { + elsif(exists($hash->{PendingPlayerCMDs}{$id})) { my $cmd = $hash->{PendingPlayerCMDs}{$id}; my $players = $obj->{result}; + if (ref($players) ne "ARRAY") { + my $keys = ""; + while ((my $k, my $v) = each $hash->{PendingPlayerCMDs} ) { + $keys .= ",$k"; + } + delete $hash->{PendingPlayerCMDs}{$id}; + Log3($name, 2, "XBMC_ProcessResponse: Not received a player array! Pending command cancelled!"); + Log3($name, 2, "XBMC_ProcessResponse: Keys in PendingPlayerCMDs: $keys"); + return -1; + } foreach my $player (@$players) { - $cmd->{id} = XBMC_CreateId(); + $cmd->{id} = XBMC_CreateId($hash); $cmd->{params}->{playerid} = $player->{playerid}; XBMC_Call($hash,$cmd,1); } - $hash->{PendingPlayerCMDs}{$id} = undef; + delete $hash->{PendingPlayerCMDs}{$id}; } else { my $result = $obj->{result}; @@ -671,7 +693,7 @@ sub XBMC_ProcessResponse($$) readingsEndUpdate($hash, 1); } } - return undef; + return 0; } sub XBMC_Is3DFile($$) { @@ -836,6 +858,9 @@ sub XBMC_Set($@) elsif($cmd eq 'openepisodeid') { return XBMC_Set_Open($hash, 'episode', @args); } + elsif($cmd eq 'openchannelid') { + return XBMC_Set_Open($hash, 'channel', @args); + } elsif($cmd eq 'addon') { return XBMC_Set_Addon($hash, @args); } @@ -1040,6 +1065,12 @@ sub XBMC_Set_Open($@) 'resume' => JSON::true } }; + } elsif($opt eq 'channel') { + $params = { + 'item' => { + 'channelid' => $path +0 + }, + }; } my $obj = { 'method' => 'Player.Open', @@ -1220,7 +1251,7 @@ sub XBMC_PlayerCommand($$$) } #we need to find out the correct player first - my $id = XBMC_CreateId(); + my $id = XBMC_CreateId($hash); $hash->{PendingPlayerCMDs}->{$id} = $obj; my $req = { 'method' => 'Player.GetActivePlayers', @@ -1263,7 +1294,7 @@ sub XBMC_Call($$$) my $name = $hash->{NAME}; #add an ID otherwise XBMC will not respond if($id &&!defined($obj->{id})) { - $obj->{id} = XBMC_CreateId(); + $obj->{id} = XBMC_CreateId($hash); } $obj->{jsonrpc} = "2.0"; #JSON RPC version has to be passed my $json = JSON->new->utf8(0)->encode($obj); @@ -1289,11 +1320,6 @@ sub XBMC_Call_raw($$$) } } -sub XBMC_CreateId() -{ - return int(rand(1000000)); -} - sub XBMC_RCmakenotify($$) { my ($nam, $ndev) = @_; my $nname="notify_$nam"; @@ -1514,8 +1540,9 @@ sub XBMC_HTTP_Request($$@)