mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 18:59:33 +00:00
Deleted as requested by the author (peterp)
git-svn-id: https://svn.fhem.de/fhem/trunk@3292 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
7be41e4aac
commit
9c11d402cf
@ -1,405 +0,0 @@
|
||||
##############################################
|
||||
# $Id$
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
|
||||
sub HMLAN_Parse($$);
|
||||
sub HMLAN_Read($);
|
||||
sub HMLAN_Write($$$);
|
||||
sub HMLAN_ReadAnswer($$$);
|
||||
sub HMLAN_uptime($);
|
||||
|
||||
sub HMLAN_SimpleWrite(@);
|
||||
|
||||
my %sets = (
|
||||
"hmPairForSec" => "HomeMatic",
|
||||
"hmPairSerial" => "HomeMatic",
|
||||
);
|
||||
|
||||
sub
|
||||
HMLAN_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
require "$attr{global}{modpath}/FHEM/DevIo.pm";
|
||||
|
||||
# Provider
|
||||
$hash->{ReadFn} = "HMLAN_Read";
|
||||
$hash->{WriteFn} = "HMLAN_Write";
|
||||
$hash->{ReadyFn} = "HMLAN_Ready";
|
||||
$hash->{SetFn} = "HMLAN_Set";
|
||||
$hash->{Clients} = ":CUL_HM:";
|
||||
my %mc = (
|
||||
"1:CUL_HM" => "^A......................",
|
||||
);
|
||||
$hash->{MatchList} = \%mc;
|
||||
|
||||
# Normal devices
|
||||
$hash->{DefFn} = "HMLAN_Define";
|
||||
$hash->{UndefFn} = "HMLAN_Undef";
|
||||
$hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 " .
|
||||
"loglevel:0,1,2,3,4,5,6 addvaltrigger " .
|
||||
"hmId hmProtocolEvents hmKey";
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
HMLAN_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
if(@a != 3) {
|
||||
my $msg = "wrong syntax: define <name> ip[:port] | /path/to/HM-USB-CFG device as a parameter"; #added for HM-USB-CFG by peterp
|
||||
|
||||
Log 2, $msg;
|
||||
return $msg;
|
||||
}
|
||||
DevIo_CloseDev($hash);
|
||||
|
||||
my $name = $a[0];
|
||||
my $dev = $a[2];
|
||||
$dev .= ":1000" if($dev !~ m/:/ && $dev ne "none" && $dev !~ m/\@/ && $dev !~ m/hiddev/ ); #changed for HM-USB-CFG by peterp
|
||||
$attr{$name}{hmId} = sprintf("%06X", time() % 0xffffff); # Will be overwritten
|
||||
|
||||
if($dev eq "none") {
|
||||
Log 1, "$name device is none, commands will be echoed only";
|
||||
$attr{$name}{dummy} = 1;
|
||||
return undef;
|
||||
}
|
||||
$hash->{DeviceName} = $dev;
|
||||
my $ret = DevIo_OpenDev($hash, 0, "HMLAN_DoInit");
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
HMLAN_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};
|
||||
}
|
||||
}
|
||||
|
||||
DevIo_CloseDev($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
HMLAN_RemoveHMPair($)
|
||||
{
|
||||
my $hash = shift;
|
||||
delete($hash->{hmPair});
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
HMLAN_Set($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
|
||||
return "\"set HMLAN\" 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);
|
||||
|
||||
if($type eq "hmPairForSec") { ####################################
|
||||
return "Usage: set $name hmPairForSec <seconds_active>"
|
||||
if(!$arg || $arg !~ m/^\d+$/);
|
||||
$hash->{hmPair} = 1;
|
||||
InternalTimer(gettimeofday()+$arg, "HMLAN_RemoveHMPair", $hash, 1);
|
||||
|
||||
} elsif($type eq "hmPairSerial") { ################################
|
||||
return "Usage: set $name hmPairSerial <10-character-serialnumber>"
|
||||
if(!$arg || $arg !~ m/^.{10}$/);
|
||||
|
||||
my $id = AttrVal($hash->{NAME}, "hmId", "123456");
|
||||
$hash->{HM_CMDNR} = $hash->{HM_CMDNR} ? ($hash->{HM_CMDNR}+1)%256 : 1;
|
||||
|
||||
HMLAN_Write($hash, undef, sprintf("As15%02X8401%s000000010A%s",
|
||||
$hash->{HM_CMDNR}, $id, unpack('H*', $arg)));
|
||||
$hash->{hmPairSerial} = $arg;
|
||||
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
# This is a direct read for commands like get
|
||||
sub
|
||||
HMLAN_ReadAnswer($$$)
|
||||
{
|
||||
my ($hash, $arg, $regexp) = @_;
|
||||
my $type = $hash->{TYPE};
|
||||
|
||||
return ("No FD", undef)
|
||||
if(!$hash && !defined($hash->{FD}));
|
||||
|
||||
my ($mdata, $rin) = ("", '');
|
||||
my $buf;
|
||||
my $to = 3; # 3 seconds timeout
|
||||
$to = $hash->{RA_Timeout} if($hash->{RA_Timeout}); # ...or less
|
||||
for(;;) {
|
||||
|
||||
return ("Device lost when reading answer for get $arg", undef)
|
||||
if(!$hash->{FD});
|
||||
vec($rin, $hash->{FD}, 1) = 1;
|
||||
my $nfound = select($rin, undef, undef, $to);
|
||||
if($nfound < 0) {
|
||||
next if ($! == EAGAIN() || $! == EINTR() || $! == 0);
|
||||
my $err = $!;
|
||||
DevIo_Disconnected($hash);
|
||||
return("HMLAN_ReadAnswer $arg: $err", undef);
|
||||
}
|
||||
return ("Timeout reading answer for get $arg", undef)
|
||||
if($nfound == 0);
|
||||
$buf = DevIo_SimpleRead($hash);
|
||||
return ("No data", undef) if(!defined($buf));
|
||||
|
||||
if($buf) {
|
||||
Log 5, "HMLAN/RAW (ReadAnswer): $buf";
|
||||
$mdata .= $buf;
|
||||
}
|
||||
if($mdata =~ m/\r\n/) {
|
||||
if($regexp && $mdata !~ m/$regexp/) {
|
||||
HMLAN_Parse($hash, $mdata);
|
||||
} else {
|
||||
return (undef, $mdata)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my %lhash;
|
||||
|
||||
#####################################
|
||||
sub
|
||||
HMLAN_Write($$$)
|
||||
{
|
||||
my ($hash,$fn,$msg) = @_;
|
||||
|
||||
my $dst = substr($msg, 16, 6);
|
||||
if(!$lhash{$dst} && $dst ne "000000") { # Don't think I grok the logic
|
||||
HMLAN_SimpleWrite($hash, "+$dst,00,00,");
|
||||
HMLAN_SimpleWrite($hash, "+$dst,00,00,");
|
||||
HMLAN_SimpleWrite($hash, "+$dst,00,00,");
|
||||
HMLAN_SimpleWrite($hash, "-$dst");
|
||||
HMLAN_SimpleWrite($hash, "+$dst,00,00,");
|
||||
HMLAN_SimpleWrite($hash, "+$dst,00,00,");
|
||||
HMLAN_SimpleWrite($hash, "+$dst,00,00,");
|
||||
HMLAN_SimpleWrite($hash, "+$dst,00,00,");
|
||||
$lhash{$dst} = 1;
|
||||
}
|
||||
my $tm = int(gettimeofday()*1000) % 0xffffffff;
|
||||
$msg = sprintf("S%08X,00,00000000,01,%08X,%s",
|
||||
$tm, $tm, substr($msg, 4));
|
||||
HMLAN_SimpleWrite($hash, $msg);
|
||||
|
||||
# Avoid problems with structure set
|
||||
# TODO: rewrite it to use a queue+internaltimer like the CUL
|
||||
select(undef, undef, undef, 0.03);
|
||||
}
|
||||
|
||||
#####################################
|
||||
# called from the global loop, when the select for hash->{FD} reports data
|
||||
sub
|
||||
HMLAN_Read($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
my $buf = DevIo_SimpleRead($hash);
|
||||
return "" if(!defined($buf));
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $hmdata = $hash->{PARTIAL};
|
||||
Log 5, "HMLAN/RAW: $hmdata/$buf";
|
||||
$hmdata .= $buf;
|
||||
|
||||
while($hmdata =~ m/\n/) {
|
||||
my $rmsg;
|
||||
($rmsg,$hmdata) = split("\n", $hmdata, 2);
|
||||
$rmsg =~ s/\r//;
|
||||
HMLAN_Parse($hash, $rmsg) if($rmsg);
|
||||
}
|
||||
$hash->{PARTIAL} = $hmdata;
|
||||
}
|
||||
|
||||
sub
|
||||
HMLAN_uptime($)
|
||||
{
|
||||
my $msec = shift;
|
||||
|
||||
$msec = hex($msec);
|
||||
my $sec = int($msec/1000);
|
||||
return sprintf("%03d %02d:%02d:%02d.%03d",
|
||||
int($msec/86400000), int($sec/3600),
|
||||
int(($sec%3600)/60), $sec%60, $msec % 1000);
|
||||
}
|
||||
|
||||
sub
|
||||
HMLAN_Parse($$)
|
||||
{
|
||||
my ($hash, $rmsg) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $ll5 = GetLogLevel($name,5);
|
||||
my ($src, $status, $msec, $d2, $rssi, $msg);
|
||||
|
||||
my $dmsg = $rmsg;
|
||||
|
||||
Log $ll5, "HMLAN_Parse: $name $rmsg";
|
||||
if($rmsg =~ m/^E(......),(....),(........),(..),(....),(.*)/) {
|
||||
($src, $status, $msec, $d2, $rssi, $msg) =
|
||||
($1, $2, $3, $4, $5, $6);
|
||||
if ($hash->{HIDDev}) #added for HM-USB-CFG by peterp
|
||||
{
|
||||
$dmsg = sprintf("A%s", uc($msg));
|
||||
}
|
||||
else
|
||||
{
|
||||
$dmsg = sprintf("A%02X%s", length($msg)/2, uc($msg));
|
||||
}
|
||||
$hash->{uptime} = HMLAN_uptime($msec);
|
||||
|
||||
} elsif($rmsg =~ m/^R(........),(....),(........),(..),(....),(.*)/) {
|
||||
($src, $status, $msec, $d2, $rssi, $msg) =
|
||||
($1, $2, $3, $4, $5, $6);
|
||||
|
||||
if ($hash->{HIDDev}) #added for HM-USB-CFG by peterp
|
||||
{
|
||||
$dmsg = sprintf("A%s", uc($msg));
|
||||
}
|
||||
else
|
||||
{
|
||||
$dmsg = sprintf("A%02X%s", length($msg)/2, uc($msg));
|
||||
}
|
||||
$dmsg .= "NACK" if($status !~ m/00(01|02|21)/);
|
||||
$hash->{uptime} = HMLAN_uptime($msec);
|
||||
|
||||
} elsif($rmsg =~
|
||||
m/^HHM-LAN-IF,(....),(..........),(......),(......),(........),(....)/) {
|
||||
my ($vers, $serno, $d1, $owner, $msec, $d2) =
|
||||
(hex($1), $2, $3, $4, $5, $6);
|
||||
$hash->{serialNr} = $serno;
|
||||
$hash->{firmware} = sprintf("%d.%d", ($vers>>12)&0xf, $vers & 0xffff);
|
||||
$hash->{owner} = $owner;
|
||||
$hash->{uptime} = HMLAN_uptime($msec);
|
||||
my $myId = AttrVal($name, "hmId", $owner);
|
||||
if(lc($owner) ne lc($myId) && !AttrVal($name, "dummy", 0)) {
|
||||
Log 1, "HMLAN setting owner to $myId from $owner";
|
||||
HMLAN_SimpleWrite($hash, "A$myId");
|
||||
}
|
||||
return;
|
||||
|
||||
} elsif($rmsg =~ m/^I00.*/) {
|
||||
# Ack from the HMLAN
|
||||
return;
|
||||
|
||||
} else {
|
||||
Log $ll5, "$name Unknown msg >$rmsg<";
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
$hash->{"${name}_MSGCNT"}++;
|
||||
$hash->{"${name}_TIME"} = TimeNow();
|
||||
$hash->{RAWMSG} = $rmsg;
|
||||
my %addvals = (RAWMSG => $rmsg);
|
||||
if(defined($rssi)) {
|
||||
$rssi = hex($rssi)-65536;
|
||||
$hash->{RSSI} = $rssi;
|
||||
$addvals{RSSI} = $rssi;
|
||||
}
|
||||
Dispatch($hash, $dmsg, \%addvals);
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
HMLAN_Ready($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
return DevIo_OpenDev($hash, 1, "HMLAN_DoInit");
|
||||
}
|
||||
|
||||
########################
|
||||
sub
|
||||
HMLAN_SimpleWrite(@)
|
||||
{
|
||||
my ($hash, $msg, $nonl) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
return if(!$hash || AttrVal($hash->{NAME}, "dummy", undef));
|
||||
|
||||
select(undef, undef, undef, 0.01);
|
||||
Log GetLogLevel($name,5), "SW: $msg";
|
||||
if (!($hash->{HIDDev}))
|
||||
{
|
||||
$msg .= "\r\n" unless($nonl) ; #changed for HM-USB-CFG by peterp
|
||||
}
|
||||
syswrite($hash->{TCPDev}, $msg) if($hash->{TCPDev});
|
||||
DevIo_SimpleWrite($hash, $msg) if ($hash->{HIDDev}); #added for HM-USB-CFG by peterp
|
||||
}
|
||||
|
||||
########################
|
||||
sub
|
||||
HMLAN_DoInit($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $id = AttrVal($name, "hmId", undef);
|
||||
my $key = AttrVal($name, "hmKey", ""); # 36(!) hex digits
|
||||
|
||||
#my $s2000 = sprintf("%02X", time()-946681200); # sec since 2000
|
||||
|
||||
# Calculate the local time in seconds from 2000.
|
||||
my $t = time();
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($t);
|
||||
$t -= 946684800; # seconds between 01.01.2000, 00:00 and THE EPOCH (1970)
|
||||
$t -= 1*3600; # Timezone offset from UTC * 3600 (MEZ=1). FIXME/HARDCODED
|
||||
$t += 3600 if $isdst;
|
||||
my $s2000 = sprintf("%02X", $t);
|
||||
|
||||
HMLAN_SimpleWrite($hash, "A$id") if($id);
|
||||
HMLAN_SimpleWrite($hash, "C");
|
||||
HMLAN_SimpleWrite($hash, "Y01,01,$key");
|
||||
HMLAN_SimpleWrite($hash, "Y02,00,");
|
||||
HMLAN_SimpleWrite($hash, "Y03,00,");
|
||||
HMLAN_SimpleWrite($hash, "Y03,00,");
|
||||
HMLAN_SimpleWrite($hash, "T$s2000,04,00,00000000");
|
||||
|
||||
InternalTimer(gettimeofday()+25, "HMLAN_KeepAlive", $hash, 0);
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
HMLAN_KeepAlive($)
|
||||
{
|
||||
my $hash = shift;
|
||||
return if(!$hash->{FD});
|
||||
HMLAN_SimpleWrite($hash, "K");
|
||||
InternalTimer(gettimeofday()+25, "HMLAN_KeepAlive", $hash, 1) if (!($hash->{HIDDev})); #changed for HM-USB-CFG by peterp
|
||||
}
|
||||
|
||||
1;
|
@ -1,443 +0,0 @@
|
||||
##############################################
|
||||
# $Id$
|
||||
package main;
|
||||
use Device::USB;
|
||||
my $timeout = 1000 ;
|
||||
|
||||
sub DevIo_SimpleRead($);
|
||||
sub DevIo_TimeoutRead($$);
|
||||
sub DevIo_SimpleWrite($$);
|
||||
sub DevIo_OpenDev($$$);
|
||||
sub DevIo_CloseDev($);
|
||||
sub DevIo_Disconnected($);
|
||||
|
||||
########################
|
||||
sub
|
||||
DevIo_DoSimpleRead($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my ($buf, $res);
|
||||
|
||||
if($hash->{USBDev}) {
|
||||
$buf = $hash->{USBDev}->input();
|
||||
|
||||
} elsif($hash->{DIODev}) {
|
||||
$res = sysread($hash->{DIODev}, $buf, 256);
|
||||
$buf = undef if(!defined($res));
|
||||
|
||||
} elsif($hash->{TCPDev}) {
|
||||
$res = sysread($hash->{TCPDev}, $buf, 256);
|
||||
$buf = undef if(!defined($res));
|
||||
}
|
||||
######################################### HID by peterp
|
||||
elsif($hash->{HIDDev}) {
|
||||
my $r; #raw message
|
||||
my $b=0; #raw message payload
|
||||
my $c=0; # ignore counter
|
||||
my $d=0; #HM message length
|
||||
my $s = 0; #start counter
|
||||
my $start = 0; #raw header flag
|
||||
my $typ ="";
|
||||
|
||||
$res = sysread($hash->{HIDDev}, $buf, 512);
|
||||
$buf = undef if(!defined($res));
|
||||
|
||||
## HID specific
|
||||
for (my $i=0; $i<64;$i++)
|
||||
{
|
||||
if ($start != 0)
|
||||
{
|
||||
$r .= unpack('H*', substr($buf,4+$i*8,1)); #copy to raw HMmessage
|
||||
if ($typ eq "E")
|
||||
{
|
||||
if ($b > 12) #raw message payload
|
||||
{
|
||||
$d--;
|
||||
if ($d == 0)
|
||||
{
|
||||
$r .= "\n"; #form a raw HMmessage for parse like HMLAN
|
||||
$start = 0;
|
||||
# Log 4, "HMUSB HMmessage:$r";
|
||||
}
|
||||
}
|
||||
$b++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$d--;
|
||||
if ($d == 0)
|
||||
{
|
||||
Log 2, "HMUSB HMmessage:$r";
|
||||
$r .= "\n"; #form a raw HMmessage for parse like HMLAN
|
||||
$start = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# $r = unpack('H*', substr($buf,4+$i*8,1));
|
||||
# Log 4, "$r\t";
|
||||
if ( ord(substr($buf,4+$i*8,1)) == 69)
|
||||
{
|
||||
$start = 1; #raw header found
|
||||
$r = "E"; #start a raw HMmessage for parse like HMLAN
|
||||
$d = ord(substr($buf,4+($i+13)*8,1)); #calc HM message length
|
||||
$s = $i;
|
||||
$typ ="E";
|
||||
# Log 4, "HMUSB ReadSimple Magic found HMlen:$d";
|
||||
}
|
||||
elsif ( ord(substr($buf,4+$i*8,1)) == 73)
|
||||
{
|
||||
Log 2, "HMUSB ReadSimple Magic >I< found i:$i b:$b ";
|
||||
$start = 1; #raw header found
|
||||
$typ = "I";
|
||||
$d = 4;
|
||||
}
|
||||
elsif ( ord(substr($buf,4+$i*8,1)) == 82)
|
||||
{
|
||||
Log 2, "HMUSB ReadSimple Magic >R< found i:$i b:$b ";
|
||||
}
|
||||
elsif ( ord(substr($buf,4+$i*8,1)) == 72)
|
||||
{
|
||||
Log 2, "HMUSB ReadSimple Magic >H< USB-IF found i:$i b:$b";
|
||||
$start = 1; #raw header found
|
||||
$typ = "H";
|
||||
$d = 40;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c++; #ignore counter
|
||||
}
|
||||
}
|
||||
}
|
||||
# Log 4, "HMUSB ReadSimple all >$r< (raw Start $s ignored $c)";
|
||||
if ($typ eq "E")
|
||||
{
|
||||
my ($src, $status, $msec, $d2, $rssi, $msg);
|
||||
$r =~ m/^E(......)(....)(........)(..)(....)(.*)/;
|
||||
($src, $status, $msec, $d2, $rssi, $msg) =
|
||||
($1, $2, $3, $4, $5, $6);
|
||||
my $cmsg = "E".$src.",".$status.",".$msec.",".$d2.",".$rssi.",".$msg."\n";
|
||||
Log 4, "HMUSB ReadSimple converted $cmsg";
|
||||
return $cmsg;
|
||||
}
|
||||
elsif ($typ eq "H")
|
||||
{
|
||||
Log 4, "HMUSB ReadSimple Wakup found";
|
||||
my ($vers, $serno, $d1, $owner, $msec, $d2);
|
||||
$r =~ m/^HHM-USB-IF(....)(..........)(......)(......)(........)(....)/;
|
||||
($vers, $serno, $d1, $owner, $msec, $d2) =
|
||||
(hex($1), $2, $3, $4, $5, $6);
|
||||
my $wmsg = "HHM-USB-IF".",".$vers.",".$serno.",".$d1.",".$owner.",".$msec.",".$d2."\n";
|
||||
Log 2, "HMUSB ReadSimple Wakeup converted $wmsg";
|
||||
return $wmsg;
|
||||
}
|
||||
elsif ($typ eq "I")
|
||||
{
|
||||
$r =~ m/^I00.*/;
|
||||
return $r;
|
||||
}
|
||||
######################################### HIDDEV by peterp
|
||||
}
|
||||
return $buf;
|
||||
}
|
||||
|
||||
########################
|
||||
sub
|
||||
DevIo_SimpleRead($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $buf = DevIo_DoSimpleRead($hash);
|
||||
|
||||
###########
|
||||
# Lets' try again: Some drivers return len(0) on the first read...
|
||||
if(defined($buf) && length($buf) == 0) {
|
||||
$buf = DevIo_DoSimpleRead($hash);
|
||||
}
|
||||
|
||||
if(!defined($buf) || length($buf) == 0) {
|
||||
DevIo_Disconnected($hash);
|
||||
return undef;
|
||||
}
|
||||
return $buf;
|
||||
}
|
||||
|
||||
########################
|
||||
# Read until you get the timeout. Use it with care
|
||||
sub
|
||||
DevIo_TimeoutRead($$)
|
||||
{
|
||||
my ($hash, $timeout) = @_;
|
||||
|
||||
my $answer = "";
|
||||
for(;;) {
|
||||
my $rin = "";
|
||||
vec($rin, $hash->{FD}, 1) = 1;
|
||||
my $nfound = select($rin, undef, undef, $timeout);
|
||||
last if($nfound <= 0);
|
||||
my $r = DevIo_DoSimpleRead($hash);
|
||||
last if(!defined($r));
|
||||
$answer .= $r;
|
||||
}
|
||||
return $answer;
|
||||
}
|
||||
|
||||
########################
|
||||
# Input is HEX, with header and CRC
|
||||
sub
|
||||
DevIo_SimpleWrite($$)
|
||||
{
|
||||
my ($hash, $msg) = @_;
|
||||
return if(!$hash);
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
my $ll5 = GetLogLevel($name,3);
|
||||
Log $ll5, "DevIo SW: $msg";
|
||||
####################################################
|
||||
if($hash->{HIDDev}) #added for HM-USB-CFG by peterp
|
||||
{
|
||||
$msg =~ s/,//g;
|
||||
my $msg1 = substr($msg,0,1);
|
||||
my $msg2 = pack('H*', substr($msg,1));
|
||||
$msg = $msg1 . $msg2 . "\r\n";
|
||||
|
||||
syswrite($hash->{HIDDev}, $msg);
|
||||
|
||||
my $tmsg = unpack('H*', $msg);
|
||||
Log 2, "DevIo_SimpleWrite: $tmsg";
|
||||
}
|
||||
else
|
||||
####################################################
|
||||
{
|
||||
$msg = pack('H*', $msg) if($ishex);
|
||||
$hash->{USBDev}->write($msg) if($hash->{USBDev});
|
||||
syswrite($hash->{TCPDev}, $msg) if($hash->{TCPDev});
|
||||
syswrite($hash->{DIODev}, $msg) if($hash->{DIODev});
|
||||
}
|
||||
select(undef, undef, undef, 0.001);
|
||||
}
|
||||
|
||||
|
||||
########################
|
||||
sub
|
||||
DevIo_OpenDev($$$)
|
||||
{
|
||||
my ($hash, $reopen, $initfn) = @_;
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $name = $hash->{NAME};
|
||||
my $po;
|
||||
my $baudrate;
|
||||
($dev, $baudrate) = split("@", $dev);
|
||||
|
||||
|
||||
$hash->{PARTIAL} = "";
|
||||
Log 4, "DEVIO OpenDev $name device $dev"
|
||||
if(!$reopen);
|
||||
|
||||
if($dev =~ m/^(.+):([0-9]+)$/) { # host:port
|
||||
|
||||
# This part is called every time the timeout (5sec) is expired _OR_
|
||||
# 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;
|
||||
}
|
||||
|
||||
my $conn = IO::Socket::INET->new(PeerAddr => $dev);
|
||||
if($conn) {
|
||||
delete($hash->{NEXT_OPEN})
|
||||
|
||||
} else {
|
||||
Log(3, "Can't connect to IPDEV $dev: $!") if(!$reopen);
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
$hash->{STATE} = "disconnected";
|
||||
$hash->{NEXT_OPEN} = time()+60;
|
||||
return "";
|
||||
}
|
||||
|
||||
$hash->{TCPDev} = $conn;
|
||||
$hash->{FD} = $conn->fileno();
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
$selectlist{"$name.$dev"} = $hash;
|
||||
|
||||
} elsif($baudrate && lc($baudrate) eq "directio") { # Without Device::SerialPort
|
||||
|
||||
if(!open($po, "+<$dev")) {
|
||||
return undef if($reopen);
|
||||
Log(3, "Can't open $dev: $!");
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
$hash->{STATE} = "disconnected";
|
||||
return "";
|
||||
}
|
||||
|
||||
$hash->{DIODev} = $po;
|
||||
|
||||
if( $^O =~ /Win/ ) {
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
} else {
|
||||
$hash->{FD} = fileno($po);
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
$selectlist{"$name.$dev"} = $hash;
|
||||
}
|
||||
#################################################### HIDDEV by peterp
|
||||
} elsif($dev =~ m/^\/dev\/usb\/hiddev[0-9]$/)
|
||||
{
|
||||
if(!open($po, "+<$dev"))
|
||||
{
|
||||
return undef if($reopen);
|
||||
Log(3, "Can't open HIDD $dev: $!");
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
$hash->{STATE} = "disconnected";
|
||||
return "";
|
||||
}
|
||||
Log(2, "DevIo opened HID $dev"); #peterp
|
||||
|
||||
$hash->{HIDDev} = $po;
|
||||
|
||||
if( $^O =~ /Win/ ) {
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
} else {
|
||||
$hash->{FD} = fileno($po);
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
$selectlist{"$name.$dev"} = $hash;
|
||||
}
|
||||
#################################################### HIDDEV by peterp
|
||||
} else { # USB/Serial device
|
||||
|
||||
|
||||
if ($^O=~/Win/) {
|
||||
require Win32::SerialPort;
|
||||
$po = new Win32::SerialPort ($dev);
|
||||
} else {
|
||||
require Device::SerialPort;
|
||||
$po = new Device::SerialPort ($dev);
|
||||
}
|
||||
|
||||
if(!$po) {
|
||||
return undef if($reopen);
|
||||
Log(3, "Can't open USB/Seriell $dev: $!");
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
$hash->{STATE} = "disconnected";
|
||||
return "";
|
||||
}
|
||||
$hash->{USBDev} = $po;
|
||||
if( $^O =~ /Win/ ) {
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
} else {
|
||||
$hash->{FD} = $po->FILENO;
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
$selectlist{"$name.$dev"} = $hash;
|
||||
}
|
||||
|
||||
if($baudrate) {
|
||||
$po->reset_error();
|
||||
Log 3, "Setting $name baudrate to $baudrate";
|
||||
$po->baudrate($baudrate);
|
||||
$po->databits(8);
|
||||
$po->parity('none');
|
||||
$po->stopbits(1);
|
||||
$po->handshake('none');
|
||||
|
||||
# This part is for some Linux kernel versions whih has strange default
|
||||
# settings. Device::SerialPort is nice: if the flag is not defined for your
|
||||
# OS then it will be ignored.
|
||||
$po->stty_icanon(0);
|
||||
#$po->stty_parmrk(0); # The debian standard install does not have it
|
||||
$po->stty_icrnl(0);
|
||||
$po->stty_echoe(0);
|
||||
$po->stty_echok(0);
|
||||
$po->stty_echoctl(0);
|
||||
|
||||
# Needed for some strange distros
|
||||
$po->stty_echo(0);
|
||||
$po->stty_icanon(0);
|
||||
$po->stty_isig(0);
|
||||
$po->stty_opost(0);
|
||||
$po->stty_icrnl(0);
|
||||
}
|
||||
|
||||
$po->write_settings;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if($reopen) {
|
||||
Log 1, "$dev reappeared ($name)";
|
||||
} else {
|
||||
Log 3, "$name device $dev opened";
|
||||
}
|
||||
|
||||
$hash->{STATE}="opened";
|
||||
|
||||
my $ret;
|
||||
if($initfn) {
|
||||
my $ret = &$initfn($hash);
|
||||
if($ret) {
|
||||
DevIo_CloseDev($hash);
|
||||
Log 1, "Cannot init $dev, ignoring it";
|
||||
}
|
||||
}
|
||||
|
||||
DoTrigger($name, "CONNECTED") if($reopen);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
########################
|
||||
sub
|
||||
DevIo_CloseDev($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
|
||||
return if(!$dev);
|
||||
|
||||
if($hash->{TCPDev}) {
|
||||
$hash->{TCPDev}->close();
|
||||
delete($hash->{TCPDev});
|
||||
|
||||
} elsif($hash->{USBDev}) {
|
||||
$hash->{USBDev}->close() ;
|
||||
delete($hash->{USBDev});
|
||||
|
||||
} elsif($hash->{DIODev}) {
|
||||
close($hash->{DIODev});
|
||||
delete($hash->{DIODev});
|
||||
|
||||
} elsif($hash->{HIDDev}) { #added for HM-USB-CFG by peterp
|
||||
close($hash->{HIDDev});
|
||||
delete($hash->{HIDDev});
|
||||
|
||||
}
|
||||
($dev, undef) = split("@", $dev); # Remove the baudrate
|
||||
delete($selectlist{"$name.$dev"});
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
delete($hash->{FD});
|
||||
}
|
||||
|
||||
sub
|
||||
DevIo_Disconnected($)
|
||||
{
|
||||
my $hash = shift;
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $name = $hash->{NAME};
|
||||
my $baudrate;
|
||||
($dev, $baudrate) = split("@", $dev);
|
||||
|
||||
return if(!defined($hash->{FD})); # Already deleted or RFR
|
||||
|
||||
Log 1, "$dev disconnected, waiting to reappear";
|
||||
DevIo_CloseDev($hash);
|
||||
$readyfnlist{"$name.$dev"} = $hash; # Start polling
|
||||
$hash->{STATE} = "disconnected";
|
||||
|
||||
# Without the following sleep the open of the device causes a SIGSEGV,
|
||||
# and following opens block infinitely. Only a reboot helps.
|
||||
sleep(5);
|
||||
|
||||
DoTrigger($name, "DISCONNECTED");
|
||||
}
|
||||
|
||||
|
||||
1;
|
@ -1,90 +0,0 @@
|
||||
Hallo Rudi,
|
||||
|
||||
anbei meine aktuelle Version von HMLAN ud DevIo für den HM-USB-CFG.
|
||||
Ich hab es bislang aber nicht geschaft zu senden. Als Monitor ist die
|
||||
Version aber brauchbar. Bitte schau drüber ob die Qualität for das
|
||||
contrib Verzeichniss reicht. Wenn's passt bitte einchecken. Vielleicht
|
||||
hat ja jemand eine Idee was fehlt...
|
||||
|
||||
Ich hab alle Änderungen deutlich mit
|
||||
|
||||
for HM-USB-CFG by peterp bzw. HIDDEV by peterp
|
||||
|
||||
gekennzeichnet und mit
|
||||
|
||||
if($hash->{HIDDev})
|
||||
|
||||
abgetrennt. Die Originalfuntionalität sollte also durch meine
|
||||
Änderungen nicht beeinträchtigt sein.
|
||||
|
||||
In der config datei definiert man
|
||||
|
||||
define HMUSB HMLAN /dev/usb/hiddev0
|
||||
attr HMUSB addvaltrigger RSSI
|
||||
attr HMUSB hmId 123456
|
||||
attr HMUSB hmProtocolEvents 1
|
||||
attr HMUSB room Innen
|
||||
|
||||
in der Logdatei sieht das dann so aus:
|
||||
|
||||
2012.04.01 20:02:22.828 2: DevIo opened HID /dev/usb/hiddev0
|
||||
2012.04.01 20:02:22.839 2: DevIo_SimpleWrite: 4178987d0d0a
|
||||
2012.04.01 20:02:22.850 2: DevIo_SimpleWrite: 430d0a
|
||||
2012.04.01 20:02:22.862 2: DevIo_SimpleWrite: 5901010d0a
|
||||
2012.04.01 20:02:22.873 2: DevIo_SimpleWrite: 5902000d0a
|
||||
2012.04.01 20:02:22.885 2: DevIo_SimpleWrite: 5903000d0a
|
||||
2012.04.01 20:02:22.896 2: DevIo_SimpleWrite: 5903000d0a
|
||||
2012.04.01 20:02:22.908 2: DevIo_SimpleWrite: 54170b54ae0400000000000d0a
|
||||
2012.04.01 20:02:23.607 0: Server started (version =VERS= from =DATE=
|
||||
($Id$), pid 10178)
|
||||
2012.04.01 20:02:47.946 2: DevIo_SimpleWrite: 4b0d0a
|
||||
2012.04.01 20:03:10.639 2: SYS HMUSB RCV L:0C N:8A CMD:A041
|
||||
(TYPE=65,BCAST,BIDI,RPTEN) SRC:14F617 DST:123456 018100
|
||||
2012.04.01 20:03:10.755 2: DevIo_SimpleWrite: 2b14f61700000d0a
|
||||
2012.04.01 20:03:10.767 2: DevIo_SimpleWrite: 2b14f61700000d0a
|
||||
2012.04.01 20:03:10.779 2: DevIo_SimpleWrite: 2b14f61700000d0a
|
||||
2012.04.01 20:03:10.790 2: DevIo_SimpleWrite: 2d14f6170d0a
|
||||
2012.04.01 20:03:10.802 2: DevIo_SimpleWrite: 2b14f61700000d0a
|
||||
2012.04.01 20:03:10.813 2: DevIo_SimpleWrite: 2b14f61700000d0a
|
||||
2012.04.01 20:03:10.825 2: DevIo_SimpleWrite: 2b14f61700000d0a
|
||||
2012.04.01 20:03:10.837 2: DevIo_SimpleWrite: 2b14f61700000d0a
|
||||
2012.04.01 20:03:10.848 2: DevIo_SimpleWrite:
|
||||
536f1333ac0000000000016f1333ac01800212345614f617010100000d0a
|
||||
2012.04.01 20:03:10.889 2: SYS HMUSB SND L:0D N:01 CMD:8002
|
||||
(TYPE=2,RPTEN) SRC:123456 DST:14F617 01010000 (ACK_STATUS CHANNEL:01
|
||||
STATUS:00)
|
||||
2012.04.01 20:03:10.908 2: HM-TFK LSE_TFKTEST closed
|
||||
2012.04.01 20:03:10.911 2: HM-TFK LSE_TFKTEST contact: closed
|
||||
2012.04.01 20:03:10.930 2: SYS HMUSB RCV L:0C N:8A CMD:A041
|
||||
(TYPE=65,BIDI,RPTEN) SRC:14F617 DST:123456 018100
|
||||
2012.04.01 20:03:11.046 2: DevIo_SimpleWrite:
|
||||
536f1334710000000000016f13347102800212345614f617010100000d0a
|
||||
2012.04.01 20:03:11.086 2: SYS HMUSB SND L:0D N:02 CMD:8002
|
||||
(TYPE=2,RPTEN) SRC:123456 DST:14F617 01010000 (ACK_STATUS CHANNEL:01
|
||||
STATUS:00)
|
||||
2012.04.01 20:03:11.407 2: SYS HMUSB RCV L:0C N:8A CMD:A041
|
||||
(TYPE=65,BIDI,RPTEN) SRC:14F617 DST:123456 018100
|
||||
2012.04.01 20:03:11.523 2: DevIo_SimpleWrite:
|
||||
536f13364e0000000000016f13364e03800212345614f617010100000d0a
|
||||
2012.04.01 20:03:11.563 2: SYS HMUSB SND L:0D N:03 CMD:8002
|
||||
(TYPE=2,RPTEN) SRC:123456 DST:14F617 01010000 (ACK_STATUS CHANNEL:01
|
||||
STATUS:00)
|
||||
2012.04.01 20:03:12.431 2: SYS HMUSB RCV L:0C N:8A CMD:A041
|
||||
(TYPE=65,BIDI,RPTEN) SRC:14F617 DST:123456 018100
|
||||
2012.04.01 20:03:12.547 2: DevIo_SimpleWrite:
|
||||
536f133a4e0000000000016f133a4e04800212345614f617010100000d0a
|
||||
2012.04.01 20:03:12.587 2: SYS HMUSB SND L:0D N:04 CMD:8002
|
||||
(TYPE=2,RPTEN) SRC:123456 DST:14F617 01010000 (ACK_STATUS CHANNEL:01
|
||||
STATUS:00)
|
||||
2012.04.01 20:03:14.447 2: SYS HMUSB RCV L:0C N:8A CMD:A041
|
||||
(TYPE=65,BIDI,RPTEN) SRC:14F617 DST:123456 018100
|
||||
2012.04.01 20:03:14.563 2: DevIo_SimpleWrite:
|
||||
536f13422e0000000000016f13422e05800212345614f617010100000d0a
|
||||
2012.04.01 20:03:14.603 2: SYS HMUSB SND L:0D N:05 CMD:8002
|
||||
(TYPE=2,RPTEN) SRC:123456 DST:14F617 01010000 (ACK_STATUS CHANNEL:01
|
||||
STATUS:00)
|
||||
2012.04.01 20:03:18.511 2: SYS HMUSB RCV L:0C N:8A CMD:A041
|
||||
(TYPE=65,BIDI,RPTEN) SRC:14F617 DST:123456 018100
|
||||
|
||||
Grüße aus Wien
|
||||
Peter
|
Loading…
Reference in New Issue
Block a user