mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
OWX_SER: implement DevIo-based communication and reconnect
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@6271 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
3fd88da9b0
commit
1a73078526
@ -84,7 +84,6 @@ if( $^O =~ /Win/ ) {
|
|||||||
|
|
||||||
use Time::HiRes qw( gettimeofday tv_interval );
|
use Time::HiRes qw( gettimeofday tv_interval );
|
||||||
|
|
||||||
require "$main::attr{global}{modpath}/FHEM/DevIo.pm";
|
|
||||||
sub Log3($$$);
|
sub Log3($$$);
|
||||||
|
|
||||||
use vars qw{%owg_family %gets %sets $owx_async_version $owx_async_debug};
|
use vars qw{%owg_family %gets %sets $owx_async_version $owx_async_debug};
|
||||||
@ -275,18 +274,12 @@ sub OWX_ASYNC_Ready ($) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
sub OWX_ASYNC_Read ($) {
|
sub OWX_ASYNC_Read ($) {
|
||||||
my $hash = shift;
|
my ($hash) = @_;
|
||||||
Log3 ($hash->{NAME},5,"OWX_ASYNC_Read") if ($owx_async_debug > 2);
|
Log3 ($hash->{NAME},5,"OWX_ASYNC_Read") if ($owx_async_debug > 2);
|
||||||
OWX_ASYNC_Poll($hash);
|
|
||||||
OWX_ASYNC_RunTasks($hash);
|
|
||||||
};
|
|
||||||
|
|
||||||
sub OWX_ASYNC_Poll ($) {
|
|
||||||
my $hash = shift;
|
|
||||||
Log3 ($hash->{NAME},5,"OWX_ASYNC_Poll") if ($owx_async_debug > 2);
|
|
||||||
if (defined $hash->{ASYNC}) {
|
if (defined $hash->{ASYNC}) {
|
||||||
$hash->{ASYNC}->poll($hash);
|
$hash->{ASYNC}->poll($hash);
|
||||||
};
|
};
|
||||||
|
OWX_ASYNC_RunTasks($hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
sub OWX_ASYNC_Disconnect($) {
|
sub OWX_ASYNC_Disconnect($) {
|
||||||
@ -295,25 +288,8 @@ sub OWX_ASYNC_Disconnect($) {
|
|||||||
Log3 ($hash->{NAME},3, "OWX_ASYNC_Disconnect");
|
Log3 ($hash->{NAME},3, "OWX_ASYNC_Disconnect");
|
||||||
if (defined $async) {
|
if (defined $async) {
|
||||||
$async->exit($hash);
|
$async->exit($hash);
|
||||||
};
|
|
||||||
my $times = AttrVal($hash->{NAME},"timeout",5000) / 50; #timeout in ms, defaults to 1 sec?
|
|
||||||
for (my $i=0;$i<$times;$i++) {
|
|
||||||
OWX_ASYNC_Poll($hash);
|
|
||||||
if ($hash->{STATE} ne "Active") {
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sub OWX_ASYNC_Disconnected($) {
|
|
||||||
my ($hash) = @_;
|
|
||||||
Log3 ($hash->{NAME},4, "OWX_ASYNC_Disconnected");
|
|
||||||
if ($hash->{ASYNC} and $hash->{ASYNC} != $hash->{OWX}) {
|
|
||||||
delete $hash->{ASYNC};
|
delete $hash->{ASYNC};
|
||||||
};
|
};
|
||||||
if (my $owx = $hash->{OWX}) {
|
|
||||||
$owx->Disconnect($hash);
|
|
||||||
};
|
|
||||||
$hash->{STATE} = "disconnected" if $hash->{STATE} eq "Active";
|
$hash->{STATE} = "disconnected" if $hash->{STATE} eq "Active";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -712,7 +688,7 @@ sub OWX_ASYNC_Init ($) {
|
|||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
if (defined ($hash->{ASNYC})) {
|
if (defined ($hash->{ASNYC})) {
|
||||||
$hash->{ASYNC}->exit($hash);
|
$hash->{ASYNC}->exit($hash);
|
||||||
$hash->{ASYNC} = undef; #TODO should we call delete on $hash->{ASYNC}?
|
delete $hash->{ASYNC}; #TODO should we call delete on $hash->{ASYNC}?
|
||||||
}
|
}
|
||||||
#-- get the interface
|
#-- get the interface
|
||||||
my $owx = $hash->{OWX};
|
my $owx = $hash->{OWX};
|
||||||
@ -729,6 +705,7 @@ sub OWX_ASYNC_Init ($) {
|
|||||||
$hash->{STATE} = "Init Failed: $err";
|
$hash->{STATE} = "Init Failed: $err";
|
||||||
return "OWX_ASYNC_Init failed: $err";
|
return "OWX_ASYNC_Init failed: $err";
|
||||||
};
|
};
|
||||||
|
return undef unless $ret;
|
||||||
$hash->{ASYNC} = $ret ;
|
$hash->{ASYNC} = $ret ;
|
||||||
$hash->{ASYNC}->{debug} = $owx_async_debug;
|
$hash->{ASYNC}->{debug} = $owx_async_debug;
|
||||||
$hash->{INTERFACE} = $owx->{interface};
|
$hash->{INTERFACE} = $owx->{interface};
|
||||||
@ -1016,7 +993,8 @@ sub OWX_ASYNC_RunToCompletion($$) {
|
|||||||
OWX_ASYNC_Schedule($hash,$task);
|
OWX_ASYNC_Schedule($hash,$task);
|
||||||
my $master = $hash->{TYPE} eq "OWX_ASYNC" ? $hash : $hash->{IODev};
|
my $master = $hash->{TYPE} eq "OWX_ASYNC" ? $hash : $hash->{IODev};
|
||||||
do {
|
do {
|
||||||
OWX_ASYNC_Poll($master);
|
die "interface $master->{INTERFACE} not active" unless defined $hash->{ASYNC};
|
||||||
|
$hash->{ASYNC}->poll($hash);
|
||||||
OWX_ASYNC_RunTasks($master);
|
OWX_ASYNC_RunTasks($master);
|
||||||
$task_state = $task->PT_STATE();
|
$task_state = $task->PT_STATE();
|
||||||
} while ($task_state == PT_INITIAL or $task_state == PT_WAITING or $task_state == PT_YIELDED);
|
} while ($task_state == PT_INITIAL or $task_state == PT_WAITING or $task_state == PT_YIELDED);
|
||||||
|
@ -86,24 +86,8 @@ sub block ($) {
|
|||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
sub query ($$$) {
|
sub query ($$$) {
|
||||||
|
|
||||||
my ($serial,$cmd,$retlen) = @_;
|
my ($serial,$cmd,$retlen) = @_;
|
||||||
my ($i,$j,$k,$l,$m,$n);
|
main::DevIo_SimpleWrite($serial->{hash},$cmd,0);
|
||||||
|
|
||||||
#-- get hardware device
|
|
||||||
my $hwdevice = $serial->{hwdevice};
|
|
||||||
|
|
||||||
die "OWX_DS2480: query with no hwdevice" unless (defined $hwdevice);
|
|
||||||
|
|
||||||
$hwdevice->baudrate($serial->{baud});
|
|
||||||
$hwdevice->write_settings;
|
|
||||||
|
|
||||||
main::Log3($serial->{name},5, "OWX_DS2480.query sending out: ".unpack ("H*",$cmd));
|
|
||||||
|
|
||||||
my $count_out = $hwdevice->write($cmd);
|
|
||||||
|
|
||||||
die "OWX_DS2480: Write incomplete ".(defined $count_out ? $count_out : "undefined")." not equal ".(length($cmd))."" if (!(defined $count_out) or ($count_out ne length($cmd)));
|
|
||||||
|
|
||||||
$serial->{retlen} += $retlen;
|
$serial->{retlen} += $retlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,16 +103,12 @@ sub query ($$$) {
|
|||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
sub read() {
|
sub read() {
|
||||||
my $serial = shift;
|
my ($serial) = @_;
|
||||||
my ($i,$j,$k);
|
|
||||||
|
|
||||||
#-- get hardware device
|
|
||||||
my $hwdevice = $serial->{hwdevice};
|
|
||||||
return undef unless (defined $hwdevice);
|
|
||||||
|
|
||||||
#-- read the data
|
#-- read the data
|
||||||
my ($count_in, $string_part) = $hwdevice->read(255);
|
my $string_part = main::DevIo_DoSimpleRead($serial->{hash});
|
||||||
return undef if (not defined $count_in or not defined $string_part);
|
return undef unless defined $string_part;
|
||||||
|
my $count_in = length ($string_part);
|
||||||
$serial->{string_in} .= $string_part;
|
$serial->{string_in} .= $string_part;
|
||||||
$serial->{retcount} += $count_in;
|
$serial->{retcount} += $count_in;
|
||||||
$serial->{num_reads}++;
|
$serial->{num_reads}++;
|
||||||
|
@ -30,6 +30,8 @@ use warnings;
|
|||||||
|
|
||||||
use vars qw/@ISA/;
|
use vars qw/@ISA/;
|
||||||
|
|
||||||
|
require "$main::attr{global}{modpath}/FHEM/DevIo.pm";
|
||||||
|
|
||||||
use Time::HiRes qw( gettimeofday );
|
use Time::HiRes qw( gettimeofday );
|
||||||
use ProtoThreads;
|
use ProtoThreads;
|
||||||
no warnings 'deprecated';
|
no warnings 'deprecated';
|
||||||
@ -44,8 +46,6 @@ sub new() {
|
|||||||
my $class = shift;
|
my $class = shift;
|
||||||
my $self = {
|
my $self = {
|
||||||
interface => "serial",
|
interface => "serial",
|
||||||
#-- baud rate serial interface
|
|
||||||
baud => 9600,
|
|
||||||
#-- 16 byte search string
|
#-- 16 byte search string
|
||||||
search => [0,0,0,0 ,0,0,0,0, 0,0,0,0, 0,0,0,0],
|
search => [0,0,0,0 ,0,0,0,0, 0,0,0,0, 0,0,0,0],
|
||||||
ROM_ID => [0,0,0,0 ,0,0,0,0],
|
ROM_ID => [0,0,0,0 ,0,0,0,0],
|
||||||
@ -64,7 +64,15 @@ sub new() {
|
|||||||
|
|
||||||
sub poll($) {
|
sub poll($) {
|
||||||
my ( $self ) = @_;
|
my ( $self ) = @_;
|
||||||
$self->read();
|
my $hash = $self->{hash};
|
||||||
|
if(defined($hash->{FD})) {
|
||||||
|
my ($rin,$win);
|
||||||
|
vec($rin, $hash->{FD}, 1) = 1;
|
||||||
|
vec($win, $hash->{FD}, 1) = 1;
|
||||||
|
if (select($rin, $win, $rin | $win, 2)) { #TODO: implement attribute based timeout
|
||||||
|
main::OWX_ASYNC_Disconnect($hash) unless $self->read();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
@ -101,6 +109,9 @@ sub Define ($$) {
|
|||||||
#-- let fhem.pl MAIN call OWX_Ready when setup is done.
|
#-- let fhem.pl MAIN call OWX_Ready when setup is done.
|
||||||
$main::readyfnlist{"$hash->{NAME}.$device"} = $hash;
|
$main::readyfnlist{"$hash->{NAME}.$device"} = $hash;
|
||||||
|
|
||||||
|
$self->{baud} = $baudrate ? $baudrate : 9600;
|
||||||
|
$self->{hash} = $hash;
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,13 +164,6 @@ sub get_pt_execute($$$$) {
|
|||||||
PT_BEGIN($thread);
|
PT_BEGIN($thread);
|
||||||
$thread->{writedata} = $writedata;
|
$thread->{writedata} = $writedata;
|
||||||
|
|
||||||
#-- get the interface
|
|
||||||
my $interface = $self->{interface};
|
|
||||||
my $hwdevice = $self->{hwdevice};
|
|
||||||
unless (defined $hwdevice) {
|
|
||||||
PT_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->reset() if ($reset);
|
$self->reset() if ($reset);
|
||||||
|
|
||||||
if (defined $writedata or $numread) {
|
if (defined $writedata or $numread) {
|
||||||
@ -263,30 +267,18 @@ sub get_pt_discover() {
|
|||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
||||||
sub initialize($) {
|
sub initialize() {
|
||||||
my ($self,$hash) = @_;
|
my ($self) = @_;
|
||||||
my ($i,$j,$k,$l,$res,$ret,$ress);
|
my ($i,$j,$k,$l,$res,$ret,$ress);
|
||||||
#-- Second step in case of serial device: open the serial device to test it
|
#-- Second step in case of serial device: open the serial device to test it
|
||||||
|
my $hash = $self->{hash};
|
||||||
my $msg = "OWX_SER: Serial device $hash->{DeviceName}";
|
my $msg = "OWX_SER: Serial device $hash->{DeviceName}";
|
||||||
main::DevIo_OpenDev($hash,0,undef);
|
main::DevIo_OpenDev($hash,$self->{reopen},undef);
|
||||||
|
return undef unless $hash->{STATE} eq "opened";
|
||||||
|
|
||||||
my $hwdevice = $hash->{USBDev};
|
my $hwdevice = $hash->{USBDev};
|
||||||
if(!defined($hwdevice)){
|
|
||||||
die $msg." not defined: $!";
|
|
||||||
} else {
|
|
||||||
main::Log3($hash->{NAME},2,$msg." defined");
|
|
||||||
}
|
|
||||||
|
|
||||||
$hwdevice->reset_error();
|
|
||||||
$hwdevice->baudrate(9600);
|
|
||||||
$hwdevice->databits(8);
|
|
||||||
$hwdevice->parity('none');
|
|
||||||
$hwdevice->stopbits(1);
|
|
||||||
$hwdevice->handshake('none');
|
|
||||||
$hwdevice->write_settings;
|
|
||||||
#-- store with OWX device
|
|
||||||
$self->{hwdevice} = $hwdevice;
|
|
||||||
|
|
||||||
#force master reset in DS2480
|
#force master reset in DS2480
|
||||||
|
$hwdevice->reset_error();
|
||||||
$hwdevice->purge_all;
|
$hwdevice->purge_all;
|
||||||
$hwdevice->baudrate(4800);
|
$hwdevice->baudrate(4800);
|
||||||
$hwdevice->write_settings;
|
$hwdevice->write_settings;
|
||||||
@ -306,12 +298,11 @@ sub initialize($) {
|
|||||||
|
|
||||||
#-- timing byte for DS2480
|
#-- timing byte for DS2480
|
||||||
$ds2480->start_query();
|
$ds2480->start_query();
|
||||||
|
$hwdevice->baudrate(9600);
|
||||||
|
$hwdevice->write_settings;
|
||||||
$ds2480->query("\xC1",1);
|
$ds2480->query("\xC1",1);
|
||||||
eval { #ignore timeout
|
$hwdevice->baudrate($self->{baud});
|
||||||
do {
|
$hwdevice->write_settings;
|
||||||
$ds2480->read();
|
|
||||||
} while (!$ds2480->response_ready());
|
|
||||||
};
|
|
||||||
|
|
||||||
#-- Max 4 tries to detect an interface
|
#-- Max 4 tries to detect an interface
|
||||||
for($l=0;$l<100;$l++) {
|
for($l=0;$l<100;$l++) {
|
||||||
@ -377,11 +368,11 @@ sub initialize($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Disconnect($) {
|
sub exit($) {
|
||||||
my ($self,$hash) = @_;
|
my ($self) = @_;
|
||||||
main::DevIo_Disconnected($hash);
|
main::DevIo_Disconnected($self->{hash});
|
||||||
delete $self->{hwdevice};
|
|
||||||
$self->{interface} = "serial";
|
$self->{interface} = "serial";
|
||||||
|
$self->{reopen} = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
Loading…
x
Reference in New Issue
Block a user