From 8889804b9a5c75c8e63c6fb4e6e0911fd8521dbd Mon Sep 17 00:00:00 2001 From: vbs <> Date: Wed, 11 Sep 2019 07:02:55 +0000 Subject: [PATCH] 70_KODI: added channel name resolution and openchannel command git-svn-id: https://svn.fhem.de/fhem/trunk@20146 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 3 + fhem/FHEM/70_KODI.pm | 153 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 140 insertions(+), 16 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 3632a9a8a..b4cd5c0f9 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,8 @@ # 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. + - feature: 70_KODI: Added fetching of channel names and command openchannel to + open channel by names. Channel IDs will be converted + automatically. - feature: 93_DbRep: SQL Wildcard (%) usage possible as placeholder in a reading- or device-list. Forum: #101756, internal code changes of SQL statement generation diff --git a/fhem/FHEM/70_KODI.pm b/fhem/FHEM/70_KODI.pm index be8582cd2..4fcad4726 100644 --- a/fhem/FHEM/70_KODI.pm +++ b/fhem/FHEM/70_KODI.pm @@ -109,6 +109,7 @@ sub KODI_Initialize($$) my ($hash) = @_; $hash->{DefFn} = "KODI_Define"; $hash->{SetFn} = "KODI_Set"; + $hash->{GetFn} = "KODI_Get"; $hash->{ReadFn} = "KODI_Read"; $hash->{ReadyFn} = "KODI_Ready"; $hash->{UndefFn} = "KODI_Undefine"; @@ -242,6 +243,7 @@ sub KODI_OnConnect($) $hash->{LAST_RECV} = time(); KODI_Update($hash); + KODI_PvrUpdateChannels($hash); KODI_QueueIntervalUpdate($hash); @@ -644,6 +646,30 @@ sub KODI_PlayerOnPlay($$) } } +sub KODI_Get($@) { + my ( $hash, $name, $cmd, @args ) = @_; + + return 'Module disabled!' if AttrVal($hash->{NAME}, 'disable', 0); + + if ($cmd eq "update_channels") { + KODI_PvrUpdateChannels($hash); + } + elsif ($cmd eq "channelid") { + if ( !defined( $args[0] ) ) { + my $msg = "$hash->{NAME} channelid requires channel name parameter"; + Log3( $hash, 3, $msg ); + return $msg; + } + + my $channel = join(" ", @args); + return KODI_PvrGetChannelId($hash, $channel); + } else { + return "Unknown command '$cmd', choose one of update_channels:noArg channelid"; + } + + return undef; +} + sub KODI_ProcessNotification($$) { my ($hash,$obj) = @_; @@ -778,27 +804,50 @@ sub KODI_ProcessResponse($$) KODI_Call($hash,$cmd,1); } delete $hash->{PendingPlayerCMDs}{$id}; - } + } else { # this is for handling other responses like responses to Application.GetProperties etc. my $result = $obj->{result}; if($result && ref $result eq "HASH") { - Log3($name, 4, "$name: KODI_ProcessResponse: updating readings"); - readingsBeginUpdate($hash); - foreach my $key (keys %$result) { - if ($key eq 'item') { - my $item = $obj->{result}->{item}; - foreach my $ikey (keys %$item) { - my $value = $item->{$ikey}; - KODI_CreateReading($hash,$ikey,$value); + if(exists($obj->{result}->{channelgroups})) { + Log3($name, 4, "$name: KODI_ProcessResponse: received channelgroups information"); + readingsBeginUpdate($hash); + foreach my $cg (@{$obj->{result}->{channelgroups}}) { + my $cgid = $cg->{channelgroupid}; + readingsBulkUpdate($hash, "channelgroup_${cgid}_type", $cg->{channeltype}); + readingsBulkUpdate($hash, "channelgroup_${cgid}_label", $cg->{label}); + + KODI_PvrGetChannels($hash, $cgid); + } + readingsEndUpdate($hash, 1); + } + elsif(exists($obj->{result}->{channels})) { + Log3($name, 4, "$name: KODI_ProcessResponse: received channels information"); + readingsBeginUpdate($hash); + foreach my $c (@{$obj->{result}->{channels}}) { + my $cid = $c->{channelid}; + readingsBulkUpdate($hash, "channel_${cid}", $c->{label}); + } + readingsEndUpdate($hash, 1); + } + else { + Log3($name, 4, "$name: KODI_ProcessResponse: updating readings"); + readingsBeginUpdate($hash); + foreach my $key (keys %$result) { + if ($key eq 'item') { + my $item = $obj->{result}->{item}; + foreach my $ikey (keys %$item) { + my $value = $item->{$ikey}; + KODI_CreateReading($hash,$ikey,$value); + } + } + else { + my $value = $result->{$key}; + KODI_CreateReading($hash,$key,$value); } } - else { - my $value = $result->{$key}; - KODI_CreateReading($hash,$key,$value); - } + readingsEndUpdate($hash, 1); } - readingsEndUpdate($hash, 1); } else { Log3($name, 5, "$name: KODI_ProcessResponse: ignoring response: $result"); @@ -977,6 +1026,17 @@ sub KODI_Set($@) elsif($cmd eq 'openepisodeid') { return KODI_Set_Open($hash, 'episode', @args); } + elsif($cmd eq 'openchannel') { + my $channel = join(' ', @args); + my $cid = KODI_PvrGetChannelId($hash, $channel); + if ($cid == -1) { + my $msg = "Could not find channel $channel"; + Log3($name, 4, "$name: KODI_Set: $msg"); + return $msg; + } + @args = ($cid); + return KODI_Set_Open($hash, 'channel', @args); + } elsif($cmd eq 'openchannelid') { return KODI_Set_Open($hash, 'channel', @args); } @@ -1121,7 +1181,7 @@ sub KODI_Set($@) my $res = "Unknown argument " . $cmd . ", choose one of " . "off play:all,audio,video,picture playpause:all,audio,video,picture pause:all,audio,video,picture " . "prev:all,audio,video,picture next:all,audio,video,picture goto stop:all,audio,video,picture " . - "open opendir openmovieid openepisodeid openchannelid addon shuffle:toggle,on,off repeat:one,all,off volumeUp:noArg volumeDown:noArg " . + "open opendir openmovieid openepisodeid openchannel openchannelid addon shuffle:toggle,on,off repeat:one,all,off volumeUp:noArg volumeDown:noArg " . "seek back:noArg contextmenu:noArg down:noArg home:noArg info:noArg left:noArg " . "right:noArg select:noArg send exec:left,right," . "up,down,pageup,pagedown,select,highlight,parentdir,parentfolder,back," . @@ -1416,6 +1476,59 @@ sub KODI_PlayerCommand($$$) return KODI_Call($hash,$req,1); } +sub KODI_PvrUpdateChannels($) +{ + my ($hash) = @_; + fhem("deletereading $hash->{NAME} channel_.*", 1); + fhem("deletereading $hash->{NAME} channelgroup_.*", 1); + + KODI_PvrGetChannelGroups($hash, "tv"); + KODI_PvrGetChannelGroups($hash, "radio"); +} + +sub KODI_PvrGetChannelGroups($$) +{ + my ($hash,$type) = @_; + + my $id = KODI_CreateId($hash); + my $req = { + 'method' => 'PVR.GetChannelGroups', + 'params' => { 'channeltype' => $type }, + 'id' => $id + }; + return KODI_Call($hash,$req,1); +} + +sub KODI_PvrGetChannels($$) +{ + my ($hash,$channelGroupId) = @_; + + my $id = KODI_CreateId($hash); + my $req = { + 'method' => 'PVR.GetChannels', + 'params' => { 'channelgroupid' => $channelGroupId + 0 }, + 'id' => $id + }; + return KODI_Call($hash,$req,1); +} + +sub KODI_PvrGetChannelId($$) { + my ($hash, $channelname) = @_; + my $name = $hash->{NAME}; + + my $cid=1; + + Log3($name, 4, "$name: KODI_PvrGetChannelId: $channelname"); + + my $readings = $defs{$name}{READINGS}; + foreach my $rname (sort keys %{$readings}) { + next if (rindex($rname, "channel_", 0) < 0); + my $curname = ReadingsVal($name, $rname, undef); + return (split /_/, $rname)[1] if ($curname eq $channelname); + } + return -1; +} + #returns 'toggle' if the argument is undef #returns JSON::true if the argument is true and not equals "off" otherwise it returns JSON::false sub KODI_Toggle($) @@ -1684,7 +1797,14 @@ sub KODI_HTTP_Request($$@) is a issue of Kodi. The fix of this bug is included in future version of Kodi (> 12.2). - +

+ + Get + +

Set