mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-07 06:48:43 +00:00
00_TUL.pm: ABU 20160403 added support for 10_KNX.pm
git-svn-id: https://svn.fhem.de/fhem/trunk@11182 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
1de290ff15
commit
e453f84102
@ -4,6 +4,9 @@
|
||||
# ABU 20150918 fixed deprecated warning, fixed warning related to hex-conversion in simple-write
|
||||
# ABU 20151123 added error-label in getGroup. Responsible for error-handling, if knxd is not accesible
|
||||
# ABU 20151213 changed message-check in decode_tpuart() to avoid ignore while receiving repeated messages
|
||||
# ABU 20160308 remoced set, get. Changed loglevel to verbose. Added KNX/EIB-Split. Added EIB-backward-compatibility.
|
||||
# ABU 20160309 fixed log2
|
||||
# ABU 20160310 repaired dispatch events - inform EIB, only is useEIB is set
|
||||
|
||||
package main;
|
||||
|
||||
@ -33,9 +36,10 @@ my %sets = (
|
||||
"raw" => "",
|
||||
);
|
||||
|
||||
my $clients = ":EIB:";
|
||||
my $clients = ":KNX:EIB:";
|
||||
|
||||
my %matchList = (
|
||||
"2:KNX" => "^C.*",
|
||||
"3:EIB" => "^B.*",
|
||||
);
|
||||
|
||||
@ -52,18 +56,16 @@ TUL_Initialize($)
|
||||
# Normal devices
|
||||
$hash->{DefFn} = "TUL_Define";
|
||||
$hash->{UndefFn} = "TUL_Undef";
|
||||
$hash->{GetFn} = "TUL_Get";
|
||||
$hash->{SetFn} = "TUL_Set";
|
||||
$hash->{StateFn} = "TUL_SetState";
|
||||
$hash->{AttrFn} = "TUL_Attr";
|
||||
#$hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 " .
|
||||
# "showtime:1,0 model:TUL loglevel:0,1,2,3,4,5,6 ";
|
||||
|
||||
$hash->{AttrList}= "do_not_notify:1,0 "
|
||||
."dummy:1,0 "
|
||||
."showtime:1,0 "
|
||||
."model:TUL "
|
||||
."loglevel:0,1,2,3,4,5,6";
|
||||
$hash->{AttrList}= "do_not_notify:1,0 " .
|
||||
"dummy:1,0 " .
|
||||
"showtime:1,0 " .
|
||||
"verbose:0,1,2,3,4,5 " .
|
||||
"useEIB:1,0 ";
|
||||
|
||||
$hash->{ShutdownFn} = "TUL_Shutdown";
|
||||
|
||||
@ -76,9 +78,10 @@ TUL_Define($$)
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
if(@a < 4) {
|
||||
if(@a < 4)
|
||||
{
|
||||
my $msg = "wrong syntax: define <name> TUL <devicename> <device addr> [<line def in hex>]";
|
||||
Log(2, $msg);
|
||||
Log (2, $msg);
|
||||
return $msg;
|
||||
}
|
||||
|
||||
@ -89,12 +92,17 @@ TUL_Define($$)
|
||||
my $devaddr = tul_str2hex($a[3]);
|
||||
my $linedef = substr(tul_str2hex($a[4]),0,2) if(@a > 4);
|
||||
|
||||
if($dev eq "none") {
|
||||
Log(1, "$name device is none, commands will be echoed only");
|
||||
if($dev eq "none")
|
||||
{
|
||||
Log3 ($name, 1, "device is none, commands will be echoed only");
|
||||
$attr{$name}{dummy} = 1;
|
||||
return undef;
|
||||
}
|
||||
|
||||
#Set attributes in order to control backward-compatibility
|
||||
$attr{$name}{useEIB} = 1;
|
||||
Log3 ($name, 1, "Using EIB is deprecated. Please migrate to KNX soon. Module 10_EIB is not maintained any longer.") if (AttrVal($name, "useEIB", 0) =~ m/1/);
|
||||
|
||||
$hash->{DeviceName} = $dev;
|
||||
$hash->{DeviceAddress} = $devaddr;
|
||||
$hash->{Clients} = $clients;
|
||||
@ -113,10 +121,9 @@ TUL_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)
|
||||
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");
|
||||
@ -136,60 +143,6 @@ sub TUL_Shutdown($)
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
TUL_Set($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
|
||||
return "\"set TUL\" needs at least one parameter" if(@a < 2);
|
||||
return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets)
|
||||
if(!defined($sets{$a[1]}));
|
||||
|
||||
my $name = shift @a;
|
||||
my $type = shift @a;
|
||||
my $arg = join("", @a);
|
||||
my $ll = GetLogLevel($name,3);
|
||||
|
||||
return "No $a[1] for dummies" if(IsDummy($name));
|
||||
|
||||
if($type eq "raw") {
|
||||
Log $ll, "set $name $type $arg";
|
||||
TUL_SimpleWrite($hash, $arg);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
TUL_Get($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
my $type = $hash->{TYPE};
|
||||
|
||||
return "\"get $type\" needs at least one parameter" if(@a < 2);
|
||||
return "Unknown argument $a[1], choose one of " . join(" ", sort keys %gets)
|
||||
if(!defined($gets{$a[1]}));
|
||||
|
||||
my $arg = ($a[2] ? $a[2] : "");
|
||||
my $rsp;
|
||||
my $name = $a[0];
|
||||
|
||||
#return "No $a[1] for dummies" if(IsDummy($name));
|
||||
|
||||
TUL_SimpleWrite($hash, "B".$gets{$a[1]}[0] . $arg);
|
||||
$rsp = TUL_SimpleRead($hash);
|
||||
if(!defined($rsp)) {
|
||||
TUL_Disconnected($hash);
|
||||
$rsp = "No answer";
|
||||
}
|
||||
|
||||
$hash->{READINGS}{$a[1]}{VAL} = $rsp;
|
||||
$hash->{READINGS}{$a[1]}{TIME} = TimeNow();
|
||||
|
||||
return "$a[0] $a[1] => $rsp";
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
TUL_SetState($$$$)
|
||||
@ -203,10 +156,8 @@ TUL_Clear($)
|
||||
{
|
||||
my $hash = shift;
|
||||
|
||||
# Clear the pipe
|
||||
# TUL has no pipe....
|
||||
|
||||
#Log(1,"TUL_Clear not defined yet");
|
||||
#Clear the pipe
|
||||
#TUL has no pipe....
|
||||
}
|
||||
|
||||
#####################################
|
||||
@ -217,7 +168,6 @@ TUL_DoInit($)
|
||||
my $name = $hash->{NAME};
|
||||
my $err;
|
||||
|
||||
|
||||
TUL_Clear($hash);
|
||||
|
||||
# send any initializing request if needed
|
||||
@ -239,11 +189,19 @@ TUL_DoInit($)
|
||||
sub
|
||||
TUL_Write($$$)
|
||||
{
|
||||
|
||||
my ($hash,$fn,$msg) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
return if(!defined($fn));
|
||||
|
||||
Log 5, "$hash->{NAME} sending $fn$msg";
|
||||
#Discard message, if not set to backward-compatibility
|
||||
if ((AttrVal($name, "useEIB", 0) =~ m/0/) and ($fn =~ m/^B/))
|
||||
{
|
||||
Log3 ($name, 0, "EIB is no longer supported. Message discarded.");
|
||||
return;
|
||||
}
|
||||
|
||||
Log3 ($name, 5, "sending $fn$msg");
|
||||
my $bstring = "$fn$msg";
|
||||
|
||||
TUL_SimpleWrite($hash, $bstring);
|
||||
@ -266,23 +224,28 @@ TUL_Read($)
|
||||
# check if refused
|
||||
if(defined($hash->{REFUSED}))
|
||||
{
|
||||
Log(3,"TUL $name refused message: $hash->{REFUSED}");
|
||||
Log3 ($name, 3,"TUL $name refused message: $hash->{REFUSED}");
|
||||
$hash->{REFUSED} = undef;
|
||||
return "";
|
||||
}
|
||||
|
||||
###########
|
||||
# Lets' try again: Some drivers return len(0) on the first read...
|
||||
if(defined($buf) && length($buf) == 0) {
|
||||
if(defined($buf) && length($buf) == 0)
|
||||
{
|
||||
$buf = TUL_SimpleRead($hash);
|
||||
}
|
||||
|
||||
if(!defined($buf) || length($buf) == 0) {
|
||||
if(!defined($buf) || length($buf) == 0)
|
||||
{
|
||||
TUL_Disconnected($hash);
|
||||
return "";
|
||||
}
|
||||
|
||||
TUL_Parse($hash, $hash, $name, $buf, $hash->{initString});
|
||||
#place KNX-Message
|
||||
TUL_Parse($hash, $hash, $name, "B".$buf, $hash->{initString}) if (AttrVal($name, "useEIB", 0) =~ m/1/);
|
||||
#place EIB-Message
|
||||
TUL_Parse($hash, $hash, $name, "C".$buf, $hash->{initString});
|
||||
}
|
||||
|
||||
sub
|
||||
@ -290,12 +253,11 @@ TUL_Parse($$$$$)
|
||||
{
|
||||
my ($hash, $iohash, $name, $rmsg, $initstr) = @_;
|
||||
|
||||
|
||||
# there is nothing specal to do at the moment.
|
||||
# just dispatch
|
||||
|
||||
my $dmsg = $rmsg;
|
||||
Log GetLogLevel($name,4), "$name: $dmsg";
|
||||
Log3 ($name, 4, "$name: $dmsg");
|
||||
|
||||
$hash->{"${name}_MSGCNT"}++;
|
||||
$hash->{"${name}_TIME"} = TimeNow();
|
||||
@ -312,8 +274,7 @@ TUL_Ready($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
return TUL_OpenDev($hash, 1)
|
||||
if($hash->{STATE} eq "disconnected");
|
||||
return TUL_OpenDev($hash, 1) if($hash->{STATE} eq "disconnected");
|
||||
|
||||
# This is relevant for windows/USB only
|
||||
my $po = $hash->{USBDev};
|
||||
@ -334,16 +295,19 @@ TUL_SimpleWrite(@)
|
||||
# v is a simple (1 Byte) or complex value (n bytes)
|
||||
|
||||
# For eibd we need a more elaborate structure
|
||||
if($msg =~ /^B(.)(.{4})(.*)$/)
|
||||
if($msg =~ /^[BC](.)(.{4})(.*)$/)
|
||||
{
|
||||
my $eibmsg;
|
||||
if($1 eq "w"){
|
||||
if($1 eq "w")
|
||||
{
|
||||
$eibmsg->{'type'} = 'write';
|
||||
}
|
||||
elsif ($1 eq "r") {
|
||||
elsif ($1 eq "r")
|
||||
{
|
||||
$eibmsg->{'type'} = 'read';
|
||||
}
|
||||
elsif ($1 eq "p") {
|
||||
elsif ($1 eq "p")
|
||||
{
|
||||
$eibmsg->{'type'} = 'reply';
|
||||
}
|
||||
|
||||
@ -375,7 +339,7 @@ TUL_SimpleWrite(@)
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(1,"Could not parse message $msg");
|
||||
Log3 ($hash->{NAME}, 1,"Could not parse message $msg");
|
||||
return undef;
|
||||
}
|
||||
|
||||
@ -387,10 +351,12 @@ sub
|
||||
TUL_SimpleRead($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $msg = getGroup($hash);
|
||||
if(!defined($msg)) {
|
||||
Log(4,"No data received.") ;
|
||||
if(!defined($msg))
|
||||
{
|
||||
Log3 ($name, 4,"No data received.") ;
|
||||
return undef;
|
||||
}
|
||||
|
||||
@ -401,24 +367,31 @@ TUL_SimpleRead($)
|
||||
my $data = "";
|
||||
|
||||
# convert bin data to hex
|
||||
foreach my $c (@bindata) {
|
||||
foreach my $c (@bindata)
|
||||
{
|
||||
$data .= sprintf ("%02x", $c);
|
||||
}
|
||||
|
||||
Log(5,"SimpleRead msg.type: $type, msg.src: $msg->{'src'}, msg.dst: $msg->{'dst'}");
|
||||
Log(5,"SimpleRead data: $data");
|
||||
Log3 ($name, 5, "SimpleRead msg.type: $type, msg.src: $msg->{'src'}, msg.dst: $msg->{'dst'}");
|
||||
Log3 ($name, 5, "SimpleRead data: $data");
|
||||
|
||||
# we will build a string like:
|
||||
# Bs1s2s3(w|r|p)g1g2g3v
|
||||
# s -> src
|
||||
my $buf ="B$src";
|
||||
if($type eq "write") {
|
||||
my $buf;
|
||||
#$buf = "C$src";
|
||||
$buf = $src;
|
||||
|
||||
if($type eq "write")
|
||||
{
|
||||
$buf .= "w";
|
||||
}
|
||||
elsif ($type eq "read") {
|
||||
elsif ($type eq "read")
|
||||
{
|
||||
$buf .= "r";
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
$buf .= "p";
|
||||
}
|
||||
|
||||
@ -440,15 +413,17 @@ TUL_CloseDev($)
|
||||
|
||||
return if(!$dev);
|
||||
|
||||
if($hash->{TCPDev}) {
|
||||
if($hash->{TCPDev})
|
||||
{
|
||||
$hash->{TCPDev}->close();
|
||||
delete($hash->{TCPDev});
|
||||
|
||||
} elsif($hash->{USBDev}) {
|
||||
}
|
||||
elsif($hash->{USBDev})
|
||||
{
|
||||
$hash->{USBDev}->close() ;
|
||||
delete($hash->{USBDev});
|
||||
|
||||
}
|
||||
|
||||
delete($selectlist{"$name.$dev"});
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
delete($hash->{FD});
|
||||
@ -464,13 +439,17 @@ TUL_OpenDev($$)
|
||||
my $po;
|
||||
|
||||
$hash->{PARTIAL} = "";
|
||||
Log 3, "TUL opening $name device $dev"
|
||||
if(!$reopen);
|
||||
Log 3, "TUL opening $name device $dev" if(!$reopen);
|
||||
|
||||
if($dev =~ m/^(eibd):(.+)$/) { # eibd:host[:port]
|
||||
# eibd:host[:port]
|
||||
if($dev =~ m/^(eibd):(.+)$/)
|
||||
{
|
||||
my $host = $2;
|
||||
my $port = 6720;
|
||||
if($host =~ m/^(.+):([0-9]+)$/){ #host:port
|
||||
|
||||
#host:port
|
||||
if($host =~ m/^(.+):([0-9]+)$/)
|
||||
{
|
||||
$host = $1;
|
||||
$port = $2;
|
||||
}
|
||||
@ -479,16 +458,16 @@ TUL_OpenDev($$)
|
||||
# somebody is communicating over another TCP connection. As the connect
|
||||
# for non-existent devices has a delay of 3 sec, we are sitting all the
|
||||
# time in this connect. NEXT_OPEN tries to avoid this problem.
|
||||
if($hash->{NEXT_OPEN} && time() < $hash->{NEXT_OPEN}) {
|
||||
return;
|
||||
}
|
||||
return if($hash->{NEXT_OPEN} && time() < $hash->{NEXT_OPEN});
|
||||
|
||||
my $conn = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port,Proto => 'tcp');
|
||||
if($conn) {
|
||||
if($conn)
|
||||
{
|
||||
delete($hash->{NEXT_OPEN})
|
||||
|
||||
} else {
|
||||
Log(3, "Can't connect to $dev: $!") if(!$reopen);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log3 ($name, 3, "Can't connect to $dev: $!") if(!$reopen);
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
$hash->{STATE} = "disconnected";
|
||||
$hash->{NEXT_OPEN} = time()+60;
|
||||
@ -500,43 +479,52 @@ TUL_OpenDev($$)
|
||||
$hash->{FD} = $conn->fileno();
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
$selectlist{"$name.$dev"} = $hash;
|
||||
|
||||
}
|
||||
elsif ($dev =~ m/^(tul|tpuart):(.+)$/) { # tpuart:ttydev[@baudrate] / USB/Serial device
|
||||
|
||||
# tpuart:ttydev[@baudrate] / USB/Serial device
|
||||
elsif ($dev =~ m/^(tul|tpuart):(.+)$/)
|
||||
{
|
||||
my $dev = $2;
|
||||
my $baudrate;
|
||||
($dev, $baudrate) = split("@", $dev);
|
||||
$baudrate = 19200 if(!$baudrate); # fix for TUL board
|
||||
|
||||
if ($^O=~/Win/) {
|
||||
if ($^O=~/Win/)
|
||||
{
|
||||
require Win32::SerialPort;
|
||||
$po = new Win32::SerialPort ($dev);
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
require Device::SerialPort;
|
||||
$po = new Device::SerialPort ($dev);
|
||||
}
|
||||
|
||||
if(!$po) {
|
||||
if(!$po)
|
||||
{
|
||||
return undef if($reopen);
|
||||
Log(3, "Can't open $dev: $!");
|
||||
Log3 ($name, 3, "Can't open $dev: $!");
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
$hash->{STATE} = "disconnected";
|
||||
return "";
|
||||
}
|
||||
|
||||
$hash->{DevType} = 'TPUART';
|
||||
$hash->{USBDev} = $po;
|
||||
if( $^O =~ /Win/ ) {
|
||||
if( $^O =~ /Win/ )
|
||||
{
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
$hash->{FD} = $po->FILENO;
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
$selectlist{"$name.$dev"} = $hash;
|
||||
}
|
||||
|
||||
if($baudrate) { # assumed always available
|
||||
# assumed always available
|
||||
if($baudrate)
|
||||
{
|
||||
$po->reset_error();
|
||||
Log 3, "TUL setting $name baudrate to $baudrate";
|
||||
Log3 ($name, 3, "TUL setting $name baudrate to $baudrate");
|
||||
$po->baudrate($baudrate);
|
||||
$po->databits(8);
|
||||
$po->parity('even');
|
||||
@ -562,24 +550,27 @@ TUL_OpenDev($$)
|
||||
}
|
||||
|
||||
$po->write_settings;
|
||||
|
||||
|
||||
}
|
||||
else { # No more devices supported now
|
||||
|
||||
Log(1, "$dev protocol is not supported");
|
||||
# No more devices supported now
|
||||
else
|
||||
{
|
||||
Log3 ($name, 1, "$dev protocol is not supported");
|
||||
}
|
||||
|
||||
if($reopen) {
|
||||
Log 1, "TUL $dev reappeared ($name)";
|
||||
} else {
|
||||
Log 3, "TUL device opened";
|
||||
if($reopen)
|
||||
{
|
||||
Log3 ($name, 1, "TUL $dev reappeared ($name)");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log3 ($name, 3, "TUL device opened");
|
||||
}
|
||||
|
||||
$hash->{STATE}=""; # Allow InitDev to set the state
|
||||
my $ret = TUL_DoInit($hash);
|
||||
|
||||
if($ret) {
|
||||
if($ret)
|
||||
{
|
||||
TUL_CloseDev($hash);
|
||||
Log 1, "Cannot init $dev, ignoring it";
|
||||
}
|
||||
@ -588,6 +579,7 @@ TUL_OpenDev($$)
|
||||
return $ret;
|
||||
}
|
||||
|
||||
########################
|
||||
sub
|
||||
TUL_Disconnected($)
|
||||
{
|
||||
@ -597,7 +589,7 @@ TUL_Disconnected($)
|
||||
|
||||
return if(!defined($hash->{FD})); # Already deleted or RFR
|
||||
|
||||
Log 1, "$dev disconnected, waiting to reappear";
|
||||
Log3 ($name, 1, "$dev disconnected, waiting to reappear");
|
||||
TUL_CloseDev($hash);
|
||||
$readyfnlist{"$name.$dev"} = $hash; # Start polling
|
||||
$hash->{STATE} = "disconnected";
|
||||
@ -609,13 +601,11 @@ TUL_Disconnected($)
|
||||
DoTrigger($name, "DISCONNECTED");
|
||||
}
|
||||
|
||||
########################
|
||||
sub
|
||||
TUL_Attr(@)
|
||||
{
|
||||
my @a = @_;
|
||||
|
||||
Log 2, "Unsupported method TUL_Attr($a[0],$a[1],$a[2],$a[3])";
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
@ -632,9 +622,11 @@ TUL_Attr(@)
|
||||
#
|
||||
|
||||
# Utility functions
|
||||
sub tul_hex2addr {
|
||||
sub tul_hex2addr
|
||||
{
|
||||
my $str = lc($_[0]);
|
||||
if ($str =~ /([0-9a-f])([0-9a-f])([0-9a-f]{2})/) {
|
||||
if ($str =~ /([0-9a-f])([0-9a-f])([0-9a-f]{2})/)
|
||||
{
|
||||
return (hex($1) << 11) | (hex($2) << 8) | hex($3);
|
||||
}
|
||||
else
|
||||
@ -644,11 +636,13 @@ sub tul_hex2addr {
|
||||
}
|
||||
}
|
||||
|
||||
sub tul_addr2hex {
|
||||
sub tul_addr2hex
|
||||
{
|
||||
my $a = $_[0];
|
||||
my $b = $_[1]; # 1 if local (group) address, else physical address
|
||||
my $str ;
|
||||
if ($b == 1) { # logical address used
|
||||
if ($b == 1)
|
||||
{ # logical address used
|
||||
$str = sprintf "%01x%01x%02x", ($a >> 11) & 0xf, ($a >> 8) & 0x7, $a & 0xff;
|
||||
}
|
||||
else { # physical address used
|
||||
@ -657,13 +651,16 @@ sub tul_addr2hex {
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub tul_str2hex {
|
||||
sub tul_str2hex
|
||||
{
|
||||
my $str = $_[0];
|
||||
if ($str =~ /(\d+)\/(\d+)\/(\d+)/) { # logical address
|
||||
if ($str =~ /(\d+)\/(\d+)\/(\d+)/)
|
||||
{ # logical address
|
||||
my $hex = sprintf("%01x%01x%02x",$1,$2,$3);
|
||||
return $hex;
|
||||
}
|
||||
elsif ($str =~ /(\d+)\.(\d+)\.(\d+)/) { # physical address
|
||||
elsif ($str =~ /(\d+)\.(\d+)\.(\d+)/)
|
||||
{ # physical address
|
||||
my $hex = sprintf("%01x%01x%02x",$1,$2,$3);
|
||||
return $hex;
|
||||
}
|
||||
@ -691,10 +688,12 @@ sub decode_eibd($)
|
||||
$apci = vec($bytes, 3, 2);
|
||||
# mask out apci bits, so we can use the whole byte as data:
|
||||
vec($bytes, 3, 2) = 0;
|
||||
if ($apci >= 0 && $apci <= $#apcicodes) {
|
||||
if ($apci >= 0 && $apci <= $#apcicodes)
|
||||
{
|
||||
$msg{'type'} = $apcicodes[$apci];
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
$msg{'type'} = 'apci ' . $apci;
|
||||
}
|
||||
|
||||
@ -703,11 +702,12 @@ sub decode_eibd($)
|
||||
|
||||
@data = unpack ("C" . length($bytes), $bytes);
|
||||
my $datalen = @data;
|
||||
Log(5, "decode_eibd byte len: " . length($bytes) . " array size: $datalen");
|
||||
Log (5, "decode_eibd byte len: " . length($bytes) . " array size: $datalen");
|
||||
|
||||
# in case of data len > 1, the first byte (the one with apci) seems not to be used
|
||||
# and only the following byte are of interest.
|
||||
if($datalen>1) {
|
||||
if($datalen>1)
|
||||
{
|
||||
shift @data;
|
||||
}
|
||||
|
||||
@ -724,7 +724,8 @@ sub encode_eibd($)
|
||||
my @data;
|
||||
|
||||
$APCI = $apcivalues{$mref->{'type'}};
|
||||
if (!(defined $APCI)) {
|
||||
if (!(defined $APCI))
|
||||
{
|
||||
Log(3,"Bad EIB message type $mref->{'type'}\n");
|
||||
return;
|
||||
}
|
||||
@ -739,7 +740,8 @@ sub encode_eibd($)
|
||||
0x0 | ($APCI >> 2), # TPDU type, Sequence no, APCI (msb)
|
||||
(($APCI & 0x3) << 6) | $data[0],
|
||||
);
|
||||
if ($datalen > 1) {
|
||||
if ($datalen > 1)
|
||||
{
|
||||
shift(@data);
|
||||
push @msg, @data;
|
||||
}
|
||||
@ -785,7 +787,8 @@ sub decode_tpuart($)
|
||||
Log(5,"msg cmd: " . sprintf("0x%02x",$cmd) ." datalen: $len");
|
||||
|
||||
my $apci = ($cmd >> 6) & 0x0F;
|
||||
if($len == 2) { # 1 byte data
|
||||
if($len == 2)
|
||||
{ # 1 byte data
|
||||
$bytes = pack("C",$cmd & 0x3F);
|
||||
}
|
||||
|
||||
@ -793,10 +796,12 @@ sub decode_tpuart($)
|
||||
|
||||
my %msg;
|
||||
my @data;
|
||||
if ($apci >= 0 && $apci <= $#apcicodes) {
|
||||
if ($apci >= 0 && $apci <= $#apcicodes)
|
||||
{
|
||||
$msg{'type'} = $apcicodes[$apci];
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
$msg{'type'} = 'apci ' . $apci;
|
||||
}
|
||||
|
||||
@ -820,7 +825,8 @@ sub encode_tpuart($)
|
||||
my @data;
|
||||
|
||||
$APCI = $apcivalues{$mref->{'type'}};
|
||||
if (!(defined $APCI)) {
|
||||
if (!(defined $APCI))
|
||||
{
|
||||
Log(3,"Bad EIB message type $mref->{'type'}\n");
|
||||
return;
|
||||
}
|
||||
@ -841,7 +847,8 @@ sub encode_tpuart($)
|
||||
0x00,
|
||||
(($APCI & 0x3) << 6) | $data[0],
|
||||
);
|
||||
if ($datalen > 1) {
|
||||
if ($datalen > 1)
|
||||
{
|
||||
shift(@data);
|
||||
push @msg, @data;
|
||||
}
|
||||
@ -1138,12 +1145,10 @@ sub sendRequest($$)
|
||||
<table>
|
||||
<tr><td>
|
||||
The TUL module is the representation of a EIB / KNX connector in FHEM.
|
||||
<a href="#EIB">EIB</a> instances represent the EIB / KNX devices and will need a TUL as IODev to communicate with the EIB / KNX network.<br>
|
||||
<a href="#KNX">KNX</a> instances represent the EIB / KNX devices and will need a TUL as IODev to communicate with the EIB / KNX network.<br>
|
||||
The TUL module is designed to connect to EIB network either using EIBD or the <a href="http://busware.de/tiki-index.php?page=TUL" target="_blank">TUL usb stick</a> created by busware.de
|
||||
|
||||
Note: this module may require the Device::SerialPort or Win32::SerialPort
|
||||
module if you attach the device via USB and the OS sets strange default
|
||||
parameters for serial devices.
|
||||
Note: this module may require the Device::SerialPort or Win32::SerialPort module if you attach the device via USB and the OS sets strange default parameters for serial devices.
|
||||
|
||||
</td><td>
|
||||
<img src="IMG_0483.jpg" width="100%" height="100%"/>
|
||||
@ -1156,66 +1161,115 @@ sub sendRequest($$)
|
||||
<code>define <name> TUL <device> <physical address></code> <br>
|
||||
<br>
|
||||
TUL usb stick / TPUART serial devices:<br><ul>
|
||||
<device> specifies the serial port to communicate with the TUL.
|
||||
The name of the serial-device depends on your distribution, under
|
||||
linux the cdc_acm kernel module is responsible, and usually a
|
||||
/dev/ttyACM0 device will be created. If your distribution does not have a
|
||||
cdc_acm module, you can force usbserial to handle the TUL by the
|
||||
following command:<ul>modprobe usbserial vendor=0x03eb
|
||||
product=0x204b</ul>In this case the device is most probably
|
||||
/dev/ttyUSB0.<br><br>
|
||||
<device> specifies the serial port to communicate with the TUL. The name of the serial-device depends on your distribution, under linux the cdc_acm kernel module is responsible, and usually a
|
||||
/dev/ttyACM0 device will be created. If your distribution does not have a cdc_acm module, you can force usbserial to handle the TUL by the following command:<ul>modprobe usbserial vendor=0x03eb
|
||||
product=0x204b</ul>In this case the device is most probably /dev/ttyUSB0.<br><br>
|
||||
|
||||
You can also specify a baudrate if the device name contains the @
|
||||
character, e.g.: /dev/ttyACM0@19200<br><br>
|
||||
Note: For TUL usb stick the baudrate 19200 is needed and this is the default
|
||||
when no baudrate is given.
|
||||
You can also specify a baudrate if the device name contains the @ character, e.g.: /dev/ttyACM0@19200<br><br>
|
||||
Note: For TUL usb stick the baudrate 19200 is needed and this is the default when no baudrate is given.
|
||||
<br><br>
|
||||
|
||||
Example:<br>
|
||||
<code>define tul TUL tul:/dev/ttyACM0 1.1.249</code>
|
||||
</ul>
|
||||
|
||||
EIBD:<br><ul>
|
||||
<device> specifies the host:port of the eibd device. E.g.
|
||||
eibd:192.168.0.244:2323. When using the standard port, the port can be omitted.
|
||||
<device> specifies the host:port of the eibd device. E.g. eibd:192.168.0.244:2323. When using the standard port, the port can be omitted.
|
||||
<br><br>
|
||||
|
||||
Example:<br>
|
||||
<code>define tul TUL eibd:localhost 1.1.249</code>
|
||||
</ul>
|
||||
<br>
|
||||
If the device is called none, then no device will be opened, so you
|
||||
can experiment without hardware attached.<br>
|
||||
If the device is called none, then no device will be opened, so you can experiment without hardware attached.<br>
|
||||
|
||||
The physical address is used as the source address of telegrams sent to EIB network.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="TULset"></a>
|
||||
<b>Set </b>
|
||||
<ul>
|
||||
<li>raw<br>
|
||||
Issue a TUL raw telegram message
|
||||
</li><br>
|
||||
</ul>
|
||||
|
||||
<a name="TULget"></a>
|
||||
<b>Get</b>
|
||||
<ul>
|
||||
<li>raw<br>
|
||||
sends a read telegram
|
||||
</li><br>
|
||||
</ul>
|
||||
|
||||
<a name="TULattr"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li><br>
|
||||
<li><a href="#attrdummy">dummy</a></li><br>
|
||||
<li><a href="#showtime">showtime</a></li><br>
|
||||
<li><a href="#loglevel">loglevel</a></li><br>
|
||||
<li><a href="#verbose">verbose</a></li><br>
|
||||
<li><a href="#useEIB">useEIB</a></li><br>
|
||||
<ul>
|
||||
The device operates the module 10_EIB, if this flag is set to 1. This is used for backward compatibility only. Otherwise, only the client 10_KNX is used.
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
|
||||
=begin html_DE
|
||||
|
||||
<a name="TUL"></a>
|
||||
<h3>TUL</h3>
|
||||
<ul>
|
||||
|
||||
<table>
|
||||
<tr><td>
|
||||
Das Modul TUL stellt die Verbindung von FHEM zum EIB / KNX dar.
|
||||
<a href="#KNX">KNX</a> Instanzen stellen die Vrbindung zu den KNX-Gruppen dar und benÖtigen ein TUL-Device als IO-Schnittstelle.<br>
|
||||
Das Modul TUL kommuniziert mit dem KNX entweder Über den EIBD, den KNXD oder den TUL <a href="http://busware.de/tiki-index.php?page=TUL" target="_blank">TUL usb stick</a> hergestellt von busware.de
|
||||
|
||||
Anmerkung: das Modul benÖtigt die Device::SerialPort oder Win32::SerialPort wenn der Stick Über USB angeschlossen wird, und das OS unrealistische Parameter fÜr das Device einstellt.
|
||||
|
||||
</td><td>
|
||||
<img src="IMG_0483.jpg" width="100%" height="100%"/>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
<a name="TULdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> TUL <device> <physical address></code> <br>
|
||||
<br>
|
||||
TUL usb stick / TPUART serial devices:<br><ul>
|
||||
<device> enthält die serielle Schnittstelle der TUL. Der name der Schnittstelle hängt von Eurer Distribution ab. Unter linux wird fÜr gewÖhnlich /dev/ttyACM0 verwandt.
|
||||
Wenn Eure Distribution das modul cdc_acm nicht enthält, kÖnnt Ihr das Laden des handles der TUL mit dem folgenden Befehl erzwingen:<ul>modprobe usbserial vendor=0x03eb
|
||||
product=0x204b</ul>Dann ist die Schnittstelle meist /dev/ttyUSB0.<br><br>
|
||||
|
||||
Ihr kÖnnt dem Gerät eine Baudrate vorgeben. Dazu dem Gerätenamen das Zeichen @ hinzufÜgen, z.B.: /dev/ttyACM0@19200<br><br>
|
||||
Anmerkung: FÜr den TUL-USB-Stick wird die Baudrate 19200 benÖtigt. Dies entspricht der Defaulteinstellung.
|
||||
<br><br>
|
||||
|
||||
Beispiel:<br>
|
||||
<code>define tul TUL tul:/dev/ttyACM0 1.1.249</code>
|
||||
</ul>
|
||||
|
||||
EIBD:<br><ul>
|
||||
<device> entspricht dem host:port des eibd-servers. z.B. eibd:192.168.0.244:2323. Wenn der Standardport genutzt wird, muss dieser nicht angegeben werden.
|
||||
<br><br>
|
||||
|
||||
Beispiel:<br>
|
||||
<code>define tul TUL eibd:localhost 1.1.249</code>
|
||||
</ul>
|
||||
<br>
|
||||
Wenn das Gerät none konfiguriert wird, wird kein device geÖffnet. So kÖnnt Ihr ohne angeschlossene Hardware experimentieren. <br>
|
||||
|
||||
Die physikalische Adresse wird als Absender fÜr KNX-Telegramme genutzt.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="TULattr"></a>
|
||||
<b>Attribute</b>
|
||||
<ul>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li><br>
|
||||
<li><a href="#attrdummy">dummy</a></li><br>
|
||||
<li><a href="#showtime">showtime</a></li><br>
|
||||
<li><a href="#verbose">verbose</a></li><br>
|
||||
<li><a href="#useEIB">useEIB</a></li><br>
|
||||
<ul>
|
||||
Das Gerät kann das Modul 10_EIB bedienen, wenn das Flag auf 1 gesetzt ist. Dies ist nur fÜr RÜckwärtskompatibiliät genutzt. Andernfalls wird nur das Modul 10_KNX bedient.
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
=end html_DE
|
||||
|
||||
=cut
|
||||
|
Loading…
x
Reference in New Issue
Block a user