diff --git a/fhem/CHANGED b/fhem/CHANGED index 88a31b027..70f60d484 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. + - feature: new module LGTV_IP12 for controlling LG SmartTV's manufactured + between 2012-2014 via network connection - feature: 30_MilightBridge: Support tcp bridge. - bugfix: 30_MilightBridge/98_ping: Use Blocking.pm for ping checks so it does not block main thread. diff --git a/fhem/FHEM/82_LGTV_IP12.pm b/fhem/FHEM/82_LGTV_IP12.pm new file mode 100755 index 000000000..57aaceadd --- /dev/null +++ b/fhem/FHEM/82_LGTV_IP12.pm @@ -0,0 +1,868 @@ +# $Id$ +############################################################################## +# +# 82_LGTV_IP12.pm +# An FHEM Perl module for controlling LG Smart TV's which were +# release between 2012 - 2014. +# +# based on 82_LGTV_IP12.pm from Julian Tatsch (http://www.tatsch-it.de/tag/lgtv/) +# +# Copyright by Markus Bloch +# e-mail: Notausstieg0309@googlemail.com +# +# This file is part of fhem. +# +# Fhem is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# Fhem is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with fhem. If not, see . +# +############################################################################## + +package main; + +use warnings; +use strict; +use HttpUtils; + + +sub LGTV_IP12_displayPairingCode($); +sub LGTV_IP12_Pair($$); +sub LGTV_IP12_getInfo($$); +sub LGTV_IP12_sendCommand($$); + +# remote control codes +my %LGTV_IP12_rcCodes = ( + "power"=>1, + "0"=>2, + "1"=>3, + "2"=>4, + "3"=>5, + "4"=>6, + "5"=>7, + "6"=>8, + "7"=>9, + "8"=>10, + "9"=>11, + "up"=>12, + "down"=>13, + "left"=>14, + "right"=>15, + "ok"=>20, + "home"=>21, + "menu"=>22, + "back"=>23, + "volumeUp"=>24, + "volumeDown"=>25, + "mute"=>26, + "channelUp"=>27, + "channelDown"=>28, + "blue"=>29, + "green"=>30, + "red"=>31, + "yellow"=>32, + "play"=>33, + "pause"=>34, + "stop"=>35, + "fastForward"=>36, + "rewind"=>37, + "skipForward"=>38, + "skipBackward"=>39, + "record"=>40, + "recordingList"=>41, + "repeat"=>42, + "liveTv"=>43, + "epg"=>44, + "info"=>45, + "ratio"=>46, + "input"=>47, + "PiP"=>48, + "subtitle"=>49, + "proglist"=>50, + "teletext"=>51, + "mark"=>52, + "3Dvideo"=>400, + "3D_L/R"=>401, + "dash"=>402, + "prevchannel"=>403, + "favouriteChannel"=>404, + "quickMenu"=>405, + "textOption"=>406, + "audioDescription"=>407, + "netCast"=>408, + "energySaving"=>409, + "avMode"=>410, + "simplink"=>411, + "exit"=>412, + "reservationProglist"=>413, + "PiP_channelUp"=>414, + "PiP_channelDown"=>415, + "switchPriSecVideo"=>416, + "myApps"=>417, +); + +sub +LGTV_IP12_Initialize($) +{ + my ($hash) = @_; + + $hash->{DefFn} = "LGTV_IP12_Define"; + $hash->{DeleteFn} = "LGTV_IP12_Delete"; + $hash->{SetFn} = "LGTV_IP12_Set"; + $hash->{GetFn} = "LGTV_IP12_Get"; + $hash->{AttrFn} = "LGTV_IP12_Attr"; + $hash->{NotifyFn} = "LGTV_IP12_Notify"; + $hash->{NOTIFYDEV} = "global"; + $hash->{AttrList} = "do_not_notify:0,1 pairingcode request-timeout:1,2,3,4,5 disable:0,1 ".$readingFnAttributes; +} + +sub +LGTV_IP12_Define($$) +{ + my ($hash, $def) = @_; + my @args = split("[ \t]+", $def); + my $name = $hash->{NAME}; + if (int(@args) < 2) + { + return "LGTV_IP12: not enough arguments. Usage: " . + "define LGTV_IP12 "; + } + + $hash->{HOST} = $args[2]; + $hash->{PORT} = "8080"; + + # if an update interval was given which is greater than zero, use it. + if(defined($args[3]) and $args[3] > 0) + { + $hash->{helper}{OFF_INTERVAL} = $args[3]; + } + else + { + $hash->{helper}{OFF_INTERVAL} = 30; + } + + if(defined($args[4]) and $args[4] > 0) + { + $hash->{ON_INTERVAL} = $args[4]; + $hash->{OFF_INTERVAL} = $hash->{helper}{OFF_INTERVAL}; + $hash->{helper}{ON_INTERVAL} = $args[4]; + } + else + { + $hash->{INTERVAL} = $hash->{helper}{OFF_INTERVAL}; + $hash->{helper}{ON_INTERVAL} = $hash->{helper}{OFF_INTERVAL}; + } + + $hash->{helper}{DISABLED} = 0 unless(exists($hash->{helper}{DISABLED})); + + $hash->{STATE} = 'defined'; + + return undef; +} + +sub +LGTV_IP12_Get($@) +{ + # not implemented yet + +} +sub +LGTV_IP12_Notify($$) +{ + my ($hash,$dev) = @_; + my $name = $hash->{NAME}; + + return if($dev->{NAME} ne "global"); + return if(!grep(m/^INITIALIZED|REREADCFG$/, @{$dev->{CHANGED}})); + + if(defined(AttrVal($name, "pairingcode", undef)) and AttrVal($name, "pairingcode", undef) =~/^\d{6}$/) + { + Log3 $name, 3, "LGTV_IP12 ($name) - try pairing with pairingcode ".AttrVal($name, "pairingcode", undef); + LGTV_IP12_Pair($hash, AttrVal($name, "pairingcode", undef)); + } + + LGTV_IP12_ResetTimer($hash, 0); +} + +sub +LGTV_IP12_Set($@) +{ + my ($hash, @args) = @_; + my $name = $hash->{NAME}; + + my $what = $args[1]; + my $arg = $args[2]; + + my $usage = "Unknown argument $what, choose one of ". "statusRequest:noArg ". + "showPairCode:noArg ". + "removePairing:noArg ". + "remoteControl:".join(",", sort keys %LGTV_IP12_rcCodes)." ". + (exists($hash->{helper}{CHANNEL_LIST}) ? "channelDown:noArg channelUp:noArg channel:".join(",",sort {$a <=> $b} keys %{$hash->{helper}{CHANNEL_LIST}}) : "")." ". + (exists($hash->{helper}{APP_LIST}) ? "startApp:".join(",",sort {$a cmp $b} keys %{$hash->{helper}{APP_LIST}})." stopApp:".join(",",sort {$a cmp $b} keys %{$hash->{helper}{APP_LIST}}) : "") + ; + + if($what eq "showPairCode") + { + LGTV_IP12_HttpGet($hash, "/udap/api/pairing", $what, undef, "showKey"); + } + elsif($what eq "removePairing") + { + LGTV_IP12_HttpGet($hash, "/udap/api/pairing", $what, undef, "byebye8080"); + } + elsif($what =~ /^(channel|channelUp|channelDown)$/) + { + unless(exists($hash->{helper}{CHANNEL_LIST})) + { + LGTV_IP12_RetrieveChannelList($hash); + } + + my $new_channel; + + if($what eq "channelUp" or $what eq "channelDown") + { + my $current_channel = ReadingsVal($name, "channel", undef); + + if(defined($current_channel) and $current_channel =~ /^\d+$/ and $current_channel > 0) + { + my $found = 0; + + $new_channel = (grep { $found++ < 1; } grep { ($what eq "channelUp" ? $_ > $current_channel : $_ < $current_channel ) } sort { ($what eq "channelUp" ? $a <=> $b : $b <=> $a) } grep { defined($_) and /^\d+$/ } keys %{$hash->{helper}{CHANNEL_LIST}})[0]; + + } + } + elsif($what eq "channel" and exists($hash->{helper}{CHANNEL_LIST}) and exists($hash->{helper}{CHANNEL_LIST}{$arg})) + { + $new_channel = $arg; + } + else + { + return $usage; + } + + if(defined($new_channel)) + { + Log3 $hash->{NAME}, 5 , "LGTV_IP12 (".$hash->{NAME}.") - set new channel: $new_channel"; + + my $xml = "HandleChannelChange"; + $xml .= "".$hash->{helper}{CHANNEL_LIST}{$new_channel}{major}.""; + $xml .= "".$hash->{helper}{CHANNEL_LIST}{$new_channel}{minor}.""; + $xml .= "".$hash->{helper}{CHANNEL_LIST}{$new_channel}{sourceIndex}.""; + $xml .= "".$hash->{helper}{CHANNEL_LIST}{$new_channel}{physicalNum}.""; + $xml .= ""; + + LGTV_IP12_HttpGet($hash, "/udap/api/command", "channel", $new_channel, $xml); + } + } + elsif($what eq "startApp" and exists($hash->{helper}{APP_LIST}) and exists($hash->{helper}{APP_LIST}{$arg})) + { + LGTV_IP12_HttpGet($hash, "/udap/api/command", $what, $arg, "AppExecute".$hash->{helper}{APP_LIST}{$arg}{auid}."".$hash->{helper}{APP_LIST}{$arg}{name}."".$hash->{helper}{APP_LIST}{$arg}{cpid}.""); + } + elsif($what eq "stopApp" and exists($hash->{helper}{APP_LIST}) and exists($hash->{helper}{APP_LIST}{$arg})) + { + LGTV_IP12_HttpGet($hash, "/udap/api/command", $what, $arg, "AppTerminate".$hash->{helper}{APP_LIST}{$arg}{auid}."".$hash->{helper}{APP_LIST}{$arg}{name}."".$hash->{helper}{APP_LIST}{$arg}{cpid}.""); + } + elsif($what eq "statusRequest") + { + LGTV_IP12_GetStatus($hash) + } + elsif($what eq "remoteControl" and exists($LGTV_IP12_rcCodes{$arg})) + { + LGTV_IP12_HttpGet($hash, "/udap/api/command", $what, $arg, "HandleKeyInput".$LGTV_IP12_rcCodes{$arg}.""); + } + else + { + return $usage; + } +} + +########################## +sub +LGTV_IP12_Attr(@) +{ + my @a = @_; + my $hash = $defs{$a[1]}; + + if($a[0] eq "set" && $a[2] eq "pairingcode") + { + # if a pairing code was set as attribute, try immediatly a pairing + LGTV_IP12_Pair($hash, $a[3]); + } + elsif($a[0] eq "del" && $a[2] eq "pairingcode") + { + # if a pairing code is removed, start unpairing + LGTV_IP12_HttpGet($hash, "/udap/api/pairing", "removePairing", undef, "byebye8080") if(exists($hash->{helper}{PAIRED}) and $hash->{helper}{PAIRED} == 1); + } + + if($a[0] eq "set" && $a[2] eq "disable") + { + if($a[3] eq "0") + { + $hash->{helper}{DISABLED} = 0; + } + elsif($a[3] eq "1") + { + $hash->{helper}{DISABLED} = 1; + readingsSingleUpdate($hash, "state", "disabled",1); + } + LGTV_IP12_ResetTimer($hash, 0); + } + elsif($a[0] eq "del" && $a[2] eq "disable") + { + $hash->{helper}{DISABLED} = 0; + LGTV_IP12_ResetTimer($hash, 0); + } + + return undef; +} + + +sub +LGTV_IP12_Delete($$) +{ + my ($hash, $name) = @_; + # unpairing + LGTV_IP12_HttpGet($hash, "/udap/api/pairing", "removePairing", undef, "byebye8080") if(exists($hash->{helper}{PAIRED}) and $hash->{helper}{PAIRED} == 1); +} + + + +################################# + +# start a status request by starting the neccessary requests +sub +LGTV_IP12_GetStatus($) +{ + my ($hash) = @_; + + unless(exists($hash->{helper}{CHANNEL_LIST}) and ReadingsVal($hash->{NAME}, "state", "off") eq "on") + { + LGTV_IP12_RetrieveChannelList($hash); + } + + unless(exists($hash->{helper}{APP_LIST}) and ReadingsVal($hash->{NAME}, "state", "off") eq "on") + { + LGTV_IP12_HttpGet($hash, "/udap/api/data?target=applist_get&type=1&index=0&number=0", "statusRequest", "appList", undef); + } + + LGTV_IP12_HttpGet($hash, "/udap/api/data?target=cur_channel", "statusRequest", "currentChannel"); + + LGTV_IP12_HttpGet($hash, "/udap/api/data?target=volume_info", "statusRequest", "volumeInfo"); + + LGTV_IP12_HttpGet($hash, "/udap/api/data?target=is_3d", "statusRequest", "is3d"); + + LGTV_IP12_ResetTimer($hash); +} + +sub +LGTV_IP12_ParseHttpResponse($$$) +{ + + my ( $param, $err, $data ) = @_; + + my $hash = $param->{hash}; + my $name = $hash->{NAME}; + my $cmd = $param->{cmd}; + my $arg = $param->{arg}; + + $err = "" unless(defined($err)); + $data = "" unless(defined($data)); + + # we successfully received a HTTP status code in the response + if($data eq "" and exists($param->{code})) + { + # when a HTTP 401 was received => UNAUTHORIZED => No Pairing + if($param->{code} eq 401) + { + Log3 $name, 3, "LGTV_IP12 ($name) - failed to execute \"$cmd".(defined($arg) ? " ".(split("\\|", $arg))[0] : "")."\": Device is not paired"; + + if(exists($hash->{helper}{PAIRED})) + { + if($hash->{helper}{PAIRED} == 1) + { + $hash->{helper}{PAIRED} = 0; + } + } + + # If a pairing code is set as attribute, try one repair (when $hash->{helper}{PAIRED} == -1) + if(defined(AttrVal($name, "pairingcode", undef)) and AttrVal($name, "pairingcode", undef) =~/^\d{6}$/) + { + Log3 $name, 3, "LGTV_IP12 ($name) - try repairing with pairingcode ".AttrVal($name, "pairingcode", undef); + LGTV_IP12_Pair($hash, AttrVal($name, "pairingcode", undef)); + return; + } + } + + if($cmd eq "channel" and $param->{code} == 200) + { + readingsSingleUpdate($hash, $cmd, $arg, 1); + LGTV_IP12_ResetTimer($hash, 2); + } + } + + + # if an error was occured, raise a log entry + if($err ne "") + { + Log3 $name, 5, "LGTV_IP12 ($name) - could not execute command \"$cmd".(defined($arg) ? " ".(split("\\|", $arg))[0] : "")."\" - $err"; + + readingsSingleUpdate($hash, "state", "off", 1); + } + + # if the response contains data, examine it. + if($data ne "") + { + Log3 $name, 5, "LGTV_IP12 ($name) - got response for \"$cmd".(defined($arg) ? " ".(split("\\|", $arg))[0] : "")."\": $data"; + + readingsSingleUpdate($hash, "state", "on", 1); + + if($cmd eq "statusRequest") + { + readingsBeginUpdate($hash); + + if($arg eq "volumeInfo") + { + if($data =~ /(.+?)<\/level>/) + { + readingsBulkUpdate($hash, "volume", $1); + } + + if($data =~ /(.+?)<\/mute>/) + { + readingsBulkUpdate($hash, "mute", $1); + } + } + + if($arg eq "currentChannel") + { + if($data =~ /(.+?)<\/inputSourceName>/) + { + readingsBulkUpdate($hash, "input", LGTV_IP12_html2txt($1)); + } + + if($data =~ /(.+?)<\/labelName>/) + { + readingsBulkUpdate($hash, "inputLabel", LGTV_IP12_html2txt($1)); + } + + if($data =~ /(.+?)<\/chname>/) + { + readingsBulkUpdate($hash, "channelName", LGTV_IP12_html2txt($1)); + } + + if($data =~ /(.+?)<\/major>/) + { + readingsBulkUpdate($hash, "channel", $1); + } + + if($data =~ /(.+?)<\/progName>/) + { + readingsBulkUpdate($hash, "currentProgram", LGTV_IP12_html2txt($1)); + } + } + + if($arg eq "is3d") + { + if($data =~ /(.+?)<\/is3D>/) + { + readingsBulkUpdate($hash, "3D", $1); + } + } + + if($arg eq "appList") + { + while($data =~ /([0-9a-f]+)<\/auid>\s*([^<]+?)\s*<\/name>(\d+)<\/type>([\w\d_-]*)<\/cpid>.*?<\/data>/gci) + { + my @fields = ($1,$2,$3,$4); + my $index = $2; + $index =~ s/[^a-z0-9\.-_ ]//gi; + $index =~ s/[\s,]+/_/g; + $hash->{helper}{APP_LIST}{$index}{auid} = $fields[0]; + $hash->{helper}{APP_LIST}{$index}{name} = $fields[1]; + $hash->{helper}{APP_LIST}{$index}{type} = $fields[2]; + $hash->{helper}{APP_LIST}{$index}{cpid} = $fields[3]; + } + } + + readingsEndUpdate($hash, 1); + + LGTV_IP12_RetrieveChannelList($hash) if(not exists($hash->{helper}{CHANNEL_LIST})); + } + } +} + +# executes a http request with or without data and starts the HTTP request non-blocking to avoid timing problems for other modules (e.g. HomeMatic) +sub +LGTV_IP12_HttpGet($$$$;$) +{ +my ($hash, $path, $cmd, $arg, $data) = @_; + + + + if(defined($data)) + { + Log3 $hash->{NAME}, 5 , "LGTV_IP12 (".$hash->{NAME}.") - sending POST request for command \"$cmd".(defined($arg) ? " ".(split("\\|", $arg))[0] : "")."\" to url $path: $data"; + # start a HTTP POST on the given url with content data + HttpUtils_NonblockingGet({ + url => "http://".$hash->{HOST}.":8080".$path, + timeout => AttrVal($hash->{NAME}, "request-timeout", 4), + noshutdown => 1, + header => "User-Agent: Linux/2.6.18 UDAP/2.0 CentOS/5.8\r\nContent-Type: text/xml; charset=utf-8\r\nConnection: Close", + data => "".$data."", + loglevel => ($hash->{helper}{AVAILABLE} ? undef : 5), + hash => $hash, + cmd => $cmd, + arg => $arg, + httpversion => "1.1", + callback => \&LGTV_IP12_ParseHttpResponse + }); + } + else + { + Log3 $hash->{NAME}, 5 , "LGTV_IP12 (".$hash->{NAME}.") - sending GET request for command \"$cmd".(defined($arg) ? " ".(split("\\|", $arg))[0] : "")."\" to url $path"; + + # start a HTTP GET on the given url + HttpUtils_NonblockingGet({ + url => "http://".$hash->{HOST}.":8080".$path, + timeout => AttrVal($hash->{NAME}, "request-timeout", 4), + noshutdown => 1, + header => "User-Agent: Linux/2.6.18 UDAP/2.0 CentOS/5.8", + loglevel => ($hash->{helper}{AVAILABLE} ? undef : 5), + hash => $hash, + cmd => $cmd, + arg => $arg, + httpversion => "1.1", + callback => \&LGTV_IP12_ParseHttpResponse + }); + } +} + +# sends the pairing request. +sub +LGTV_IP12_Pair($$) +{ + my ($hash, $code) = @_; + + LGTV_IP12_HttpGet($hash, "/udap/api/pairing", "pairing", $code, "hello$code8080"); + +} + +sub +LGTV_IP12_RetrieveChannelList($) +{ + my ($hash) = @_; + my $name = $hash->{NAME}; + + Log3 $name, 4 , "LGTV_IP12 ($name) - requesting channel list"; + + my ($err, $channel_list) = HttpUtils_BlockingGet({ + url => "http://".$hash->{HOST}.":8080/udap/api/data?target=channel_list", + timeout => AttrVal($hash->{NAME}, "request-timeout", 4), + noshutdown => 1, + header => "User-Agent: Linux/2.6.18 UDAP/2.0 CentOS/5.8", + loglevel => ($hash->{helper}{AVAILABLE} ? undef : 5), + httpversion => "1.1", + }); + + Log3 $name, 3 , "LGTV_IP12 ($name) - error while retrieving channel list: $err" if($err ne "" and $hash->{helper}{AVAILABLE}); + + return if(not defined($channel_list) or $channel_list eq ""); + + delete($hash->{helper}{CHANNEL_LIST}) if(exists($hash->{helper}{CHANNEL_LIST})); + + while($channel_list =~ /(.+?)<\/data>/gc) + { + my $channel = $1; + if($channel =~ /(\d+?)<\/major>/) + { + my $channel_major = $1; + $hash->{helper}{CHANNEL_LIST}{$channel_major}{major} = $channel_major; + + if($channel =~ /(\d+?)<\/minor>/) + { + $hash->{helper}{CHANNEL_LIST}{$channel_major}{minor} = $1; + } + + if($channel =~ /(\d+?)<\/sourceIndex>/) + { + $hash->{helper}{CHANNEL_LIST}{$channel_major}{sourceIndex} = $1; + } + + if($channel =~ /(\d+?)<\/physicalNum>/) + { + $hash->{helper}{CHANNEL_LIST}{$channel_major}{physicalNum} = $1; + } + + if($channel =~ /(.+?)<\/chname>/) + { + Log3 $name, 5 , "LGTV_IP12 ($name) - adding channel ".LGTV_IP12_html2txt($1); + $hash->{helper}{CHANNEL_LIST}{$channel_major}{chname} = LGTV_IP12_html2txt($1); + } + } + } +} + +sub LGTV_IP12_ResetTimer($;$) +{ + my ($hash, $interval) = @_; + + RemoveInternalTimer($hash); + + if($hash->{helper}{DISABLED} == 0) + { + if(defined($interval)) + { + InternalTimer(gettimeofday()+$interval, "LGTV_IP12_GetStatus", $hash, 0); + } + elsif(ReadingsVal($hash->{NAME}, "state", "off") eq "on") + { + InternalTimer(gettimeofday()+$hash->{helper}{ON_INTERVAL}, "LGTV_IP12_GetStatus", $hash, 0); + } + else + { + InternalTimer(gettimeofday()+$hash->{helper}{OFF_INTERVAL}, "LGTV_IP12_GetStatus", $hash, 0); + } + } +} +############################# +# convert all HTML entities into UTF-8 aquivalents +sub LGTV_IP12_html2txt($) +{ + my ($string) = @_; + + $string =~ s/&/&/g; + $string =~ s/&/&/g; + $string =~ s/ / /g; + $string =~ s/'/'/g; + $string =~ s/(\xe4|ä)/ä/g; + $string =~ s/(\xc4|Ä)/Ä/g; + $string =~ s/(\xf6|ö)/ö/g; + $string =~ s/(\xd6|Ö)/Ö/g; + $string =~ s/(\xfc|ü)/ü/g; + $string =~ s/(\xdc|Ü)/Ü/g; + $string =~ s/(\xdf|ß)/ß/g; + + $string =~ s/<.+?>//g; + $string =~ s/(^\s+|\s+$)//g; + + return $string; +} + +1; + +=pod +=item device +=begin html + + +

