File Coverage

blib/lib/Device/Conrad/RelaisControl.pm
Criterion Covered Total %
statement 32 114 28.0
branch 0 26 0.0
condition 0 5 0.0
subroutine 11 21 52.3
pod 0 9 0.0
total 43 175 24.5


line stmt bran cond sub pod time code
1             package Device::Conrad::RelaisControl;
2              
3             ###
4             # $Revision: 1.3 $
5             # $Date: 2002/02/16 15:27:32 $
6             # $Author: ruediger $
7             ###
8              
9 1     1   19080 use 5.006;
  1         3  
  1         40  
10 1     1   6 use strict;
  1         3  
  1         33  
11 1     1   4 use warnings;
  1         6  
  1         65  
12              
13             require Exporter;
14 1     1   944 use AutoLoader qw(AUTOLOAD);
  1         2146  
  1         6  
15              
16             our @ISA = qw(Exporter);
17              
18             # Items to export into callers namespace by default. Note: do not export
19             # names by default without a very good reason. Use EXPORT_OK instead.
20             # Do not simply export all your public functions/methods/constants.
21              
22             # This allows declaration use Device::Conrad::RelaisControl ':all';
23             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
24             # will save memory.
25             our %EXPORT_TAGS = ( 'all' => [ qw(
26            
27             ) ] );
28              
29             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
30              
31             our @EXPORT = qw(
32            
33             );
34             our $VERSION = '0.12';
35              
36              
37             # Preloaded methods go here.
38              
39 1     1   1437 use Device::SerialPort qw(:PARAM :STAT 0.07);
  1         61025  
  1         430  
40 1     1   741 use Device::Conrad::Frame;
  1         3  
  1         31  
41 1     1   580 use Device::Conrad::RelaisCard;
  1         3  
  1         27  
42 1     1   6 use Carp;
  1         2  
  1         59  
43 1     1   5 use strict;
  1         3  
  1         29  
44              
45 1     1   5 use vars qw ($VERSION);
  1         1  
  1         1499  
