From da98a8624b65b82251e4cc941a546336bcab7a96 Mon Sep 17 00:00:00 2001 From: ntruchsess <> Date: Mon, 21 Jul 2014 21:02:28 +0000 Subject: [PATCH] OWX_SER: add support for network-attached serial git-svn-id: https://svn.fhem.de/fhem/trunk@6292 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/00_OWX_ASYNC.pm | 8 ++--- fhem/FHEM/OWX_DS2480.pm | 30 +++++++++---------- fhem/FHEM/OWX_SER.pm | 63 ++++++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 44 deletions(-) diff --git a/fhem/FHEM/00_OWX_ASYNC.pm b/fhem/FHEM/00_OWX_ASYNC.pm index bb355349f..08bb642a2 100644 --- a/fhem/FHEM/00_OWX_ASYNC.pm +++ b/fhem/FHEM/00_OWX_ASYNC.pm @@ -129,7 +129,7 @@ my %attrs = ( #-- some globals needed for the 1-Wire module $owx_async_version=5.8; #-- Debugging 0,1,2,3 -$owx_async_debug=0; +$owx_async_debug=3; ######################################################################################## # @@ -191,10 +191,10 @@ sub OWX_ASYNC_Define ($$) { my $owx; #-- First step - different methods #-- check if we have a serial device attached - if ( $dev =~ m|$SER_regexp|i){ + if ( $dev =~ m|$SER_regexp|i or $dev =~ m/^(.+):([0-9]+)$/ ){ require "$main::attr{global}{modpath}/FHEM/OWX_SER.pm"; $owx = OWX_SER->new(); - #-- check if we have a COC/CUNO interface attached + #-- check if we have a COC/CUNO interface attached }elsif( (defined $main::defs{$dev} && (defined( $main::defs{$dev}->{VERSION} ) ? $main::defs{$dev}->{VERSION} : "") =~ m/CSM|CUNO/ )){ require "$main::attr{global}{modpath}/FHEM/OWX_CCC.pm"; $owx = OWX_CCC->new(); @@ -207,7 +207,7 @@ sub OWX_ASYNC_Define ($$) { }; my $ret = $owx->Define($hash,$def); - #-- cancel definition of OWX if interface define fails + #-- cancel definition of OWX if interface define fails return $ret if $ret; $hash->{OWX} = $owx; diff --git a/fhem/FHEM/OWX_DS2480.pm b/fhem/FHEM/OWX_DS2480.pm index 34acea8b0..a9bed588e 100644 --- a/fhem/FHEM/OWX_DS2480.pm +++ b/fhem/FHEM/OWX_DS2480.pm @@ -104,26 +104,24 @@ sub query ($$$) { sub read() { my ($serial) = @_; - #-- read the data my $string_part = main::DevIo_DoSimpleRead($serial->{hash}); - return undef unless defined $string_part; - my $count_in = length ($string_part); - $serial->{string_in} .= $string_part; - $serial->{retcount} += $count_in; $serial->{num_reads}++; - if( $main::owx_async_debug > 1 ) { - if ($count_in>0) { - main::Log3($serial->{name},5, "OWX_DS2480 read: Loop no. $serial->{num_reads}, Receiving: ".unpack("H*",$string_part)); - } elsif ($main::owx_async_debug > 2) { - main::Log3($serial->{name},5, "OWX_DS2480 read: Loop no. $serial->{num_reads}, no data read:"); - foreach my $i (0..6) { - my ($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash) = caller($i); - main::Log3($serial->{name},5, "$subroutine $filename $line"); - } + #return undef unless defined $string_part; + if (defined $string_part) { + my $count_in = length ($string_part); + $serial->{string_in} .= $string_part; + $serial->{retcount} += $count_in; + main::Log3($serial->{name},5, "OWX_DS2480 read: Loop no. $serial->{num_reads}, Receiving: ".unpack("H*",$string_part)) if( $main::owx_async_debug > 1 ); + return $count_in > 0 ? 1 : undef; + } elsif ($main::owx_async_debug > 2) { + main::Log3($serial->{name},5, "OWX_DS2480 read: Loop no. $serial->{num_reads}, no data read:"); + foreach my $i (0..6) { + my ($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash) = caller($i); + main::Log3($serial->{name},5, "$subroutine $filename $line"); } } - return $count_in > 0 ? 1 : undef; + return undef; } sub response_ready() { @@ -142,7 +140,7 @@ sub response_ready() { sub start_query() { my ($serial) = @_; #read and discard any outstanding data from previous commands: - while($serial->read()) {}; + while($serial->poll()) {}; $serial->{string_in} = ""; $serial->{num_reads} = 0; diff --git a/fhem/FHEM/OWX_SER.pm b/fhem/FHEM/OWX_SER.pm index 91044e46b..aa4b72025 100644 --- a/fhem/FHEM/OWX_SER.pm +++ b/fhem/FHEM/OWX_SER.pm @@ -71,9 +71,14 @@ sub poll($) { select($rout=$rin, undef, undef, 0.1); my $mfound = vec($rout, $hash->{FD}, 1); if ($mfound) { - main::OWX_ASYNC_Disconnect($hash) unless $self->read(); + if ($self->read()) { + return 1; + } else { + main::OWX_ASYNC_Disconnect($hash); + } } } + return undef; } ######################################################################################## @@ -102,17 +107,23 @@ sub Define ($$) { } my $dev = $a[2]; - #-- when the specified device name contains @ already, use it as supplied - if ( $dev !~ m/\@\d*/ ){ - $hash->{DeviceName} = $dev."\@9600"; + my $device; + #-- network attached serial: + if ( $dev =~ m/^(.+):([0-9]+)$/ ) { + $hash->{DeviceName} = $dev; + $device = $dev; + } else { + #-- when the specified device name contains @ already, use it as supplied + if ( $dev !~ m/\@\d*/ ){ + $hash->{DeviceName} = $dev."\@9600"; + } + my $baudrate; + ($device,$baudrate) = split('@',$dev); + $self->{baud} = $baudrate ? $baudrate : 9600; } - my ($device,$baudrate) = split('@',$dev); #-- let fhem.pl MAIN call OWX_Ready when setup is done. $main::readyfnlist{"$hash->{NAME}.$device"} = $hash; - - $self->{baud} = $baudrate ? $baudrate : 9600; $self->{hash} = $hash; - return undef; } @@ -277,15 +288,6 @@ sub initialize() { main::DevIo_OpenDev($hash,$self->{reopen},undef); return undef unless $hash->{STATE} eq "opened"; - my $hwdevice = $hash->{USBDev}; - #force master reset in DS2480 - $hwdevice->reset_error(); - $hwdevice->purge_all; - $hwdevice->baudrate(4800); - $hwdevice->write_settings; - $hwdevice->write(sprintf("\x00")); - select(undef,undef,undef,0.5); - #-- Third step detect busmaster on serial interface my $name = $self->{name}; @@ -297,13 +299,26 @@ sub initialize() { require "$main::attr{global}{modpath}/FHEM/OWX_DS2480.pm"; my $ds2480 = OWX_DS2480->new($self); - #-- timing byte for DS2480 - $ds2480->start_query(); - $hwdevice->baudrate(9600); - $hwdevice->write_settings; - $ds2480->query("\xC1",1); - $hwdevice->baudrate($self->{baud}); - $hwdevice->write_settings; + if (defined (my $hwdevice = $hash->{USBDev})) { + #force master reset in DS2480 + $hwdevice->reset_error(); + $hwdevice->purge_all; + $hwdevice->baudrate(4800); + $hwdevice->write_settings; + $hwdevice->write(sprintf("\x00")); + select(undef,undef,undef,0.5); + #-- timing byte for DS2480 + $ds2480->start_query(); + $hwdevice->baudrate(9600); + $hwdevice->write_settings; + $ds2480->query("\xC1",0); + $hwdevice->baudrate($self->{baud}); + $hwdevice->write_settings; + } else { + #-- for serial over network we cannot reset but just send the timing byte + $ds2480->start_query(); + $ds2480->query("\xC1",0); + } #-- Max 4 tries to detect an interface for($l=0;$l<100;$l++) {