File Coverage

blib/lib/Device/Kiln.pm
Criterion Covered Total %
statement 41 163 25.1
branch 1 18 5.5
condition 1 15 6.6
subroutine 9 16 56.2
pod 1 8 12.5
total 53 220 24.0


line stmt bran cond sub pod time code
1             package Device::Kiln;
2              
3 1     1   47124 use Device::DSE::Q1573;
  1         42107  
  1         53  
4 1     1   1063 use Device::Kiln::Orton;
  1         17574  
  1         43  
5 1     1   2452 use SVG::TT::Graph::TimeSeries;
  1         313337  
  1         44  
6 1     1   13 use HTTP::Date qw(time2iso str2time);
  1         2  
  1         76  
7              
8              
9 1     1   6 use strict;
  1         1  
  1         43  
10              
11             BEGIN {
12 1     1   5 require Device::DSE::Q1573;
13 1     1   6 use Exporter ();
  1         2  
  1         19  
14 1     1   5 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         1  
  1         106  
15 1         3 $VERSION = '0.03';
16 1         17 @ISA = qw(Exporter);
17 1         2 @EXPORT = qw();
18 1         2 @EXPORT_OK = qw();
19 1         2059 %EXPORT_TAGS = ();
20              
21             }
22              
23             sub new {
24            
25 1     1 1 14 my $class = shift;
26 1         4 my %config = %{$_[0]};
  1         47  
27            
28              
29              
30 1   33     18 my $self = bless( {}, ref($class) || $class );
31            
32            
33 1 50       5 if( defined $config{'serialport'} ) {
34 0         0 $self->{meter} = Device::DSE::Q1573->new($config{serialport});
35 0         0 $self->{serialport} = $config{serialport};
36             }
37            
38              
39 1         15 $self->{width} = $config{'width'};
40 1         3 $self->{height} = $config{'height'};
41 1         5 $self->{interval} = $config{'interval'};
42 1         3 $self->{rampuprate} = 150;
43 1         4 $self->{tid} = undef;
44 1         5 $self->{datafile} = '/tmp/q1573.tmp';
45 1         29 $self->{cones} = {
46             '1 - 018' => {
47             60 => 712,
48             100 => 722,
49             150 => 732
50             },
51            
52             '2 - 017' => {
53             60 => 736,
54             100 => 748,
55             150 => 761
56             },
57            
58             '3 - 016' => {
59             60 => 769,
60             100 => 782,
61             150 => 794
62             },
63            
64             };
65            
66 1         6 $self->{maxtemp} = [""];
67 1         6 return $self;
68             }
69              
70             sub run {
71              
72              
73 0     0 0   my $self = shift;
74              
75 0           print $self->{file} . "\n";
76 0           my $time = 0;
77 0           my $count = 0;
78              
79 0           my $fh;
80              
81 0           open( $fh, ">>", $self->{datafile} );
82 0           $fh->autoflush(1);
83              
84 0           sleep 1;
85              
86 0           while (1) {
87            
88 0           my $time = time();
89 0           my $raw = $self->{meter}->rawread();
90             #print $raw. "\n";
91 0           $self->{setting} = substr( $raw, 0, 2 );
92 0           $self->{value} = substr( $raw, 2, 7 ) + 0;
93 0           $self->{units} = substr( $raw, 11, 1 );
94              
95 0           $self->{value} =~ s/ //g;
96              
97             #print $self->{value} . " ";
98 0           print time2iso() . "\n";
99              
100 0           print $fh time2iso() . "|" . $self->{value} . "\n";
101            
102            
103 0           while( time() < ($self->{interval} + $time) ){sleep 1;};
  0            
104 0           print time() . " : $time\n";
105            
106              
107             }
108              
109             }
110              
111             sub graph {
112              
113 0     0 0   my $self = shift;
114 0           my $config = shift;
115            
116 0           my @data;
117             my @ideal;
118 0           my $fh;
119 0           my ($startperiod, $startvalue);
120            
121            
122 0           $config->{conemax} = Device::Kiln::Orton->hashref()->{$config->{cone}}->{$config->{conerate}};
123             #$config->{conemax} = $self->{cones}->{$config->{cone}}->{$config->{conerate}};
124            
125              
126             #@data = ( [ time2iso(), $self->{value} ] );
127            
128 0           open( $fh, "<", $self->{datafile} );
129 0           my $count = 0;
130 0           while(<$fh>) {
131              
132              
133 0           chomp;
134 0           push @data, [split /\|/, $_];
135            
136            
137 0 0         if($count == 0 ) {
138 0           $startperiod = $data[0][0];
139 0           $startvalue = $data[0][1];
140 0           $count++;
141             }
142            
143            
144             }
145              
146 0           debug("-------------------------");
147            
148 0           debug("Warmupramp :" . $config->{warmupramp});
149 0           debug("Warmuptemp :" . $config->{warmuptemp});
150 0           debug("Warmuptime :" . $config->{warmuptime});
151 0           debug("Fireuprate :" . $config->{fireuprate});
152 0           debug("Conerate :" . $config->{conerate});
153 0           debug("Cone :" . $config->{cone});
154 0           debug("Cone Max :" . $config->{conemax});
155            
156            
157            
158 0           my $endperiod = @{@data[@data-1]}[0];
  0            
159 0           my $duration = str2time($endperiod) - str2time($startperiod);
160            
161 0           my $value=$startvalue;
162              
163 0           debug("Duration " . $duration);
164            
165 0           push @ideal, [$startperiod,$value];
166 0           debug( "Data : " . $ideal[@ideal-1][0] . ", " . $ideal[@ideal-1][1]);
167            
168              
169            
170 0           push @ideal, warmupramp($startvalue,$startperiod,$endperiod,$config);
171              
172            
173             # Warm Up Time
174 0           my $warmupsecs = $config->{warmuptime} * 60;
175            
176 0 0 0       if($duration > $config->{used} || $config->{fullgraph} == 0) {
177            
178 0           push @ideal, warmuptime($startvalue,$startperiod,$endperiod,$config);
179            
180             # Fire up to Pre Cone Fire
181 0 0 0       if( $duration > $config->{warmupramptime} + $warmupsecs && $config->{fullgraph} == 0) {
182 0           push @ideal, fireuptime($startvalue,$startperiod,$endperiod,$config);
183            
184 0 0         if($duration > $config->{fireuptime}) {
185 0           push @ideal, conefire($startvalue,$startperiod,$endperiod,$config);
186             }
187             }
188            
189             }
190            
191            
192            
193 0           my $graph = SVG::TT::Graph::TimeSeries->new(
194             {
195              
196             # Optional - defaults shown
197             'height' => 600,
198             'width' => 1024,
199              
200             'x_label_format' => '%H:%M:%S',
201             'area_fill' => 1,
202              
203             'max_time_span' => 0,
204             'timescale_divisions' => '15 minutes',
205              
206             'rollover_values' => 1,
207             'show_data_points' => 1,
208             'show_data_values' => 1,
209              
210             # Stylesheet defaults
211             'style_sheet' => '/graph.css', # internal stylesheet
212             'random_colors' => 0,
213             'compress' => 0,
214             'key' => 1,
215            
216             }
217             );
218              
219 0           $graph->add_data(
220             {
221             'data' => \@data,
222             'title' => 'Temperature',
223             }
224             );
225            
226 0           $graph->add_data(
227             {
228             'data' => \@ideal,
229             'title' => 'Ideal',
230             }
231             );
232            
233            
234 0           debug("-------------------------");
235              
236            
237 0           return $graph->burn();
238            
239              
240             }
241              
242              
243             sub warmupramp {
244              
245 0     0 0   my ($startvalue,$startperiod,$endperiod,$config) = @_;
246            
247 0           my @ideal;
248 0           my $duration = str2time($endperiod) - str2time($startperiod);
249            
250             #
251             # Warmup Ramp
252             #
253 0           debug( "-----> warmupramp ");
254 0           $config->{warmupramptime} = ($config->{warmuptemp}-$startvalue)/($config->{warmupramp})*60*60;
255            
256            
257 0 0 0       if($duration <= $config->{warmupramptime} && $config->{fullgraph} == 0) {
258 0           my $value = ($duration/3600) * $config->{warmupramp} + $startvalue;
259 0           push @ideal, [$endperiod,$value];
260 0           debug( "Data : " . $ideal[@ideal-1][0] . ", " . $ideal[@ideal-1][1]);
261 0           $config->{used} = $duration;
262            
263             } else {
264 0           push @ideal, [time2iso($config->{warmupramptime}+str2time($startperiod)),$config->{warmuptemp}];
265 0           $config->{used} = $config->{warmupramptime};
266 0           debug( "Data : " . $ideal[@ideal-1][0] . ", " . $ideal[@ideal-1][1]);
267            
268             }
269 0           return @ideal;
270             }
271              
272             sub warmuptime {
273            
274 0     0 0   my ($startvalue,$startperiod,$endperiod,$config) = @_;
275 0           my $warmupsecs = $config->{warmuptime} * 60;
276 0           my $duration = str2time($endperiod) - str2time($startperiod);
277 0           my @ideal;
278            
279 0 0 0       if( $duration < $config->{used} + $warmupsecs && $config->{fullgraph} == 0) {
280            
281 0           push @ideal, [$endperiod,$config->{warmuptemp}];
282 0           $config->{used} = $duration;
283            
284             } else {
285              
286 0           push @ideal, [time2iso($config->{warmupramptime}+str2time($startperiod)+ $warmupsecs),$config->{warmuptemp}];
287 0           $config->{used} = $config->{used} + $warmupsecs;
288            
289             }
290              
291 0           debug( "Data : " . $ideal[@ideal-1][0] . ", " . $ideal[@ideal-1][1]);
292 0           return @ideal;
293            
294             }
295              
296              
297              
298             sub fireuptime {
299            
300 0     0 0   my ($startvalue,$startperiod,$endperiod,$config) = @_;
301 0           my $duration = str2time($endperiod) - str2time($startperiod);
302            
303 0           my @ideal;
304            
305 0           my $endtemp = $config->{conemax} - 100;
306 0           my $risetemp = $endtemp - $config->{warmuptemp};
307            
308            
309 0           my $endfireuptime = $config->{used} + ($risetemp / $config->{fireuprate}) * 3600;
310            
311            
312 0 0         if($duration < $endfireuptime ) {
313 0           my $leftover = $duration - $config->{used};
314 0           my $value = $leftover * ($config->{fireuprate} / 3600) + $config->{warmuptemp};
315 0           push @ideal, [$endperiod, $value];
316 0           $config->{used} = $duration;
317            
318             } else {
319            
320            
321 0           push @ideal, [time2iso($endfireuptime + str2time($startperiod)),$endtemp];
322 0           $config->{used} = $endfireuptime;
323 0           $config->{fireuptemp} = $endtemp;
324             }
325            
326            
327 0           debug( "Data : " . $ideal[@ideal-1][0] . ", " . $ideal[@ideal-1][1]);
328 0           return @ideal;
329            
330             }
331              
332              
333             sub conefire {
334            
335 0     0 0   my ($startvalue,$startperiod,$endperiod,$config) = @_;
336 0           my $duration = str2time($endperiod) - str2time($startperiod);
337 0           my @ideal;
338 0           my $fullconetime = 100 / $config->{conerate} * 3600;
339            
340 0 0         if( $duration < $config->{used} + $fullconetime ) {
341            
342 0           push @ideal, [$endperiod, $config->{fireuptemp} + 100 * (($duration-$config->{used})/$fullconetime) ];
343 0           $config->{used} = $duration;
344            
345             } else {
346            
347            
348 0           push @ideal, [time2iso($config->{used} + 3600 + str2time($startperiod)), $config->{conemax}];
349 0           $config->{used} += $fullconetime;
350 0           debug("in");
351             }
352            
353 0           debug( "Data : " . $ideal[@ideal-1][0] . ", " . $ideal[@ideal-1][1]);
354 0           return @ideal;
355            
356             }
357              
358             sub debug {
359            
360 0     0 0   my $msg = shift;
361            
362 0           open( my $dfh, ">>", "/tmp/kilnserver.dbg");
363 0           print $dfh (scalar localtime) . " : " . $msg . "\n";
364 0           close($dfh);
365            
366             }
367              
368             =head1 NAME
369              
370             Device::Kiln - Graph kiln firing use Data logged from Device::DSE::Q1573
371              
372             =head1 SYNOPSIS
373              
374             use Device::Kiln;
375             my $meter = Device::Kiln->new("/dev/ttyS0");
376            
377              
378              
379             =head1 DESCRIPTION
380              
381             Sets up a connection to a DSE Q1573 or Metex ME-22
382             Digital Multimeter, and allows then plots data to a png file
383             at regular intervals.
384             =head1 USAGE
385              
386             =head2 new(serialport)
387              
388             Usage : my $meter=Device::Kiln->new("/dev/ttyS0")
389             Purpose : Opens the meter on the specified serial port
390             Returns : object of type Device::Kiln
391             Argument : serial port
392            
393             =head2 rawread();
394              
395             Usage : my $meter->rawread()
396             Purpose : Returns the raw 14 byte string from the meter.
397            
398             =head1 EXAMPLE
399              
400             use Device::DSE::Q1573;
401              
402             my $meter = Device::Kiln->new( "/dev/ttyS0" );
403              
404             while(1) {
405             my $data = $meter->read();
406             print $data . "\n";
407             sleep(1);
408             }
409              
410              
411             =head1 AUTHOR
412              
413             David Peters
414             CPAN ID: DAVIDP
415             davidp@electronf.com
416             http://www.electronf.com
417              
418             =head1 COPYRIGHT
419              
420             This program is free software; you can redistribute
421             it and/or modify it under the same terms as Perl itself.
422              
423             The full text of the license can be found in the
424             LICENSE file included with this module.
425              
426              
427             =head1 SEE ALSO
428              
429             perl(1).
430              
431             =cut
432              
433             #################### main pod documentation end ###################
434              
435             1;