From f14b3ec3ad8c4a17b746c505f5a3be57943614a0 Mon Sep 17 00:00:00 2001 From: teevau <> Date: Mon, 11 Jan 2016 18:03:07 +0000 Subject: [PATCH] - feature: 70_VIERA: Using non blocking for status update. Added color button for remoteControl and SVG layout Some new SVG icons for remoteControl layout git-svn-id: https://svn.fhem.de/fhem/trunk@10463 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 3 + fhem/FHEM/70_VIERA.pm | 573 ++++++++++++++------- fhem/www/images/fhemSVG/rc_ASPECT.svg | 91 ++++ fhem/www/images/fhemSVG/rc_BLANK2.svg | 55 ++ fhem/www/images/fhemSVG/rc_INFO2.svg | 71 +++ fhem/www/images/fhemSVG/rc_PROG.svg | 77 +++ fhem/www/images/fhemSVG/rc_TV2.svg | 75 +++ fhem/www/images/fhemSVG/rc_VIERA_LINK.svg | 103 ++++ fhem/www/images/fhemSVG/rc_VIERA_TOOLS.svg | 107 ++++ fhem/www/images/fhemSVG/rc_VOL.svg | 74 +++ 10 files changed, 1045 insertions(+), 184 deletions(-) create mode 100644 fhem/www/images/fhemSVG/rc_ASPECT.svg create mode 100644 fhem/www/images/fhemSVG/rc_BLANK2.svg create mode 100644 fhem/www/images/fhemSVG/rc_INFO2.svg create mode 100644 fhem/www/images/fhemSVG/rc_PROG.svg create mode 100644 fhem/www/images/fhemSVG/rc_TV2.svg create mode 100644 fhem/www/images/fhemSVG/rc_VIERA_LINK.svg create mode 100644 fhem/www/images/fhemSVG/rc_VIERA_TOOLS.svg create mode 100644 fhem/www/images/fhemSVG/rc_VOL.svg diff --git a/fhem/CHANGED b/fhem/CHANGED index ec83b10a7..13f95498c 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_VIERA: Using non blocking for status update. + Added color button for remoteControl and SVG layout + Some new SVG icons for remoteControl layout - change: 73_km200: New attribute "disabled" and default values changed. - feature: HUEbridge: added set deletescene and get scenes detail - feature: HUEDevice: added (hue|sat|ct)(Up|Down) commands diff --git a/fhem/FHEM/70_VIERA.pm b/fhem/FHEM/70_VIERA.pm index 8ffe192c5..7a9c4f3aa 100644 --- a/fhem/FHEM/70_VIERA.pm +++ b/fhem/FHEM/70_VIERA.pm @@ -8,9 +8,19 @@ # written 2013 by Tobias Vaupel # # -# Version = 1.23 +# Version = 1.24 # # Version History: +# - 1.24 - 2015-07-08 +# -- Using non blocking as default for status update. Use attr to use blocking mode. +# -- Replaced when/given with if/elsif +# -- Added color buttons for remoteControl Layout +# -- Added remoteControl Layout with SVG +# -- InternalTimer is deleted at define. Avoid multiple internalTimer running in parallel when redefining device +# -- Added TCP-Port to internal PORT instead of fixed coding +# -- increased byte length at command read (IO::Socket::INET) from 1 to 1024 +# -- in very few cases the TV is answering with HTTP Code 400 BAD REQUEST. This is considered now and is interpreted as device on instead of off. +# # - 1.23 - 2014-08-01 # -- Add parameter "HDMI1" - "HDMI4" for command remoteControl to select HDMI input directly # -- Add command "input" to select a HDMI port, TV or SD-Card as source @@ -27,7 +37,7 @@ # # - 1.11 - 2013-08-13 # -- added "noArg" at get/set-command -# -- changed format of return() in VIERA_Get() for get-command dropdown menu in FHEMWEB +# -- changed format of return() in VIERA_Get() for get-command drop down menu in FHEMWEB # # - 1.10 - 2013-06-29 # -- Added support for module 95_remotecontrol @@ -45,10 +55,12 @@ use warnings; use IO::Socket::INET; use feature qw/say switch/; use Time::HiRes qw(gettimeofday sleep); +use Blocking; + -######################### # Forward declaration for remotecontrol module sub VIERA_RClayout_TV(); +sub VIERA_RClayout_TV_SVG(); sub VIERA_RCmakenotify($$); @@ -113,46 +125,63 @@ my %VIERA_remoteControl_args = ( "NRC_HDMI4" => "Switch to HDMI input 4", ); - +# Initialize the module and tell FHEM name of additional functions +# Param1: Hash of FHEM-Device +# Return: no return code sub VIERA_Initialize($){ my ($hash) = @_; $hash->{DefFn} = "VIERA_Define"; $hash->{SetFn} = "VIERA_Set"; $hash->{GetFn} = "VIERA_Get"; $hash->{UndefFn} = "VIERA_Undefine"; - $hash->{AttrList} = $readingFnAttributes; + $hash->{AttrList} = "blocking:1,0 $readingFnAttributes"; $data{RC_layout}{VIERA_TV} = "VIERA_RClayout_TV"; + $data{RC_layout}{VIERA_TV_SVG} = "VIERA_RClayout_TV_SVG"; $data{RC_makenotify}{VIERA} = "VIERA_RCmakenotify"; } +# Callback when 'define' is used at FHEM +# Param1: Hash of FHEM-Device +# Param2: String of 'define' command +# Return: Help text for FHEMWEB sub VIERA_Define($$){ my ($hash, $def) = @_; my @args = split("[ \t][ \t]*", $def); my $name = $hash->{NAME}; - + if(int(@args) < 3 && int(@args) > 4) { my $msg = "wrong syntax: define VIERA []"; Log3 $name, 2, "VIERA: $msg"; return $msg; } - + $hash->{helper}{HOST} = $args[2]; - readingsSingleUpdate($hash,"state","Initialized",1); + $hash->{helper}{PORT} = 55000; if(defined($args[3]) and $args[3] > 10) { $hash->{helper}{INTERVAL}=$args[3]; } - else{ + else { $hash->{helper}{INTERVAL}=30; } - CommandAttr(undef,$name.' webCmd off') if( !defined( AttrVal($hash->{NAME}, "webCmd", undef) ) ); - Log3 $name, 2, "VIERA: defined with host: $hash->{helper}{HOST} and interval: $hash->{helper}{INTERVAL}"; + CommandAttr(undef,$name.' webCmd off') if( !defined( AttrVal($hash->{NAME}, "webCmd", undef)) ); + + BlockingKill($hash->{helper}{RUNNING_PID_GET}) if(defined($hash->{helper}{RUNNING_PID_GET})); + delete($hash->{helper}{RUNNING_PID_GET}); + + RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$hash->{helper}{INTERVAL}, "VIERA_GetStatus", $hash, 0); - + + Log3 $name, 2, "VIERA: defined with host: $hash->{helper}{HOST} and interval: $hash->{helper}{INTERVAL}"; + readingsSingleUpdate($hash,"state","Initialized",1); return undef; } +# Callback when 'set' is used at FHEM +# Param1: Hash of FHEM-Device +# Param2: String of 'set' command +# Return: Help text for FHEMWEB sub VIERA_Set($@){ my ($hash, @a) = @_; my $name = $hash->{NAME}; @@ -171,114 +200,92 @@ sub VIERA_Set($@){ return "VIERA: No argument given, $usage" if(!defined($a[1])); my $state = lc($a[2]) if(defined($a[2])); - given($what) { - when("mute"){ - Log3 $name, 3, "VIERA: Set mute $state"; - if ($state eq "on") {$state = 1;} else {$state = 0;} - VIERA_connection(VIERA_BuildXML_RendCtrl($hash, "Set", "Mute", $state), $host); - VIERA_GetStatus($hash, 1); - break; + if ($what eq "mute"){ + Log3 $name, 3, "VIERA: Set mute $state"; + if ($state eq "on") {$state = 1;} else {$state = 0;} + VIERA_connection($hash, VIERA_BuildXML_RendCtrl($hash, "Set", "Mute", $state)); + VIERA_GetStatus($hash, 1); + } + elsif ($what eq "volume"){ + return "VIERA: Volume range is too high! Use Value 0 till 100 for volume." if($state < 0 || $state > 100); + Log3 $name, 3, "VIERA: Set volume $state"; + VIERA_connection($hash, VIERA_BuildXML_RendCtrl($hash, "Set", "Volume", $state)); + VIERA_GetStatus($hash, 1); + } + elsif ($what eq "volumeup"){ + return "VIERA: Volume range is too high!" if(ReadingsVal($name, "volume", "0") > 100); + Log3 $name, 3, "VIERA: Set volumeUp"; + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,"VOLUP")); + VIERA_GetStatus($hash, 1); + } + elsif ($what eq "volumedown"){ + return "VIERA: Volume range is too low!" if(ReadingsVal($name, "volume", "0") < 1); + Log3 $name, 3, "VIERA: Set volumeDown"; + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,"VOLDOWN")); + VIERA_GetStatus($hash, 1); + } + elsif ($what eq "channel"){ + return "VIERA: Channel is too high or low!" if($state < 1 || $state > 9999); + Log3 $name, 3, "VIERA: Set channel $state"; + for(my $i = 0; $i <= length($state)-1; $i++) { + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,"D" . substr($state, $i, 1))); + sleep 0.1; } - - when("volume"){ - return "VIERA: Volume range is too high! Use Value 0 till 100 for volume." if($state < 0 || $state > 100); - Log3 $name, 3, "VIERA: Set volume $state"; - VIERA_connection(VIERA_BuildXML_RendCtrl($hash, "Set", "Volume", $state), $host); - VIERA_GetStatus($hash, 1); - break; + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,"ENTER")); + } + elsif ($what eq "channelup"){ + Log3 $name, 3, "VIERA: Set channelUp"; + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,"CH_UP")); + } + elsif ($what eq "channeldown"){ + Log3 $name, 3, "VIERA: Set channelDown"; + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,"CH_DOWN")); + } + elsif ($what eq "remotecontrol"){ + if($state eq "?"){ + $usage = "choose one of the states:\n"; + foreach $key (sort keys %VIERA_remoteControl_args){ + if(length($key) < 17){ $tab = "\t\t"; }else{ $tab = "\t"; } + $usage .= "$key $tab=> $VIERA_remoteControl_args{$key}\n"; } - - when("volumeup"){ - return "VIERA: Volume range is too high!" if(ReadingsVal($name, "volume", "0") > 100); - Log3 $name, 3, "VIERA: Set volumeUp"; - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,"VOLUP"), $host); - VIERA_GetStatus($hash, 1); - break; + $usage =~ s/(NRC_|-ONOFF)//g; + return $usage; } - - when("volumedown"){ - return "VIERA: Volume range is too low!" if(ReadingsVal($name, "volume", "0") < 1); - Log3 $name, 3, "VIERA: Set volumeDown"; - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,"VOLDOWN"), $host); - VIERA_GetStatus($hash, 1); - break; + else{ + $state = uc($state); + Log3 $name, 3, "VIERA: Set remoteControl $state"; + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,$state)); } - - when("channel"){ - return "VIERA: Channel is too high or low!" if($state < 1 || $state > 9999); - Log3 $name, 3, "VIERA: Set channel $state"; - for(my $i = 0; $i <= length($state)-1; $i++) { - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,"D" . substr($state, $i, 1)), $host); - sleep 0.1; - } - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,"ENTER"), $host); - break; - } - - when("channelup"){ - Log3 $name, 3, "VIERA: Set channelUp"; - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,"CH_UP"), $host); - break; - } - - when("channeldown"){ - Log3 $name, 3, "VIERA: Set channelDown"; - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,"CH_DOWN"), $host); - break; - } - - when("remotecontrol"){ - if($state eq "?"){ - $usage = "choose one of the states:\n"; - foreach $key (sort keys %VIERA_remoteControl_args){ - if(length($key) < 17){ $tab = "\t\t"; }else{ $tab = "\t"; } - $usage .= "$key $tab=> $VIERA_remoteControl_args{$key}\n"; - } - $usage =~ s/(NRC_|-ONOFF)//g; - return $usage; - } - else{ - $state = uc($state); - Log3 $name, 3, "VIERA: Set remoteControl $state"; - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,$state), $host); - } - break; - } - - when("off"){ - Log3 $name, 3, "VIERA: Set off"; - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,"POWER"), $host); - break; - } - - when("statusrequest"){ - Log3 $name, 3, "VIERA: Set statusRequest"; - VIERA_GetStatus($hash, 1); - break; - } - - when("input"){ - $state = uc($state); - return "VIERA: Input $state isn't available." if($state ne "HDMI1" && $state ne "HDMI2" && $state ne "HDMI3" && $state ne "HDMI4" && $state ne "SDCARD" && $state ne "TV"); - $state = "SD_CARD" if ($state eq "SDCARD"); - Log3 $name, 3, "VIERA: Set input $state"; - VIERA_connection(VIERA_BuildXML_NetCtrl($hash,$state), $host); - break; - } - - when("?"){ - return "$usage"; - break; - } - - default{ - Log3 $name, 3, "VIERA: Unknown argument $what, $usage"; - return "Unknown argument $what, $usage"; - }; + } + elsif ($what eq "off"){ + Log3 $name, 3, "VIERA: Set off"; + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,"POWER")); + } + elsif ($what eq "statusrequest"){ + Log3 $name, 3, "VIERA: Set statusRequest"; + VIERA_GetStatus($hash, 1); + } + elsif ($what eq "input"){ + $state = uc($state); + return "VIERA: Input $state isn't available." if($state ne "HDMI1" && $state ne "HDMI2" && $state ne "HDMI3" && $state ne "HDMI4" && $state ne "SDCARD" && $state ne "TV"); + $state = "SD_CARD" if ($state eq "SDCARD"); + Log3 $name, 3, "VIERA: Set input $state"; + VIERA_connection($hash, VIERA_BuildXML_NetCtrl($hash,$state)); + } + elsif ($what eq "?"){ + return "$usage"; + } + else { + Log3 $name, 3, "VIERA: Unknown argument $what, $usage"; + return "Unknown argument $what, $usage"; } return undef; } +# Callback when 'get' is used at FHEM +# Param1: Hash of FHEM-Device +# Param2: String of 'set' command +# Return: Help text for FHEMWEB sub VIERA_Get($@){ my ($hash, @a) = @_; my $what; @@ -302,29 +309,51 @@ sub VIERA_Get($@){ } } +# Callback when 'delete' is used at FHEM or FHEM is restarting/shutdown +# Param1: Hash of FHEM-Device +# Param2: Name of FHEM-Device +# Return: undef sub VIERA_Undefine($$){ my($hash, $name) = @_; # Stop the internal GetStatus-Loop and exist RemoveInternalTimer($hash); + BlockingKill($hash->{helper}{RUNNING_PID_GET}) if(defined($hash->{helper}{RUNNING_PID_GET})); + return undef; } +# Function is called periodically by InternalTimer and fetch informations from device. The decision if blocking or nonBlocking is used is made here. +# Param1: Hash of FHEM-Device +# Param2: Optional, if set to 1 fetch information from device without interrupting InternalTimer sub VIERA_GetStatus($;$){ my ($hash, $local) = @_; my $name = $hash->{NAME}; my $host = $hash->{helper}{HOST}; + my $blocking = AttrVal($name, "blocking", 0); #use non-blocking in standard. Just use blocking when set by attr - #if $local is set to 1 just fetch informations from device without interupting InternalTimer + #if $local is set to 1 just fetch informations from device without interrupting InternalTimer $local = 0 unless(defined($local)); InternalTimer(gettimeofday()+$hash->{helper}{INTERVAL}, "VIERA_GetStatus", $hash, 0) unless($local == 1); return "" if(!defined($hash->{helper}{HOST}) or !defined($hash->{helper}{INTERVAL})); - - my $returnVol = VIERA_connection(VIERA_BuildXML_RendCtrl($hash, "Get", "Volume", ""), $host); - Log3 $name, 5, "VIERA: GetStatusVol-Request returned: $returnVol" if(defined($returnVol)); + + if ($blocking == 0) { + Log3 $name, 4, "VIERA[VIERA_GetStatus]: Using non blocking..."; + $hash->{helper}{RUNNING_PID_GET} = BlockingCall("VIERA_GetDoIt", $hash, "VIERA_GetDone", 10, "VIERA_GetAbortFn", $hash) unless(exists($hash->{helper}{RUNNING_PID_GET})); + if($hash->{helper}{RUNNING_PID_GET}) { + Log3 $name, 4, "VIERA[VIERA_GetStatus]: VIERA_GetDoIt() BlockingCall process started with PID $hash->{helper}{RUNNING_PID_GET}{pid}"; + } + else { + Log3 $name, 3, "VIERA[VIERA_GetStatus]: BlockingCall process start failed for VIERA_GetDoIt()"; + } + return; + } + Log3 $name, 4, "VIERA[VIERA_GetStatus]: Using blocking..."; + my $returnVol = VIERA_connection($hash, VIERA_BuildXML_RendCtrl($hash, "Get", "Volume", "")); + Log3 $name, 5, "VIERA[VIERA_GetStatus]: Vol-Request returned: $returnVol" if(defined($returnVol)); if(not defined($returnVol) or $returnVol eq "") { - Log3 $name, 4, "VIERA: GetStatusVol-Request NO SOCKET!"; + Log3 $name, 4, "VIERA[VIERA_GetStatus]: Vol-Request NO SOCKET!"; if( ReadingsVal($name,"state","absent") ne "absent") { readingsBeginUpdate($hash); readingsBulkUpdate($hash, "state", "absent"); @@ -335,10 +364,10 @@ sub VIERA_GetStatus($;$){ return; } - my $returnMute = VIERA_connection(VIERA_BuildXML_RendCtrl($hash, "Get", "Mute", ""), $host); - Log3 $name, 5, "VIERA: GetStatusMute-Request returned: $returnMute" if(defined($returnMute)); + my $returnMute = VIERA_connection($hash, VIERA_BuildXML_RendCtrl($hash, "Get", "Mute", "")); + Log3 $name, 5, "VIERA[VIERA_GetStatus]: Mute-Request returned: $returnMute" if(defined($returnMute)); if(not defined($returnMute) or $returnMute eq "") { - Log3 $name, 4, "VIERA: GetStatusMute-Request NO SOCKET!"; + Log3 $name, 4, "VIERA[VIERA_GetStatus]: Mute-Request NO SOCKET!"; if( ReadingsVal($name,"state","absent") ne "absent") { readingsBeginUpdate($hash); readingsBulkUpdate($hash, "state", "absent"); @@ -351,14 +380,14 @@ sub VIERA_GetStatus($;$){ readingsBeginUpdate($hash); if($returnVol =~ /(.+)<\/CurrentVolume>/){ - Log3 $name, 4, "VIERA: GetStatus-Set reading volume to $1"; + Log3 $name, 4, "VIERA[VIERA_GetStatus]: Set reading volume to $1"; if( $1 != ReadingsVal($name, "volume", "0") ) {readingsBulkUpdate($hash, "volume", $1);} } if($returnMute =~ /(.+)<\/CurrentMute>/){ my $myMute = $1; if ($myMute == 0) { $myMute = "off"; } else { $myMute = "on";} - Log3 $name, 4, "VIERA: GetStatus-Set reading mute to $myMute"; + Log3 $name, 4, "VIERA[VIERA_GetStatus]: Set reading mute to $myMute"; if( $myMute ne ReadingsVal($name, "mute", "0") ) {readingsBulkUpdate($hash, "mute", $myMute);} } if( ReadingsVal($name,"state","absent") ne "on") { @@ -368,88 +397,132 @@ sub VIERA_GetStatus($;$){ } readingsEndUpdate($hash, 1); - #Log3 $name, 4, "VIERA $name: $hash->{STATE}"; return $hash->{STATE}; } +# To sent RAW-Data as TCP Client to device +# param1: Hash of FHEM-Device +# param2: RAW Data +#return: RAW answer when successful or undef if no socket is available. sub VIERA_connection($$){ - my $tmp = shift ; - my $TV = shift; + my ($hash, $data) = @_; + my $name = $hash->{NAME}; my $buffer = ""; - my $tmp2 = ""; + my $buff = ""; + my $blocking = "NonBlocking-VIERA_connection()" if (AttrVal($name, "blocking", 0) == 0); + $blocking = "Blocking-VIERA_connection()" if (AttrVal($name, "blocking", 0) == 1); + my $sock = new IO::Socket::INET ( - PeerAddr => $TV, - PeerPort => '55000', + PeerAddr => $hash->{helper}{HOST}, + PeerPort => $hash->{helper}{PORT}, Proto => 'tcp', Timeout => 2 ); - - #Log3 $name, 5, "VIERA: connection message: $tmp"; - - if(defined ($sock)){ - print $sock $tmp; - my $buff =""; - while ((read $sock, $buff, 1) > 0){ + if(defined ($sock)) { + Log3 $hash, 5, "VIERA[$blocking]: Send Data to $hash->{helper}{HOST}:$hash->{helper}{PORT}:\n$data"; + print $sock $data; + + while ((read $sock, $buff, 1024) > 0){ $buffer .= $buff; } - - my @tmp2 = split (/\n/,$buffer); - #Log3 $name, 4, "VIERA: $TV response: $tmp2[0]"; - #Log3 $name, 5, "VIERA: $TV buffer response: $buffer"; + + Log3 $hash, 5, "VIERA[$blocking]: $hash->{helper}{HOST} buffer response:\n$buffer"; $sock->close(); return $buffer; } - else{ - #Log3 $name, 4, "VIERA: $TV: not able to open socket"; + else { + Log3 $hash, 4, "VIERA[$blocking]: $hash->{helper}{HOST}: not able to open socket"; return undef; } } -##################################### # Callback from 95_remotecontrol for command makenotify. +# Param1: Name of remoteControl device +# Param2: Name of target FHEM device sub VIERA_RCmakenotify($$) { my ($nam, $ndev) = @_; my $nname="notify_$nam"; fhem("define $nname notify $nam set $ndev remoteControl ".'$EVENT',1); - Log3 undef, 2, "[remotecontrol:VIERA] Notify created: $nname"; + Log3 undef, 2, "[remoteControl:VIERA] Notify created: $nname"; return "Notify created by VIERA: $nname"; } -##################################### -# Default-layout for panasonic TV (maybe other VIERA devices will have other layouts) +# Callback from 95_remotecontrol for command layout. Creates non svg layout sub VIERA_RClayout_TV() { my @row; + my $i = 0; - $row[0]="power:POWEROFF2,TV, CHG_INPUT:HDMI"; - $row[1]="MENU, disp_mode:ASPECT,epg:GUIDE"; - $row[2]="VIERA_LINK,VTOOLS,INTERNET"; - $row[3]=":blank,:blank,:blank"; - $row[4]="INFO:INFO2,UP,cancel:EXIT"; - $row[5]="LEFT,ENTER,RIGHT"; - $row[6]="SUBMENU,DOWN,RETURN"; - $row[7]=":blank,:blank,:blank"; - $row[8]="d1:1,d2:2,d3:3"; - $row[9]="d4:4,d5:5,d6:6"; - $row[10]="d7:7,d8:8,d9:9"; - $row[11]="MUTE,d0:0,r_tune:PRECH"; - $row[12]=":blank,:blank,:blank"; - $row[13]="VOLUP,:blank,ch_up:CHUP"; - $row[14]=":VOL,:blank,:PROG"; - $row[15]="VOLDOWN,:blank,ch_down:CHDOWN"; - $row[16]=":blank,:blank,:blank"; - $row[17]="rew:REWIND,PLAY,FF"; - $row[18]="STOP,PAUSE,REC"; + $row[$i++]="power:POWEROFF2, TV, CHG_INPUT:HDMI"; + $row[$i++]="MENU, disp_mode:ASPECT, epg:GUIDE"; + $row[$i++]="VIERA_LINK, VTOOLS, INTERNET"; + $row[$i++]=":blank, :blank, :blank"; + $row[$i++]="INFO:INFO2, UP, cancel:EXIT"; + $row[$i++]="LEFT, ENTER, RIGHT"; + $row[$i++]="SUBMENU, DOWN, RETURN"; + $row[$i++]="red:RED, :blank, green:GREEN"; + $row[$i++]="yellow:YELLOW, :blank, blue:BLUE"; + $row[$i++]="d1:1, d2:2, d3:3"; + $row[$i++]="d4:4, d5:5, d6:6"; + $row[$i++]="d7:7, d8:8, d9:9"; + $row[$i++]="MUTE, d0:0, r_tune:PRECH"; + $row[$i++]=":blank, :blank, :blank"; + $row[$i++]="VOLUP, :blank, ch_up:CHUP"; + $row[$i++]=":VOL, :blank, :PROG"; + $row[$i++]="VOLDOWN, :blank, ch_down:CHDOWN"; + $row[$i++]=":blank, :blank, :blank"; + $row[$i++]="rew:REWIND, PLAY, FF"; + $row[$i++]="STOP, PAUSE, REC"; + + #Replace two or more spaces with one space + for (@row) {s/\s+/ /g} + + $row[$i++]="attr rc_iconpath icons/remotecontrol"; + $row[$i++]="attr rc_iconprefix black_btn_"; - $row[19]="attr rc_iconpath icons/remotecontrol"; - $row[20]="attr rc_iconprefix black_btn_"; return @row; } +# Callback from 95_remotecontrol for command layout. Creates svg layout +sub VIERA_RClayout_TV_SVG() { + my @row; + my $i = 0; + + $row[$i++]="power:rc_POWER.svg, TV:rc_TV2.svg, CHG_INPUT:rc_AV.svg"; + $row[$i++]="MENU:rc_MENU.svg, disp_mode:rc_ASPECT.svg, epg:rc_EPG.svg"; + $row[$i++]="VIERA_LINK:rc_VIERA_LINK.svg, VTOOLS:rc_VIERA_TOOLS.svg, INTERNET:rc_WEB.svg"; + $row[$i++]=":rc_BLANK.svg, :rc_BLANK.svg, :rc_BLANK.svg"; + $row[$i++]="INFO:rc_INFO2.svg, UP:rc_UP.svg, cancel:rc_EXIT.svg"; + $row[$i++]="LEFT:rc_LEFT.svg, ENTER:rc_dot.svg, RIGHT:rc_RIGHT.svg"; + $row[$i++]="SUBMENU:rc_OPTIONS.svg, DOWN:rc_DOWN.svg, RETURN:rc_BACK.svg"; + $row[$i++]="red:rc_RED.svg, :rc_BLANK.svg, green:rc_GREEN.svg"; + $row[$i++]="yellow:rc_YELLOW.svg, :rc_BLANK.svg, blue:rc_BLUE.svg"; + $row[$i++]="d1:rc_1.svg, d2:rc_2.svg, d3:rc_3.svg"; + $row[$i++]="d4:rc_4.svg, d5:rc_5.svg, d6:rc_6.svg"; + $row[$i++]="d7:rc_7.svg, d8:rc_8.svg, d9:rc_9.svg"; + $row[$i++]="MUTE:rc_MUTE.svg, d0:rc_0.svg, r_tune:rc_BACK.svg"; + $row[$i++]=":rc_BLANK.svg, :rc_BLANK.svg, :rc_BLANK.svg"; + $row[$i++]="VOLUP:rc_UP.svg, :rc_BLANK.svg, ch_up:rc_UP.svg"; + $row[$i++]=":rc_VOL.svg, :rc_BLANK.svg, :rc_PROG.svg"; + $row[$i++]="VOLDOWN:rc_DOWN.svg, :rc_BLANK.svg, ch_down:rc_DOWN.svg"; + $row[$i++]=":rc_BLANK.svg, :rc_BLANK.svg, :rc_BLANK.svg"; + $row[$i++]="rew:rc_REW.svg, PLAY:rc_PLAY.svg, FF:rc_FF.svg"; + $row[$i++]="STOP:rc_STOP.svg, PAUSE:rc_PAUSE.svg, REC:rc_REC.svg"; + + #Replace two or more spaces with one space + for (@row) {s/\s+/ /g} + return @row; +} + +# Create RAW Data to sent pressed keys of remoteControl to device. +# Param1: Hash of FHEM-Device +# Param2: Name of key to send +# Return: RAW html request for xml soap sub VIERA_BuildXML_NetCtrl($$){ my ($hash, $command) = @_; my $host = $hash->{helper}{HOST}; + my $port = $hash->{helper}{PORT}; my $callsoap = ""; my $message = ""; @@ -468,7 +541,7 @@ sub VIERA_BuildXML_NetCtrl($$){ $size = length($callsoap); $head .= "POST /nrc/control_0 HTTP/1.1\r\n"; - $head .= "Host: $host:55000\r\n"; + $head .= "Host: $host:$port\r\n"; $head .= "SOAPACTION: \"urn:panasonic-com:service:p00NetworkControl:1#X_SendKey\"\r\n"; $head .= "Content-Type: text/xml; charset=\"utf-8\"\r\n"; $head .= "Content-Length: $size\r\n"; @@ -476,20 +549,27 @@ sub VIERA_BuildXML_NetCtrl($$){ $message .= $head; $message .= $callsoap; - Log3 $hash, 5, "VIERA: Building XML SOAP (NetworkControl) for command $command to host $host:\n$message"; + #Log3 $hash, 5, "VIERA: Building XML SOAP (NetworkControl) for command $command to host $host:\n$message"; return $message; } +# Create RAW Data to send or get volume/mute state +# Param1: Hash of FHEM-Device +# Param2: get|set +# Param3: volume|mute +# Param4: value for set command +# Return: RAW html request for xml soap sub VIERA_BuildXML_RendCtrl($$$$){ my ($hash, $methode, $command, $value) = @_; my $host = $hash->{helper}{HOST}; + my $port = $hash->{helper}{PORT}; my $callsoap = ""; my $message = ""; my $head = ""; my $size = ""; - Log3 $hash, 5, "DEBUG: $command with $value to $host"; + #Log3 $hash, 5, "VIERA: $command with $value to $host"; $callsoap .= "\r\n"; $callsoap .= "\r\n"; @@ -504,8 +584,8 @@ sub VIERA_BuildXML_RendCtrl($$$$){ $size = length($callsoap); - $head .= "POST /dmr/control_0 HTTP/1.1\r\n"; - $head .= "Host: $host:55000\r\n"; + $head .= "POST /dmr/control_0 HTTP/1.0\r\n"; + $head .= "Host: $host:$port\r\n"; $head .= "SOAPACTION: \"urn:schemas-upnp-org:service:RenderingControl:1#$methode$command\"\r\n"; $head .= "Content-Type: text/xml; charset=\"utf-8\"\r\n"; $head .= "Content-Length: $size\r\n"; @@ -513,9 +593,133 @@ sub VIERA_BuildXML_RendCtrl($$$$){ $message .= $head; $message .= $callsoap; - Log3 $hash, 5, "VIERA: Building XML SOAP (RenderingControl) for command $command with value $value to host $host:\n$message"; + #Log3 $hash, 5, "VIERA: Building XML SOAP (RenderingControl) for command $command with value $value to host $host:\n$message"; return $message; } + +# Get volume and mute state from device. This function is called non blocking! +# Param1: Hash of FHEM-Device +# Return: || +sub VIERA_GetDoIt($) { + my ($hash) = @_; + my $myVol = ""; + my $myMute = ""; + + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDoIt()]: BlockingCall for ".$hash->{NAME}." start..."; + + my $returnVol = VIERA_connection($hash, VIERA_BuildXML_RendCtrl($hash, "Get", "Volume", "")); + Log3 $hash, 5, "VIERA[NonBlocking-VIERA_GetDoIt()]: GetStatusVol-Request returned: $returnVol" if(defined($returnVol)); + if(not defined($returnVol) or $returnVol eq "") { + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDoIt()]: GetStatusVol-Request NO SOCKET!"; + + return $hash->{NAME}. "|". + "error-noSocket" . "|". + "error-noSocket"; + } + + my $returnMute = VIERA_connection($hash, VIERA_BuildXML_RendCtrl($hash, "Get", "Mute", "")); + Log3 $hash, 5, "VIERA[NonBlocking-VIERA_GetDoIt()]: GetStatusMute-Request returned: $returnMute" if(defined($returnMute)); + if(not defined($returnMute) or $returnMute eq "") { + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDoIt()]: GetStatusMute-Request NO SOCKET!"; + + return $hash->{NAME}. "|". + "error-noSocket" . "|". + "error-noSocket"; + } + + if ($returnVol =~ /HTTP\/1\.1 ([\d]{3}) (.*)/) { + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDoIt()]: Received HTTP Code $1 $2"; + $myVol = "error-$1 $2" if ($1 ne "200"); + } + if($returnVol =~ /(.+)<\/CurrentVolume>/){ + $myVol = $1; + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDoIt()]: Received volume with level $myVol"; + } + + if ($returnMute =~ /HTTP\/1\.1 ([\d]{3}) (.*)/) { + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDoIt()]: Received HTTP Code $1 $2"; + $myMute = "error-$1 $2" if ($1 ne "200"); + } + if($returnMute =~ /(.+)<\/CurrentMute>/){ + $myMute = $1; + if ($myMute == 0) { $myMute = "off"; } else { $myMute = "on";} + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDoIt()]: Received mute state $myMute"; + } + + return $hash->{NAME}. "|". + "$myVol" . "|". + "$myMute"; +} + +# Callback of non blocking function VIERA_GetDoIt. Parse the results and set readings at fhem-device +# Param1: || +# volume level = 0 - 100 +# mute state = 1 or 0 +# If no socket is available Par1 and Par2 contains "error" +# Return: no return code +#################################################### +sub VIERA_GetDone($) { + my ($string) = @_; + return unless(defined($string)); + + my @a = split("\\|",$string); + my $name = shift(@a); + my $myVol = shift(@a); + my $myMute = shift(@a); + my $hash = $defs{$name}; + + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDone()]: Param: $string"; + + if ($myVol =~ /error-(.*)/ || $myMute =~ /error-(.*)/) { + if ($1 eq "noSocket") { + Log3 $name, 4, "VIERA[NonBlocking-VIERA_GetDone()]: Seems to be there is no socket available. Guessing TV is off!"; + if (ReadingsVal($name,"state","absent") ne "absent") { + readingsBeginUpdate($hash); + readingsBulkUpdate($hash, "state", "absent"); + readingsBulkUpdate($hash, "power", "off"); + readingsBulkUpdate($hash, "presence", "absent"); + readingsEndUpdate($hash, 1); + } + delete($hash->{helper}{RUNNING_PID_GET}); + return; + } + else { + Log3 $name, 3, "VIERA[NonBlocking-VIERA_GetDone()]: TV answered with $1. Seems to be on but delivering no data"; + return; + } + } + + readingsBeginUpdate($hash); + if ($myVol != ReadingsVal($name, "volume", "0")) { + Log3 $hash, 4, "VIERA[NonBlocking-VIERA_GetDone()]: Set reading volume to $myVol"; + readingsBulkUpdate($hash, "volume", $myVol); + } + + if ($myMute ne ReadingsVal($name, "mute", "0")) { + Log3 $name, 4, "VIERA[NonBlocking-VIERA_GetDone()]: Set reading mute to $myMute"; + readingsBulkUpdate($hash, "mute", $myMute); + } + + if (ReadingsVal($name,"state","absent") ne "on") { + readingsBulkUpdate($hash, "state", "on"); + readingsBulkUpdate($hash, "power", "on"); + readingsBulkUpdate($hash, "presence", "present"); + } + readingsEndUpdate($hash, 1); + + delete($hash->{helper}{RUNNING_PID_GET}); +} + +# Callback of non blocking when function VIERA_GetDoIt runs into timeout. +# Param1: Hash of FHEM-Device +# Return: no return code +sub VIERA_GetAbortFn($) { + my ($hash) = @_; + + delete($hash->{helper}{RUNNING_PID_GET}); + Log3 $hash, 2, "VIERA[NonBlocking-VIERA_GetAbortFn()]: BlockingCall for $hash->{NAME} was aborted, timeout reached"; +} + 1; =pod @@ -537,7 +741,11 @@ sub VIERA_BuildXML_RendCtrl($$$$){ Defining a VIERA device will schedule an internal task (interval can be set with optional parameter <interval> in seconds, if not set, the value is 30 seconds), which periodically reads the status of volume and mute status and triggers - notify/filelog commands.