46              
47             my $VERBOSE = 0;
48             my $CONSTREAD = 200;
49             my $CHARREAD = 10;
50             my $LOCKFILE = "/tmp/relaiscard.lock";
51              
52             sub new
53             {
54 0     0 0   my $proto = shift;
55 0   0       my $class = ref($proto) || $proto;
56 0           my $self = {};
57              
58 0           my $portName = shift;
59 0           $self->{'_portName'} = $portName;
60             #$self->{'_lockFile'} = "/tmp/relaiscard.lock";
61 0           $self->{'_cards'} = [];
62              
63 0   0       my $port = new Device::SerialPort ($portName, 0, $LOCKFILE)
64             || die "Can't open: $!\n";
65              
66 0 0         print "open device: $portName\n" if $VERBOSE;
67 0           $port->devicetype('none');
68              
69 0 0         print "setting device params: 19200 8n1 no handshake\n" if $VERBOSE;
70 0           $port->baudrate(19200);
71 0           $port->parity("none");
72 0           $port->databits(8);
73 0           $port->stopbits(1);
74 0           $port->handshake("none");
75              
76 0 0         print "setting timings: constant reading = 500, char read = 50\n" if $VERBOSE;
77 0           $port->read_const_time($CONSTREAD);
78 0           $port->read_char_time($CHARREAD);
79 0           $self->{'_timeout'} = ($CONSTREAD + (4 * $CHARREAD))/1000;
80              
81 0           $port->write_settings;
82 0 0         $port->debug(1) if $VERBOSE;
83              
84 0           $self->{'_port'} = $port;
85 0           bless ($self, $class);
86 0           return $self;
87             }
88              
89             sub init
90             {
91 0     0 0   my($self) = shift;
92 0           my $setupFrame;
93              
94 0           undef $self->{'_cards'};
95 0 0         print "initialize control\n" if $VERBOSE;
96              
97 0           my $setup = new Device::Conrad::Frame(Device::Conrad::RelaisCard::CMD_SETUP, 1, 0);
98 0 0         unless($setupFrame = $self->sendFrame($setup))
99             {
100 0           carp "initialize failed\n";
101             }
102 0           my $nFrame;
103 0           while(($nFrame = $self->readFrame())->command() != 0)
104             {
105 0           push @{$self->{'_cards'}}, new Device::Conrad::RelaisCard($setupFrame->address(), $self);
  0            
106 0           select(undef,undef,undef,0.50);
107 0           $setupFrame = $nFrame;
108             }
109 0 0         print @{$self->{'_cards'}}+0," cards detected\n" if $VERBOSE;
  0            
110              
111 0           my $card;
112 0           foreach $card (@{$self->{'_cards'}})
  0            
113             {
114 0           $card->init();
115             }
116             }
117              
118             sub getNumCards
119             {
120 0     0 0   my($self) = @_;
121              
122 0           return @{$self->{'_cards'}}+0;
  0            
123             }
124              
125             sub getCard
126             {
127 0     0 0   my($self, $num) = @_;
128            
129 0 0         if($num > $#{$self->{'_cards'}})
  0            
130             {
131 0           die "$num exceeds number of cards";
132             }
133 0           return $self->{'_cards'}->[$num];
134             }
135            
136             sub current
137             {
138 0     0 0   my($self) = shift;
139              
140 0 0         if(@_)
141             {
142 0           $self->{'_current'} = $self->getCard(shift);
143             }
144 0           return $self->{'_current'};
145             }
146              
147             sub close
148             {
149 0     0 0   my($self, $cardNum, $port) = @_;
150              
151 0           my $card = $self->getCard($cardNum);
152 0           $card->close($port);
153             }
154              
155             sub open
156             {
157 0     0 0   my($self, $cardNum, $port) = @_;
158              
159 0           my $card = $self->getCard($cardNum);
160 0           $card->open($port);
161             }
162              
163             sub sendFrame
164             {
165 0     0 0   my($self, $frameOut) = @_;
166              
167 0 0         print "sending packet: ".$frameOut->toString()."\n" if $VERBOSE;
168 0           my $crcFrame = $frameOut->createCRCFrame();
169            
170 0           $self->{'_port'}->write($frameOut->toPacket());
171 0           select(undef, undef, undef, 0.1);
172              
173 0           my $frameIn = $self->readFrame();
174 0 0         print "received packet: ".$frameIn->toString()."\n" if $VERBOSE;
175              
176 0 0         unless($frameIn->equals($crcFrame))
177             {
178 0           my $stopFrame = new Device::Conrad::Frame(3,1,0);
179 0           $self->{'_port'}->write($stopFrame->toPacket());
180 0           carp "controller response is incorrect. \n sent ".$frameOut->toString."\n got ".$frameIn->toString()."\n should be ".$crcFrame->toString()."\n";
181 0           return new Device::Conrad::Frame(0,0,0);
182             }
183              
184 0           return $frameIn;
185             }
186            
187             sub readFrame
188             {
189 0     0 0   my($self) = shift;
190              
191 0           my ($bytesIn, $packetIn) = $self->{'_port'}->read(Device::Conrad::Frame::FRAMESIZE);
192              
193 0 0         unless($bytesIn == Device::Conrad::Frame::FRAMESIZE)
194             {
195 0           return new Device::Conrad::Frame(0,0,0);
196             }
197              
198 0           my $frameIn = Device::Conrad::Frame::createFromPacket($packetIn);
199              
200 0           return $frameIn;
201             }
202              
203             sub DESTROY
204             {
205 0     0     my($self) =shift;
206 0           unlink $LOCKFILE;
207             }
208              
209             sub END
210             {
211 1     1   209 my($self) =shift;
212 1         30 unlink $LOCKFILE;
213             }
214             1;
215             # Autoload methods go after =cut, and are processed by the autosplit program.
216              
217             1;
218             __END__