mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
USB reconnect fixed
git-svn-id: https://svn.fhem.de/fhem/trunk@878 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
5b7d9481bc
commit
a5c65608f9
@ -15,7 +15,6 @@ package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Math::Complex;
|
||||
use Device::SerialPort;
|
||||
|
||||
#####################################
|
||||
@ -25,7 +24,7 @@ USBWX_Initialize($)
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{ReadFn} = "USBWX_Read";
|
||||
# $hash->{ReadyFn} = "USBWX_Ready";
|
||||
$hash->{ReadyFn} = "USBWX_Ready";
|
||||
# Normal devices
|
||||
$hash->{DefFn} = "USBWX_Define";
|
||||
$hash->{UndefFn} = "USBWX_Undef";
|
||||
@ -34,10 +33,15 @@ USBWX_Initialize($)
|
||||
$hash->{SetFn} = "USBWX_Set";
|
||||
$hash->{ParseFn} = "USBWX_Parse";
|
||||
|
||||
$hash->{StateFn} = "USBWX_SetState";
|
||||
|
||||
$hash->{Match} = ".*";
|
||||
|
||||
#$hash->{AttrList}= "model:USB-WDE1 loglevel:0,1,2,3,4,5,6";
|
||||
$hash->{AttrList}= "loglevel:0,1,2,3,4,5,6";
|
||||
|
||||
$hash->{ShutdownFn} = "USBWX_Shutdown";
|
||||
|
||||
}
|
||||
|
||||
#####################################
|
||||
@ -98,116 +102,125 @@ USBWX_Define($$)
|
||||
sub
|
||||
USBWX_OpenDev($$)
|
||||
{
|
||||
my ($hash, $reopen) = @_;
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $name = $hash->{NAME};
|
||||
my $po;
|
||||
my ($hash, $reopen) = @_;
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $name = $hash->{NAME};
|
||||
my $po;
|
||||
|
||||
$hash->{PARTIAL} = "";
|
||||
Log 3, "USBWX opening $name device $dev"
|
||||
if(!$reopen);
|
||||
#Log 1, "USBWX opening $name device $dev reopen = $reopen";
|
||||
|
||||
if ($^O=~/Win/)
|
||||
{
|
||||
$hash->{PARTIAL} = "";
|
||||
Log 3, "USBWX opening $name device $dev"
|
||||
if(!$reopen);
|
||||
|
||||
if ($^O=~/Win/) {
|
||||
require Win32::SerialPort;
|
||||
$po = new Win32::SerialPort ($dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
require Device::SerialPort;
|
||||
$po = Device::SerialPort->new($dev);
|
||||
}
|
||||
} else {
|
||||
require Device::SerialPort;
|
||||
$po = new Device::SerialPort ($dev);
|
||||
}
|
||||
|
||||
if(!$po)
|
||||
{
|
||||
if(!$po) {
|
||||
return undef if($reopen);
|
||||
Log(2, "USBWX Can't open $dev: $!");
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
$hash->{STATE} = "disconnected";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
$hash->{USBWX} = $po;
|
||||
if( $^O =~ /Win/ )
|
||||
{
|
||||
$hash->{USBWX} = $po;
|
||||
|
||||
if( $^O =~ /Win/ ) {
|
||||
$readyfnlist{"$name.$dev"} = $hash;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$hash->{FD} = $po->FILENO;
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
$selectlist{"$name.$dev"} = $hash;
|
||||
}
|
||||
}
|
||||
|
||||
$po->baudrate(9600);
|
||||
$po->databits(8);
|
||||
$po->parity('none');
|
||||
$po->stopbits(1);
|
||||
$po->handshake('none');
|
||||
$po->reset_error();
|
||||
$po->lookclear; # clear buffers
|
||||
$po->baudrate(9600) || Log 1, "USBWX could not set baudrate";
|
||||
$po->databits(8) || Log 1, "USBWX could not set databits";
|
||||
$po->parity('none') || Log 1, "USBWX could not set parity";
|
||||
$po->stopbits(1) || Log 1, "USBWX could not set stopbits";
|
||||
$po->handshake('none') || Log 1, "USBWX could not set handshake";
|
||||
#$po->reset_error() || Log 1, "USBWX reset_error";
|
||||
$po->lookclear || Log 1, "USBWX could not set lookclear";
|
||||
|
||||
$po->write_settings || Log 1, "USBWX could not write_settings $dev";
|
||||
|
||||
if($reopen)
|
||||
{
|
||||
if($reopen) {
|
||||
Log 1, "USBWX $dev reappeared ($name)";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Log 2, "USBWX opened device $dev";
|
||||
}
|
||||
}
|
||||
|
||||
$hash->{STATE}=""; # Allow InitDev to set the state
|
||||
my $ret = USBWX_DoInit($hash);
|
||||
$hash->{po} = $po;
|
||||
$hash->{socket} = 0;
|
||||
|
||||
if($ret)
|
||||
{
|
||||
# try again
|
||||
Log 1, "USBWX Cannot init $dev, at first try. Trying again.";
|
||||
my $ret = USBWX_DoInit($hash);
|
||||
if($ret)
|
||||
{
|
||||
USBWX_CloseDev($hash);
|
||||
Log 1, "USBWX Cannot init $dev, ignoring it";
|
||||
# return "USBWX Error Init string.";
|
||||
}
|
||||
}
|
||||
DoTrigger($name, "CONNECTED") if($reopen);
|
||||
$hash->{STATE}=""; # Allow InitDev to set the state
|
||||
my $ret = USBWX_DoInit($hash);
|
||||
|
||||
return undef;
|
||||
if($ret) {
|
||||
# try again
|
||||
Log 1, "USBWX Cannot init $dev, at first try. Trying again.";
|
||||
my $ret = USBWX_DoInit($hash);
|
||||
if($ret) {
|
||||
USBWX_CloseDev($hash);
|
||||
Log 1, "USBWX Cannot init $dev, ignoring it";
|
||||
return "USBWX Error Init string.";
|
||||
}
|
||||
}
|
||||
|
||||
DoTrigger($name, "CONNECTED") if($reopen);
|
||||
|
||||
#return undef;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
########################
|
||||
sub
|
||||
USBWX_CloseDev($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
|
||||
return if(!$dev);
|
||||
return if(!$dev);
|
||||
|
||||
$hash->{USBWX}->close() ;
|
||||
delete($hash->{USBWX});
|
||||
delete($selectlist{"$name.$dev"});
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
delete($hash->{FD});
|
||||
Log 1, "USBWX: closing $dev";
|
||||
|
||||
$hash->{USBWX}->close() ;
|
||||
delete($hash->{USBWX});
|
||||
|
||||
delete($selectlist{"$name.$dev"});
|
||||
delete($readyfnlist{"$name.$dev"});
|
||||
delete($hash->{FD});
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
USBWX_Ready($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my ($hash) = @_;
|
||||
|
||||
return USBWX_OpenDev($hash, 1)
|
||||
if($hash->{STATE} eq "disconnected");
|
||||
return USBWX_OpenDev($hash, 1)
|
||||
if($hash->{STATE} eq "disconnected");
|
||||
|
||||
# This is relevant for windows/USB only
|
||||
my $po = $hash->{USBWX};
|
||||
my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
|
||||
return ($InBytes>0);
|
||||
# This is relevant for windows/USB only
|
||||
my $po = $hash->{USBWX};
|
||||
my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
|
||||
return ($InBytes>0);
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
USBWX_SetState($$$$)
|
||||
{
|
||||
my ($hash, $tim, $vt, $val) = @_;
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
USBWX_Clear($)
|
||||
@ -266,19 +279,19 @@ USBWX_Read($)
|
||||
#Log 4, "USBWX Read State:$hash->{STATE}";
|
||||
|
||||
my $mybuf = USBWX_SimpleRead($hash);
|
||||
|
||||
my $usbwx_data = $hash->{PARTIAL};
|
||||
#Log 1, "USBWX usbwxdata='$usbwx_data' $mybuf='$mybuf'";
|
||||
|
||||
if ( ( length($usbwx_data) > 1) && ($mybuf eq "\n") ) {
|
||||
Log 4, "USBWX/RAW Satz: $usbwx_data !!";
|
||||
#Log 1, "USBWX/RAW line='$usbwx_data'";
|
||||
}
|
||||
|
||||
if(!defined($mybuf) || length($mybuf) == 0) {
|
||||
USBWX_Disconnected($hash);
|
||||
return "";
|
||||
}
|
||||
|
||||
if ( ( length($usbwx_data) > 1) && ($mybuf eq "\n") ) {
|
||||
Log 4, "USBWX/RAW line: '$usbwx_data'";
|
||||
#Log 1, "USBWX/RAW line='$usbwx_data'";
|
||||
}
|
||||
|
||||
if ($mybuf eq "\n") {
|
||||
USBWX_Parse($hash, $usbwx_data);
|
||||
@ -290,6 +303,13 @@ USBWX_Read($)
|
||||
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
USBWX_Shutdown($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
@ -329,7 +349,7 @@ my $buf;
|
||||
if($hash->{USBWX})
|
||||
{
|
||||
$buf = $hash->{USBWX}->read(1) ;
|
||||
if (length($buf) == 0)
|
||||
if (!defined($buf) || length($buf) == 0)
|
||||
{
|
||||
$buf = $hash->{USBWX}->read(1) ;
|
||||
}
|
||||
@ -352,31 +372,6 @@ select(undef, undef, undef, 0.001);
|
||||
}
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Dewpoint calculation.
|
||||
# see http://www.faqs.org/faqs/meteorology/temp-dewpoint/ "5. EXAMPLE"
|
||||
sub
|
||||
USBWX_Dewpoint($$)
|
||||
{
|
||||
my ($temperature, $humidity) = @_;
|
||||
|
||||
my $dp;
|
||||
|
||||
my $A = 17.2694;
|
||||
my $B = ($temperature > 0) ? 237.3 : 265.5;
|
||||
my $es = 610.78 * exp( $A * $temperature / ($temperature + $B) );
|
||||
my $e = $humidity/ 100 * $es;
|
||||
if ($e == 0) {
|
||||
Log 1, "Error: Dewpointcalculation e=0";
|
||||
return 0;
|
||||
}
|
||||
my $f = ln( $e / 610.78 ) / $A;
|
||||
|
||||
$dp = $B * $f / ( 1 - $f );
|
||||
|
||||
return($dp);
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
USBWX_Parse($$)
|
||||
@ -449,7 +444,7 @@ USBWX_Parse($$)
|
||||
$def->{READINGS}{$sensor}{VAL} = $current;
|
||||
$def->{CHANGED}[$n++] = $sensor . ": " . $current;
|
||||
|
||||
my $dewpoint = sprintf("%.1f", USBWX_Dewpoint($temperature,$humidity));
|
||||
my $dewpoint = sprintf("%.1f", dewpoint($temperature,$humidity));
|
||||
$current = $dewpoint;
|
||||
$sensor = "dewpoint";
|
||||
$def->{READINGS}{$sensor}{TIME} = $tm;
|
||||
@ -581,6 +576,12 @@ USBWX_Parse($$)
|
||||
Log 4, "USBWX BAUD rmsg='$rmsg'";
|
||||
} elsif ($rmsg =~ /^OK.*/) {
|
||||
Log 4, "USBWX EMPTY rmsg='$rmsg'";
|
||||
} elsif ($rmsg =~ /^FullBuff/) {
|
||||
Log 1, "USBWX Fullbuf-Error rmsg='$rmsg'";
|
||||
Log 1, "USBWX closing device";
|
||||
USBWX_Disconnected($hash);
|
||||
Log 1, "USBWX opening device";
|
||||
my $ret = USBWX_OpenDev($hash, 0);
|
||||
} elsif ($rmsg eq "") {
|
||||
Log 4, "USBWX OK rmsg='$rmsg'";
|
||||
} else {
|
||||
@ -593,22 +594,22 @@ USBWX_Parse($$)
|
||||
sub
|
||||
USBWX_Disconnected($)
|
||||
{
|
||||
my $hash = shift;
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $name = $hash->{NAME};
|
||||
my $hash = shift;
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
return if(!defined($hash->{FD})); # Already deleted
|
||||
return if(!defined($hash->{FD})); # Already deleted
|
||||
|
||||
Log 1, "USBWX $dev disconnected, waiting to reappear";
|
||||
USBWX_CloseDev($hash);
|
||||
$readyfnlist{"$name.$dev"} = $hash; # Start polling
|
||||
$hash->{STATE} = "disconnected";
|
||||
Log 1, "USBWX dev='$dev' name='$name' disconnected, waiting to reappear";
|
||||
USBWX_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);
|
||||
# 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");
|
||||
DoTrigger($name, "DISCONNECTED");
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user