LGTV_IP12

+
    + This module controls LG SmartTV's which were released between 2012 - 2014 via network connection. You are able + to switch query it's power state, control the TV channels, open and close apps and send all remote control commands. +

    + For a list of supported models see the compatibility list for LG TV Remote smartphone app. +

    + + Define +
      + + define <name> LGTV_IP12 <ip-address> [<status_interval>] +

      + define <name> LGTV_IP12 <ip-address> [<off_status_interval>] [<on_status_interval>] +
      +

      + + Defining a LGTV_IP12 device will schedule an internal task (interval can be set + with optional parameter <status_interval> in seconds, if not set, the value is 30 + seconds), which periodically reads the status of the TV (power state, current channel, input, ...) + and triggers notify/FileLog commands. +

      + Different status update intervals depending on the power state can be given also. + If two intervals are given to the define statement, the first interval statement represents the status update + interval in seconds in case the device is off, absent or any other non-normal state. The second + interval statement is used when the device is on. + + Example:

      +
        + define TV LGTV_IP12 192.168.0.10 +

        + # With custom status interval of 60 seconds
        + define TV LGTV_IP12 192.168.0.10 60 +

        + # With custom "off"-interval of 60 seconds and "on"-interval of 10 seconds
        + define TV LGTV_IP12 192.168.0.10 60 10 +
      + +
    +

    + + + Set +
      + set <name> <command> [<parameter>] +

      + Currently, the following commands are defined. +

      +
        +
      • channel   -   set the current channel
      • +
      • channelUp   -   switches to next channel
      • +
      • channelDown   -   switches to previous channel
      • +
      • removePairing   -   deletes the pairing with the device
      • +
      • showPairCode   -   requests the TV to display the pair code on the TV screen. This pair code must be set in the attribute pairingcode
      • +
      • startApp   -   start a installed app on the TV
      • +
      • stopApp   -   stops a running app on the TV
      • +
      • statusRequest   -   requests the current status of the device
      • +
      • remoteControl up,down,...   -   sends remote control commands
      • +
      +
    +

    + + Get +
      + get <name> <reading> +

      + Currently, the get command only returns the reading values. For a specific list of possible values, see section "Generated Readings/Events". +
    +

    + + Attributes +
      +
    • do_not_notify
    • +
    • readingFnAttributes

    • +
    • disable
    • + Optional attribute to disable the internal cyclic status update of the player. Manual status updates via statusRequest command is still possible. +

      + Possible values: 0 => perform cyclic status update, 1 => don't perform cyclic status updates.

      +
    • request-timeout
    • + Optional attribute change the response timeout in seconds for all queries to the player. +

      + Possible values: 1-5 seconds. Default value is 4 seconds.

      +
    • pairingcode
    • + This attribute contains the pairing code to authenticate FHEM as trusted controller. The pairing code can be displayed via set command showPairCode +
    +

    + Generated Readings/Events:
    +
      +
    • 3D - The status of 3D playback (can be "true" or "false")
    • +
    • channel - The number of the current channel
    • +
    • channelName - The name of the current channel
    • +
    • currentProgram - The name of the running program of the current channel
    • +
    • input - The current input source (e.g. Antenna, Sattelite, HDMI1, ...)
    • +
    • inputLabel - The user defined name of the current input source
    • +
    • mute - Reports the current mute state (can be "on" or "off")
    • +
    • presence - Reports the presence state (can be "present" or "absent").
    • +
    • volume - Reports the volume state.
    • +
    +
+ + +=end html +=begin html_DE + + +

LGTV_IP12

+
    + Dieses Modul steuert SmartTV's des Herstellers LG welche zwischen 2012 und 2014 produziert wurden über die Netzwerkschnittstelle. + Es bietet die Möglichkeit den aktuellen TV Kanal zu steuern, sowie Apps zu starten, Fernbedienungsbefehle zu senden, sowie den aktuellen Status abzufragen. +

    + Es werden alle TV Modelle unterstützt, welche mit der LG TV Remote Smartphone App steuerbar sind. +

    + + Definition +
      + define <name> LGTV_IP12 <IP-Addresse> [<Status_Interval>] +

      + define <name> LGTV_IP12 <IP-Addresse> [<Off_Interval>] [<On_Interval>] +
      +

      + Bei der Definition eines LGTV_IP12-Moduls wird eine interne Routine in Gang gesetzt, welche regelmäßig + (einstellbar durch den optionalen Parameter <Status_Interval>; falls nicht gesetzt ist der Standardwert 30 Sekunden) + den Status des TV abfragt und entsprechende Notify-/FileLog-Definitionen triggert. +

      + Sofern 2 Interval-Argumente übergeben werden, wird der erste Parameter <Off_Interval> genutzt + sofern der TV ausgeschaltet oder nicht erreichbar ist. Der zweiter Parameter <On_Interval> + wird verwendet, sofern der TV eingeschaltet ist. +

      + Beispiel:

      +
        + define TV LGTV_IP12 192.168.0.10 +

        + # Mit modifiziertem Status Interval (60 Sekunden)
        + define TV LGTV_IP12 192.168.0.10 60 +

        + # Mit gesetztem "Off"-Interval (60 Sekunden) und "On"-Interval (10 Sekunden)
        + define TV LGTV_IP12 192.168.0.10 60 10 +
      +
    +

    + + Set-Kommandos +
      + set <Name> <Kommando> [<Parameter>] +

      + Aktuell werden folgende Kommandos unterstützt. +

      +
        +
      • channel <Nummer>  -   wählt den aktuellen TV-Kanal aus
      • +
      • channelUp   -   schaltet auf den nächsten Kanal um
      • +
      • channelDown   -   schaltet auf den vorherigen Kanal um
      • +
      • removePairing   -   löscht das Pairing zwischen FHEM und dem TV
      • +
      • showPairCode   -   zeigt den Pair-Code auf dem TV-Bildschirm an. Dieser Code muss im Attribut pairingcode gesetzt werden, damit FHEM mit dem TV kommunizieren kann.
      • +
      • startApp <Name>  -   startet eine installierte App
      • +
      • stopApp <Name>  -   stoppt eine laufende App
      • +
      • statusRequest   -   fragt den aktuellen Status ab
      • +
      • remoteControl up,down,...   -   sendet Fernbedienungsbefehle
      • +
      +
    +

    + + Get-Kommandos +
      + get <Name> <Readingname> +

      + Aktuell stehen via GET lediglich die Werte der Readings zur Verfügung. Eine genaue Auflistung aller möglichen Readings folgen unter "Generierte Readings/Events". +
    +

    + + Attribute +
      + +
    • do_not_notify
    • +
    • readingFnAttributes

    • +
    • disable
    • + Optionales Attribut zur Deaktivierung des zyklischen Status-Updates. Ein manuelles Update via statusRequest-Befehl ist dennoch möglich. +

      + Mögliche Werte: 0 => zyklische Status-Updates, 1 => keine zyklischen Status-Updates.

      +
    • request-timeout
    • + Optionales Attribut. Maximale Dauer einer Anfrage in Sekunden zum TV. +

      + Mögliche Werte: 1-5 Sekunden. Standartwert ist 4 Sekunden

      +
    • pairingcode
    • + Dieses Attribut speichert den Pairing Code um sich gegenüber dem TV als vertrauenswürdigen Controller zu authentifizieren. Der Pairing-Code kann via Set-Kommando showPairCode angezeigt werden. +
    +

    + Generierte Readings/Events:
    +
      +
    • 3D - Status des 3D-Wiedergabemodus ("true" => 3D Wiedergabemodus aktiv, "false" => 3D Wiedergabemodus nicht aktiv)
    • +
    • channel - Die Nummer des aktuellen TV-Kanals
    • +
    • channelName - Der Name des aktuellen TV-Kanals
    • +
    • currentProgram - Der Name der laufenden Sendung
    • +
    • input - Die aktuelle Eingangsquelle (z.B. Antenna, Sattelite, HDMI1, ...)
    • +
    • inputLabel - Die benutzerdefinierte Bezeichnung der aktuellen Eingangsquelle
    • +
    • mute on,off - Der aktuelle Stumm-Status ("on" => Stumm, "off" => Laut)
    • +
    • presence - Zeigt an, ob das Gerät aktuell empfangsbereit ist ("present" => Gerät ist empfangsbereit, "absent" => Gerät ist nicht empfangsbereit).
    • +
    • volume - Der aktuelle Lautstärkepegel.
    • +
    +
+=end html_DE + +=cut + + diff --git a/fhem/MAINTAINER.txt b/fhem/MAINTAINER.txt index 56ba79207..72f73fdf5 100644 --- a/fhem/MAINTAINER.txt +++ b/fhem/MAINTAINER.txt @@ -263,6 +263,7 @@ FHEM/80_M232.pm borisneubert http://forum.fhem.de Sonstige FHEM/80_xxLG7000.pm markusbloch http://forum.fhem.de Multimedia FHEM/81_M232Counter.pm borisneubert http://forum.fhem.de Sonstige Systeme FHEM/82_LGTV.pm markusbloch http://forum.fhem.de Multimedia +FHEM/82_LGTV_IP12.pm markusbloch http://forum.fhem.de Multimedia FHEM/82_M232Voltage.pm borisneubert http://forum.fhem.de Sonstige Systeme FHEM/87_WS2000.pm tdressler http://forum.fhem.de Sonstiges FHEM/88_ALL4000T.pm sachag http://forum.fhem.de Sonstiges