mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-07 16:59:18 +00:00
82_LGTV.pm & 80_xxLG7000.pm, Initial Release.
git-svn-id: https://svn.fhem.de/fhem/trunk@552 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
aeea6033a8
commit
5a5a579d14
@ -29,7 +29,7 @@
|
|||||||
#
|
#
|
||||||
# Contributed by Kai 'wusel' Siering <wusel+fhem@uu.org> in 2010
|
# Contributed by Kai 'wusel' Siering <wusel+fhem@uu.org> in 2010
|
||||||
# Based in part on work for FHEM by other authors ...
|
# Based in part on work for FHEM by other authors ...
|
||||||
# $Id: 70_SISPM.pm,v 1.3 2010-01-19 19:33:01 painseeker Exp $
|
# $Id: 70_SISPM.pm,v 1.4 2010-01-20 01:04:01 painseeker Exp $
|
||||||
###########################
|
###########################
|
||||||
|
|
||||||
package main;
|
package main;
|
||||||
@ -37,18 +37,6 @@ package main;
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
my %sets = (
|
|
||||||
"cmd" => "",
|
|
||||||
"freq" => "",
|
|
||||||
);
|
|
||||||
|
|
||||||
my %TranslatedCodes = (
|
|
||||||
"Date" => "Date",
|
|
||||||
);
|
|
||||||
|
|
||||||
my %WantedCodesForStatus = (
|
|
||||||
"Ti" => "Ti:",
|
|
||||||
);
|
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
sub
|
sub
|
||||||
@ -326,7 +314,7 @@ SISPM_Read($)
|
|||||||
|
|
||||||
if($inputline =~ /^Status of outlet (\d):\s+(.*)/) {
|
if($inputline =~ /^Status of outlet (\d):\s+(.*)/) {
|
||||||
if($currentserial ne "none") {
|
if($currentserial ne "none") {
|
||||||
Log 3, "SISPM found socket $1 on $currentserial, state $2";
|
Log 5, "SISPM found socket $1 on $currentserial, state $2";
|
||||||
my $dmsg="socket " . $currentserial . " $1 state " . $2;
|
my $dmsg="socket " . $currentserial . " $1 state " . $2;
|
||||||
my %addvals;
|
my %addvals;
|
||||||
Dispatch($hash, $dmsg, \%addvals);
|
Dispatch($hash, $dmsg, \%addvals);
|
||||||
|
411
fhem/FHEM/80_xxLG7000.pm
Normal file
411
fhem/FHEM/80_xxLG7000.pm
Normal file
@ -0,0 +1,411 @@
|
|||||||
|
#
|
||||||
|
# 80_xxLG7000.pm; an FHEM module for interfacing
|
||||||
|
# with LG's Scarlet Series of LCDs (e. g. LG 47LG7000)
|
||||||
|
#
|
||||||
|
# Written by Kai 'wusel' Siering <wusel+fhem@uu.org> around 2010-01-20
|
||||||
|
#
|
||||||
|
# re-using code of 80_M232.pm by Dr. Boris Neubert
|
||||||
|
##############################################
|
||||||
|
package main;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
|
||||||
|
sub xxLG7000Write($$);
|
||||||
|
sub xxLG7000GetData($$);
|
||||||
|
sub Log($$);
|
||||||
|
use vars qw {%attr %defs};
|
||||||
|
|
||||||
|
my %commands = (
|
||||||
|
"power state" => "ka %d FF\r",
|
||||||
|
"power on" => "ka %d 01\r",
|
||||||
|
"power off" => "ka %d 00\r",
|
||||||
|
"input AV1" => "xb %d 20\r",
|
||||||
|
"input AV2" => "xb %d 21\r",
|
||||||
|
"input AV3" => "xb %d 22\r",
|
||||||
|
"input AV4" => "xb %d 23\r",
|
||||||
|
"input Component" => "xb %d 40\r",
|
||||||
|
"input RGB-PC" => "xb %d 50\r",
|
||||||
|
"input HDMI1" => "xb %d 90\r",
|
||||||
|
"input HDMI2" => "xb %d 91\r",
|
||||||
|
"input HDMI3" => "xb %d 92\r",
|
||||||
|
"input HDMI4" => "xb %d 93\r",
|
||||||
|
"input DVBT" => "xb %d 00\r",
|
||||||
|
"input PAL" => "xb %d 10\r",
|
||||||
|
"selected input" => "xb %d FF\r",
|
||||||
|
"audio mute" => "ke %d 00\r",
|
||||||
|
"audio normal" => "ke %d 01\r",
|
||||||
|
);
|
||||||
|
|
||||||
|
my %responses = (
|
||||||
|
"a OK00" => "power off",
|
||||||
|
"a OK01" => "power on",
|
||||||
|
"b OK20" => "input AV1",
|
||||||
|
"b OK21" => "input AV2",
|
||||||
|
"b OK22" => "input AV3",
|
||||||
|
"b OK23" => "input AV4",
|
||||||
|
"b OK90" => "input HDMI1",
|
||||||
|
"b OK91" => "input HDMI2",
|
||||||
|
"b OK92" => "input HDMI3",
|
||||||
|
"b OK93" => "input HDMI4",
|
||||||
|
"b OK40" => "input Components",
|
||||||
|
"b OK50" => "input RGB-PC",
|
||||||
|
"b OK10" => "input PAL",
|
||||||
|
"b OK00" => "input DVB-T",
|
||||||
|
"e OK00" => "audio muted",
|
||||||
|
"e OK01" => "audio normal",
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
xxLG7000_Initialize($)
|
||||||
|
{
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
# Provider
|
||||||
|
$hash->{WriteFn} = "xxLG7000_Write";
|
||||||
|
$hash->{Clients} = ":LGTV:";
|
||||||
|
# No ReadFn as this is a purely command->response interface, in contrast
|
||||||
|
# to e. g. CUL which send's data on it's own. -wusel
|
||||||
|
|
||||||
|
# Consumer
|
||||||
|
$hash->{DefFn} = "xxLG7000_Define";
|
||||||
|
$hash->{UndefFn} = "xxLG7000_Undef";
|
||||||
|
# $hash->{GetFn} = "xxLG7000_Get";
|
||||||
|
# $hash->{SetFn} = "xxLG7000_Set";
|
||||||
|
$hash->{AttrList}= "SetID:01,02, loglevel:0,1,2,3,4,5";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
xxLG7000_Define($$)
|
||||||
|
{
|
||||||
|
my ($hash, $def) = @_;
|
||||||
|
my @a = split("[ \t][ \t]*", $def);
|
||||||
|
|
||||||
|
$hash->{STATE} = "Initialized";
|
||||||
|
|
||||||
|
my $dev = $a[2];
|
||||||
|
if($dev eq "none") {
|
||||||
|
Log 1, "xxLG7000 device is none, commands will be echoed only";
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log 3, "xxLG7000 opening device $dev";
|
||||||
|
my $po;
|
||||||
|
if ($^O eq 'MSWin32') {
|
||||||
|
eval ("use Win32::SerialPort;");
|
||||||
|
if ($@) {
|
||||||
|
$hash->{STATE} = "error using Modul Win32::SerialPort";
|
||||||
|
Log 1,"Error using Device::SerialPort";
|
||||||
|
return "Can't use Win32::SerialPort $@\n";
|
||||||
|
}
|
||||||
|
$po = new Win32::SerialPort ($dev, 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
eval ("use Device::SerialPort;");
|
||||||
|
if ($@) {
|
||||||
|
$hash->{STATE} = "error using Modul Device::SerialPort";
|
||||||
|
Log 1,"Error using Device::SerialPort";
|
||||||
|
return "Can't Device::SerialPort $@\n";
|
||||||
|
}
|
||||||
|
$po = new Device::SerialPort ($dev, 1);
|
||||||
|
}
|
||||||
|
if (!$po) {
|
||||||
|
$hash->{STATE} = "error opening device";
|
||||||
|
Log 1,"Error opening Serial Device $dev";
|
||||||
|
return "Can't open Device $dev: $^E\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
Log 3, "xxLG7000 opened device $dev";
|
||||||
|
$po->close();
|
||||||
|
|
||||||
|
$hash->{DeviceName} = $dev;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
xxLG7000_Undef($$)
|
||||||
|
{
|
||||||
|
my ($hash, $arg) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
foreach my $d (sort keys %defs) {
|
||||||
|
if(defined($defs{$d}) &&
|
||||||
|
defined($defs{$d}{IODev}) &&
|
||||||
|
$defs{$d}{IODev} == $hash)
|
||||||
|
{
|
||||||
|
my $lev = ($reread_active ? 4 : 2);
|
||||||
|
Log GetLogLevel($name,$lev), "deleting port for $d";
|
||||||
|
delete $defs{$d}{IODev};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# implement ReadyFn, only used for Win32
|
||||||
|
sub
|
||||||
|
xxLG7000_Ready($$)
|
||||||
|
{
|
||||||
|
my ($hash, $dev) = @_;
|
||||||
|
my $po=$dev||$hash->{po};
|
||||||
|
return 0 if !$po;
|
||||||
|
my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags)=$po->status;
|
||||||
|
return ($InBytes>0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
xxLG7000_Set($@)
|
||||||
|
{
|
||||||
|
my ($hash, @a) = @_;
|
||||||
|
my $u1 = "Usage: see commandref.html for details\n";
|
||||||
|
|
||||||
|
return $u1 if(int(@a) < 2);
|
||||||
|
my $msg;
|
||||||
|
my $reading= $a[1];
|
||||||
|
my $value;
|
||||||
|
my @legal;
|
||||||
|
|
||||||
|
if($reading eq "auto") {
|
||||||
|
return $u1 if(int(@a) !=3);
|
||||||
|
$value= $a[2];
|
||||||
|
@legal= (0..5,"none");
|
||||||
|
if(!grep($value eq $_, @legal)) {
|
||||||
|
return "Illegal value $value, possible values: @legal";
|
||||||
|
}
|
||||||
|
if($value eq "none") { $value= 0; } else { $value+=1; }
|
||||||
|
$msg= "M" . $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif($reading eq "start") {
|
||||||
|
return $u1 if(int(@a) !=2);
|
||||||
|
$msg= "Z1";
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif($reading eq "stop") {
|
||||||
|
return $u1 if(int(@a) !=2);
|
||||||
|
$msg= "Z0";
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif($reading eq "octet") {
|
||||||
|
return $u1 if(int(@a) !=3);
|
||||||
|
$value= $a[2];
|
||||||
|
@legal= (0..255);
|
||||||
|
if(!grep($value eq $_, @legal)) {
|
||||||
|
return "Illegal value $value, possible values: 0..255";
|
||||||
|
}
|
||||||
|
$msg= sprintf("W%02X", $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif($reading =~ /^io[0-7]$/) {
|
||||||
|
return $u1 if(int(@a) !=3);
|
||||||
|
$value= $a[2];
|
||||||
|
return $u1 unless($value eq "0" || $value eq "1");
|
||||||
|
$msg= "D" . substr($reading,2,1) . $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
else { return $u1; }
|
||||||
|
|
||||||
|
my $d = xxLG7000GetData($hash, $msg);
|
||||||
|
return "Read error" if(!defined($d));
|
||||||
|
return $d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
xxLG7000_Get($@)
|
||||||
|
{
|
||||||
|
|
||||||
|
my ($hash, @a) = @_;
|
||||||
|
my $u1 = "Usage: get <name> [an0..an5]\n" .
|
||||||
|
"get <name> [io0..io7]\n" .
|
||||||
|
"get <name> octet\n" .
|
||||||
|
"get <name> counter";
|
||||||
|
|
||||||
|
return $u1 if(int(@a) != 2);
|
||||||
|
|
||||||
|
my $name= $a[0];
|
||||||
|
my $reading= $a[1];
|
||||||
|
my $msg;
|
||||||
|
my $retval;
|
||||||
|
my ($count,$d,$state,$iscurrent,$voltage);
|
||||||
|
|
||||||
|
|
||||||
|
if($reading eq "counter") {
|
||||||
|
$msg= "z";
|
||||||
|
$d = xxLG7000GetData($hash, $msg);
|
||||||
|
return "Read error" if(!defined($d));
|
||||||
|
$count= hex $d;
|
||||||
|
$retval= $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif($reading =~ /^an[0-5]$/) {
|
||||||
|
$msg= "a" . substr($reading,2,1);
|
||||||
|
$d = xxLG7000GetData($hash, $msg);
|
||||||
|
return "Read error" if(!defined($d));
|
||||||
|
$voltage= (hex substr($d,0,3))*5.00/1024.0;
|
||||||
|
$iscurrent= substr($d,3,1);
|
||||||
|
$retval= $voltage; # . " " . $iscurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif($reading =~ /^io[0-7]$/) {
|
||||||
|
$msg= "d" . substr($reading,2,1);
|
||||||
|
$d = xxLG7000GetData($hash, $msg);
|
||||||
|
return "Read error" if(!defined($d));
|
||||||
|
$state= hex $d;
|
||||||
|
$retval= $state;
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif($reading eq "octet") {
|
||||||
|
$msg= "w";
|
||||||
|
$d = xxLG7000GetData($hash, $msg);
|
||||||
|
return "Read error" if(!defined($d));
|
||||||
|
$state= hex $d;
|
||||||
|
$retval= $state;
|
||||||
|
}
|
||||||
|
|
||||||
|
else { return $u1; }
|
||||||
|
|
||||||
|
$hash->{READINGS}{$reading}{VAL}= $retval;
|
||||||
|
$hash->{READINGS}{$reading}{TIME}= TimeNow();
|
||||||
|
|
||||||
|
return "$name $reading => $retval";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
xxLG7000_Write($$)
|
||||||
|
{
|
||||||
|
my ($hash,$msg) = @_;
|
||||||
|
my $dev = $hash->{DeviceName};
|
||||||
|
my $UnitNo=1;
|
||||||
|
my $ret;
|
||||||
|
my $retmsg;
|
||||||
|
|
||||||
|
my $sendstring=$commands{$msg};
|
||||||
|
|
||||||
|
if(!defined($sendstring)) {
|
||||||
|
return "Unknown command $msg, choose one of " . join(" ", sort keys %commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sendstring=sprintf($sendstring, $UnitNo); # FIXME! This needs to become a settable attribut!
|
||||||
|
$ret=xxLG7000GetData($hash, $sendstring);
|
||||||
|
|
||||||
|
Log 3, "xxLG7000_Write: wrote $msg, received $ret";
|
||||||
|
|
||||||
|
$retmsg=sprintf("%s %s", substr($ret, 0, 1), substr($ret, 5));
|
||||||
|
$retmsg=$responses{$retmsg};
|
||||||
|
if(!defined($retmsg)) {
|
||||||
|
if(substr($ret, 5, 2) eq "NG") {
|
||||||
|
$retmsg="error message";
|
||||||
|
Log 3, "xxLG7000_Write: error message: $ret";
|
||||||
|
} else {
|
||||||
|
$retmsg=sprintf("Unknown response %s, help me!");
|
||||||
|
Log 3, "xxLG7000_Write: $retmsg";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log 3, "xxLG7000_Write: returns $retmsg";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $retmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
sub
|
||||||
|
xxLG7000GetData($$)
|
||||||
|
{
|
||||||
|
my ($hash, $data) = @_;
|
||||||
|
my $dev=$hash->{DeviceName};
|
||||||
|
my $serport;
|
||||||
|
my $d = $data;
|
||||||
|
my $MSGACK= 'x';
|
||||||
|
|
||||||
|
if ($^O eq 'MSWin32') {
|
||||||
|
$serport=new Win32::SerialPort ($dev, 1);
|
||||||
|
} else {
|
||||||
|
$serport=new Device::SerialPort ($dev, 1);
|
||||||
|
}
|
||||||
|
if(!$serport) {
|
||||||
|
Log 3, "xxLG7000: Can't open $dev: $!";
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
$serport->reset_error();
|
||||||
|
$serport->baudrate(9800);
|
||||||
|
$serport->databits(8);
|
||||||
|
$serport->parity('none');
|
||||||
|
$serport->stopbits(1);
|
||||||
|
$serport->handshake('none');
|
||||||
|
$serport->write_settings;
|
||||||
|
$hash->{po}=$serport;
|
||||||
|
Log 4, "xxLG7000: Sending $d";
|
||||||
|
|
||||||
|
my $rm = "xxLG7000: ?";
|
||||||
|
|
||||||
|
$serport->lookclear;
|
||||||
|
$serport->write($d);
|
||||||
|
|
||||||
|
my $retval = "";
|
||||||
|
my $status = "";
|
||||||
|
my $nfound=0;
|
||||||
|
my $ret=undef;
|
||||||
|
sleep(1);
|
||||||
|
for(;;) {
|
||||||
|
if ($^O eq 'MSWin32') {
|
||||||
|
$nfound=xxLG7000_Ready($hash,undef);
|
||||||
|
} else {
|
||||||
|
my ($rout, $rin) = ('', '');
|
||||||
|
vec($rin, $serport->FILENO, 1) = 1;
|
||||||
|
$nfound = select($rin, undef, undef, 1.0); # 3 seconds timeout
|
||||||
|
if($nfound < 0) {
|
||||||
|
next if ($! == EAGAIN() || $! == EINTR() || $! == 0);
|
||||||
|
$rm="xxLG7000:Select error $nfound / $!";
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last if($nfound == 0);
|
||||||
|
|
||||||
|
my $out = $serport->read(1);
|
||||||
|
if(!defined($out) || length($out) == 0) {
|
||||||
|
$rm = "xxLG7000 EOF on $dev";
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($out eq $MSGACK) {
|
||||||
|
$rm= "xxLG7000: acknowledged";
|
||||||
|
Log 4, "xxLG7000: return value \'" . $retval . "\'";
|
||||||
|
$status= "ACK";
|
||||||
|
} else {
|
||||||
|
$retval .= $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($status) {
|
||||||
|
$ret=$retval;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DONE:
|
||||||
|
$serport->close();
|
||||||
|
undef $serport;
|
||||||
|
delete $hash->{po} if exists($hash->{po});
|
||||||
|
Log 4, $rm;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
195
fhem/FHEM/82_LGTV.pm
Normal file
195
fhem/FHEM/82_LGTV.pm
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
# 82_LGTV.pm; an FHEM high level module for interfacing
|
||||||
|
# with LG's Scarlet Series of LCDs (e. g. LG 47LG7000)
|
||||||
|
# Trying to implement a generic command set so that is
|
||||||
|
# is re-usable with other low-level drivers besides my
|
||||||
|
# 80_xxLG7000.pm for a serial connection.
|
||||||
|
#
|
||||||
|
# Written by Kai 'wusel' Siering <wusel+fhem@uu.org> around 2010-01-20
|
||||||
|
#
|
||||||
|
# re-using code of 82_M232Voltage.pm
|
||||||
|
# written by Dr. Boris Neubert 2007-12-24
|
||||||
|
# e-mail: omega at online dot de
|
||||||
|
#
|
||||||
|
##############################################
|
||||||
|
package main;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Time::HiRes qw(gettimeofday);
|
||||||
|
|
||||||
|
sub LGTV_Get($@);
|
||||||
|
sub LGTV_Define($$);
|
||||||
|
sub LGTV_GetStatus($);
|
||||||
|
|
||||||
|
my @commandlist = (
|
||||||
|
"power state",
|
||||||
|
"power on",
|
||||||
|
"power off",
|
||||||
|
"input AV1",
|
||||||
|
"input AV2",
|
||||||
|
"input AV3",
|
||||||
|
"input AV3",
|
||||||
|
"input Component",
|
||||||
|
"input RGB",
|
||||||
|
"input HDMI1",
|
||||||
|
"input HDMI2",
|
||||||
|
"input HDMI3",
|
||||||
|
"input HDMI4",
|
||||||
|
"input DVBT",
|
||||||
|
"input PAL",
|
||||||
|
"audio mute",
|
||||||
|
"audio normal",
|
||||||
|
"selected input"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub
|
||||||
|
LGTV_Initialize($)
|
||||||
|
{
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
# $hash->{GetFn} = "LGTV_Get";
|
||||||
|
$hash->{SetFn} = "LGTV_Set";
|
||||||
|
$hash->{DefFn} = "LGTV_Define";
|
||||||
|
|
||||||
|
$hash->{AttrList} = "dummy:1,0 model:LGTV loglevel:0,1,2,3,4,5";
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub
|
||||||
|
LGTV_GetStatus($)
|
||||||
|
{
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
if(!$hash->{LOCAL}) {
|
||||||
|
InternalTimer(gettimeofday()+60, "LGTV_GetStatus", $hash, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
my $d = IOWrite($hash, "power state");
|
||||||
|
if(!defined($d)) {
|
||||||
|
my $msg = "LGTV $name read error";
|
||||||
|
Log GetLogLevel($name,2), $msg;
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
my $tn = TimeNow();
|
||||||
|
|
||||||
|
my ($value, $state)=split(" ", $d);
|
||||||
|
|
||||||
|
if($value eq "power") {
|
||||||
|
$hash->{READINGS}{$value}{TIME} = $tn;
|
||||||
|
$hash->{READINGS}{$value}{VAL} = $state;
|
||||||
|
$hash->{CHANGED}[0]= "$value: $state";
|
||||||
|
$hash->{STATE} = $state;
|
||||||
|
|
||||||
|
if($state eq "on") {
|
||||||
|
$d = IOWrite($hash, "selected input");
|
||||||
|
if(!defined($d)) {
|
||||||
|
my $msg = "LGTV $name read error";
|
||||||
|
Log GetLogLevel($name,2), $msg;
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
$tn = TimeNow();
|
||||||
|
($value, $state)=split(" ", $d);
|
||||||
|
|
||||||
|
$hash->{READINGS}{$value}{TIME} = $tn;
|
||||||
|
$hash->{READINGS}{$value}{VAL} = $state;
|
||||||
|
$hash->{CHANGED}[1]= "$value: $state";
|
||||||
|
$hash->{STATE} = $hash->{STATE} . ", " . $state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DoTrigger($name, undef);
|
||||||
|
|
||||||
|
Log GetLogLevel($name,4), "LGTV $name: $hash->{STATE}";
|
||||||
|
|
||||||
|
return $hash->{STATE};
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub
|
||||||
|
LGTV_Get($@)
|
||||||
|
{
|
||||||
|
my ($hash, @a) = @_;
|
||||||
|
|
||||||
|
return "argument is missing" if(int(@a) != 2);
|
||||||
|
|
||||||
|
my $msg;
|
||||||
|
|
||||||
|
if($a[1] ne "status") {
|
||||||
|
return "unknown get value, valid is status";
|
||||||
|
}
|
||||||
|
$hash->{LOCAL} = 1;
|
||||||
|
my $v = LGTV_GetStatus($hash);
|
||||||
|
delete $hash->{LOCAL};
|
||||||
|
|
||||||
|
return "$a[0] $a[1] => $v";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub
|
||||||
|
LGTV_Set($@)
|
||||||
|
{
|
||||||
|
my ($hash, @a) = @_;
|
||||||
|
my $ret = undef;
|
||||||
|
my $na = int(@a);
|
||||||
|
my $ncmds=int(@commandlist);
|
||||||
|
my $i;
|
||||||
|
my $known_cmd=0;
|
||||||
|
my $what = "";
|
||||||
|
|
||||||
|
$what=$a[1];
|
||||||
|
if($na>1) {
|
||||||
|
for($i=2; $i<$na; $i++) {
|
||||||
|
$what=$what . " " . $a[$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for($i=0; $i<$ncmds; $i++ && $known_cmd==0) {
|
||||||
|
if($commandlist[$i] eq $what) {
|
||||||
|
$known_cmd+=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($known_cmd==0) {
|
||||||
|
return "Unknown argument $what, choose one of power input audio";
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret=IOWrite($hash, $what, "");
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################
|
||||||
|
sub
|
||||||
|
LGTV_Define($$)
|
||||||
|
{
|
||||||
|
my ($hash, $def) = @_;
|
||||||
|
my @a = split("[ \t][ \t]*", $def);
|
||||||
|
|
||||||
|
# return "syntax: define <name> LGTV an0..an5 [unit [factor]]"
|
||||||
|
# if(int(@a) < 3 && int(@a) > 5);
|
||||||
|
#
|
||||||
|
# my $reading= $a[2];
|
||||||
|
# return "$reading is not an analog input, valid: an0..an5"
|
||||||
|
# if($reading !~ /^an[0-5]$/) ;
|
||||||
|
#
|
||||||
|
# my $unit= ((int(@a) > 3) ? $a[3] : "volts");
|
||||||
|
# my $factor= ((int(@a) > 4) ? $a[4] : 1.0);
|
||||||
|
#
|
||||||
|
# $hash->{INPUT}= substr($reading,2);
|
||||||
|
# $hash->{UNIT}= $unit;
|
||||||
|
# $hash->{FACTOR}= $factor;
|
||||||
|
|
||||||
|
AssignIoPort($hash);
|
||||||
|
|
||||||
|
if(!$hash->{LOCAL}) {
|
||||||
|
InternalTimer(gettimeofday()+60, "LGTV_GetStatus", $hash, 0);
|
||||||
|
}
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
@ -86,6 +86,8 @@
|
|||||||
<a href="#Weather">Weather</a>
|
<a href="#Weather">Weather</a>
|
||||||
<a href="#USF1000">USF1000</a>
|
<a href="#USF1000">USF1000</a>
|
||||||
<a href="#X10">X10</a>
|
<a href="#X10">X10</a>
|
||||||
|
<a href="#xxLG7000">xxLG7000</a>
|
||||||
|
<a href="#LGTV">LGTV</a>
|
||||||
<a href="#FHEMRENDERER">FHEMRENDERER</a>
|
<a href="#FHEMRENDERER">FHEMRENDERER</a>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
@ -2916,6 +2918,121 @@ A line ending with \ will be concatenated with the next one, so long lines
|
|||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<a name="xxLG7000"></a>
|
||||||
|
<h3>xxLG7000</h3>
|
||||||
|
<ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="xxLG7000define"></a>
|
||||||
|
<b>Define</b>
|
||||||
|
<ul>
|
||||||
|
<code>define <name> xxLG7000 <serial-device></code>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
Defines a serial link to a TV set of LG's xxLG70yy series; these LCD TVs
|
||||||
|
(as well as their Plasma cousins, xxPG70yy) feature a serial connector which
|
||||||
|
can officially be used to control the TV set (see your Onwer's Manual, there's
|
||||||
|
an Appendix labelled "External Control Device setup"). And, well, xxLG7000 is
|
||||||
|
the FHEM module to actually do this. (BTW, they run Linux internally ;))<br><br>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
<ul>
|
||||||
|
<code>define myLG7k xxLG7000 /dev/ttyUSB1</code><br>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<a name="xxLG7000set"></a>
|
||||||
|
<b>Set </b>
|
||||||
|
<ul> Not used, nothing to set directly. </ul>
|
||||||
|
|
||||||
|
<a name="xxLG7000get"></a>
|
||||||
|
<b>Get</b>
|
||||||
|
<ul> Not used, nothing to get directly. </ul>
|
||||||
|
|
||||||
|
<b>Attributes</b>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#loglevel">loglevel</a></li>
|
||||||
|
<li>SetID (1, 2, ...; see Owner's Manual. Currently, only SetID 1 is addressed, regardless of this setting. Anyone who onws more than one of these?)</li>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<a name="LGTV"></a>
|
||||||
|
<h3>LGTV</h3>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<a name="LGTVdefine"></a>
|
||||||
|
<b>Define</b>
|
||||||
|
<ul>
|
||||||
|
<code>define <name> LGTV</code>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
This module is expected to work with <a href="#xxLG7000">xxLG7000</a> as it's
|
||||||
|
IODev. With LGTV and a compatible hardware module (currently, there's only
|
||||||
|
xxLG7000), you are able to power your TV set on and off, query it's power state,
|
||||||
|
select the input (AV, RGB, Composites, analogue TV, DVB-T, HDMI) or mute/unmute
|
||||||
|
the volume.<br>
|
||||||
|
Defining a LGTV device will schedule an internal task, which periodically reads
|
||||||
|
the status of the TV set (power state; if power is on, query the selected input)
|
||||||
|
and triggers notify/filelog commands.<br><br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<a name="LGTVset"></a>
|
||||||
|
<b>Set </b>
|
||||||
|
<ul>
|
||||||
|
<code>set <name> <what> <value></code>
|
||||||
|
<br><br>
|
||||||
|
Currently, the following commands are defined; not all may be available on a
|
||||||
|
given TV set. An error messages should be recorded if e. g. the input in question
|
||||||
|
is not usable.
|
||||||
|
|
||||||
|
<pre>power state
|
||||||
|
power on
|
||||||
|
power off
|
||||||
|
input AV1
|
||||||
|
input AV2
|
||||||
|
input AV3
|
||||||
|
input AV3
|
||||||
|
input Component
|
||||||
|
input RGB
|
||||||
|
input HDMI1
|
||||||
|
input HDMI2
|
||||||
|
input HDMI3
|
||||||
|
input HDMI4
|
||||||
|
input DVBT
|
||||||
|
input PAL
|
||||||
|
audio mute
|
||||||
|
audio normal
|
||||||
|
selected input</pre>
|
||||||
|
</ul>
|
||||||
|
<a name="LGTVget"></a>
|
||||||
|
<b>Get</b>
|
||||||
|
<ul>
|
||||||
|
<!-- <code>get <name> status</code>
|
||||||
|
<br><br> -->
|
||||||
|
Not yet implemented; use "set name power state" or "set name selected input" for now.
|
||||||
|
<br><br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<b>Attributes</b>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#attrdummy">dummy</a></li><br>
|
||||||
|
<li><a href="#loglevel">loglevel</a></li>
|
||||||
|
<!-- <li><a href="#model">model</a> (M232Counter)</li> -->
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
<b>Implementator's note</b>
|
||||||
|
<ul>
|
||||||
|
The commands listed above are send 1:1 to the underlying IODev (e. g. xxLG7000); that IODev
|
||||||
|
is responsible for translation into <i>whatever means</i> to invoke the function on the TV.
|
||||||
|
It is my hope that other's will adopt this idea and write compatible low level drivers for other
|
||||||
|
TV sets, to make this module (even ;)) more useful.
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<a name="OWFS"></a>
|
<a name="OWFS"></a>
|
||||||
<h3>OWFS</h3>
|
<h3>OWFS</h3>
|
||||||
<ul>
|
<ul>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user