+ notify/filelog commands. +

+ Notes:
+
    Activate volume remotecontrol by DLNA: Menu -> Setup -> Network Setup -> Network Link Settings -> DLNA RemoteVolume -> On
+
Example:
    define myTV1 VIERA 192.168.178.20

    @@ -564,6 +772,7 @@ sub VIERA_BuildXML_RendCtrl($$$$){ channelDown
    statusRequest
    remoteControl <command>
    + input [hdmi1|hdmi2|hdmi3|hdmi4|sdCard|tv]
@@ -634,10 +843,6 @@ sub VIERA_BuildXML_RendCtrl($$$$){ set <name> volume 20
set <name> remoteControl CH_DOWN
- -
- Notes:
-
    Activate volume remotecontrol by DLNA: Menu -> Setup -> Network Setup -> Network Link Settings -> DLNA RemoteVolume -> On

@@ -658,7 +863,7 @@ sub VIERA_BuildXML_RendCtrl($$$$){
Attributes -
    N/A
+
    blocking [0|1]

@@ -694,6 +899,9 @@ sub VIERA_BuildXML_RendCtrl($$$$){ den Status der Lautstärke und des Mute-Zustand ausliest. Das Intervall des Timer kann über den Parameter <interval> geändert werden. Wird kein Interval angegeben, liest das Modul alle 30 Sekunden die Werte aus und triggert ein notify.

+ Anmerkung:
+
    Aktivieren von Fernbedienung der Lautstärke per DLNA: Menü -> Setup -> Netzwerk-Setup -> Netzwerkverbindungsein. -> DLNA-Fernbed. Lautst. -> Ein
+
Beispiel:
    define myTV1 VIERA 192.168.178.20

    @@ -719,6 +927,7 @@ sub VIERA_BuildXML_RendCtrl($$$$){ channelDown
    statusRequest
    remoteControl <command>
    + input [hdmi1|hdmi2|hdmi3|hdmi4|sdCard|tv]
    @@ -787,11 +996,7 @@ sub VIERA_BuildXML_RendCtrl($$$$){ set <name> mute on
    set <name> volume 20
    set <name> remoteControl CH_DOWN
    -
- -
- Anmerkung:
-
    Aktivieren von Fernbedienung der Lautstärke per DLNA: Menü -> Setup -> Netzwerk-Setup -> Netzwerkverbindungsein. -> DLNA-Fernbed. Lautst. -> Ein
+
@@ -812,7 +1017,7 @@ sub VIERA_BuildXML_RendCtrl($$$$){
Attribute -
    N/A
+
    blocking [0|1]

diff --git a/fhem/www/images/fhemSVG/rc_ASPECT.svg b/fhem/www/images/fhemSVG/rc_ASPECT.svg new file mode 100644 index 000000000..d42656934 --- /dev/null +++ b/fhem/www/images/fhemSVG/rc_ASPECT.svg @@ -0,0 +1,91 @@ + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/fhem/www/images/fhemSVG/rc_BLANK2.svg b/fhem/www/images/fhemSVG/rc_BLANK2.svg new file mode 100644 index 000000000..e39cfec17 --- /dev/null +++ b/fhem/www/images/fhemSVG/rc_BLANK2.svg @@ -0,0 +1,55 @@ + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + diff --git a/fhem/www/images/fhemSVG/rc_INFO2.svg b/fhem/www/images/fhemSVG/rc_INFO2.svg new file mode 100644 index 000000000..165810bce --- /dev/null +++ b/fhem/www/images/fhemSVG/rc_INFO2.svg @@ -0,0 +1,71 @@ + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + + + + + + + diff --git a/fhem/www/images/fhemSVG/rc_PROG.svg b/fhem/www/images/fhemSVG/rc_PROG.svg new file mode 100644 index 000000000..c4460e493 --- /dev/null +++ b/fhem/www/images/fhemSVG/rc_PROG.svg @@ -0,0 +1,77 @@ + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + + + + + + + diff --git a/fhem/www/images/fhemSVG/rc_TV2.svg b/fhem/www/images/fhemSVG/rc_TV2.svg new file mode 100644 index 000000000..8c638eebe --- /dev/null +++ b/fhem/www/images/fhemSVG/rc_TV2.svg @@ -0,0 +1,75 @@ + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + + + + + + + + diff --git a/fhem/www/images/fhemSVG/rc_VIERA_LINK.svg b/fhem/www/images/fhemSVG/rc_VIERA_LINK.svg new file mode 100644 index 000000000..b9fb83fb2 --- /dev/null +++ b/fhem/www/images/fhemSVG/rc_VIERA_LINK.svg @@ -0,0 +1,103 @@ + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/fhem/www/images/fhemSVG/rc_VIERA_TOOLS.svg b/fhem/www/images/fhemSVG/rc_VIERA_TOOLS.svg new file mode 100644 index 000000000..47d7b2aa4 --- /dev/null +++ b/fhem/www/images/fhemSVG/rc_VIERA_TOOLS.svg @@ -0,0 +1,107 @@ + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/fhem/www/images/fhemSVG/rc_VOL.svg b/fhem/www/images/fhemSVG/rc_VOL.svg new file mode 100644 index 000000000..1bb2f58de --- /dev/null +++ b/fhem/www/images/fhemSVG/rc_VOL.svg @@ -0,0 +1,74 @@ + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + + + + + +