Send wind even if it hasn't changed
[dweather.git] / b.pl
1 #!/usr/bin/perl
2
3 use DBI;
4 use strict;
5 use Device::SerialPort;
6 use Time::HiRes;
7
8 my $devname = "/dev/davis";
9 my $dbsort = "SQLite";
10 my $db="weather.db";
11 my $host="";
12 my $userid="";
13 my $passwd="";
14 my $connectionInfo="dbi:$dbsort:$db";
15 $connectionInfo .= ":$host" if $host;
16
17 # make connection to database
18 my %attr = ( PrintError => 0, RaiseError => 0 );
19 my $dbh = DBI->connect($connectionInfo,$userid,$passwd,\%attr) or die "Couldn't connect to database: " . DBI->errstr;
20
21
22 my ($count, $result);
23 my %hsh;
24 my @crc_table=();
25 my %bar_trend=();
26 load_crc_table();
27
28 my $ob = Device::SerialPort->new ($devname) || die;
29
30 $ob->user_msg(1);                               # misc. warnings
31 $ob->error_msg(1);                              # hardware and data errors
32
33 $ob->baudrate(19200);
34 $ob->parity("none");
35 #$ob->parity_enable(1);         # for any parity except "none"
36 $ob->databits(8);
37 $ob->stopbits(1);
38 $ob->handshake('none');
39 $ob->read_const_time(15000);    # ultimate timeout (15 seconds)
40 $ob->write_settings||die"setting failed";
41
42
43 my $awake=0;
44 my $attempts=0;
45 $ob->write("\n");                               # initial wake
46
47 while ($awake==0) {
48         $ob->write("\n");                                  # wake for real
49         $ob->read_interval(600);                   # wait for a max of 600ms
50         ($count, $result) = $ob->read(10); # read up to 10 chars
51         if ($result eq "\n\r") {
52                 print "awoke on attempt $attempts :)\n";
53                 $awake=1;
54         } else {
55                 print "wake error on attempt $attempts :(\n";
56         }
57         $attempts++;
58         dienice("failed to wake device - tried $attempts times") unless $attempts<6;
59 }
60
61 $ob->write("LAMPS 0\n");
62 $ob->read_interval(300);                  # wait for a max of 300ms
63 ($count, $result) = $ob->read(8); # read up to 8 chars
64 $result=~s/(\r|\n)//g;
65 if ($result eq "OK") {
66         print "lamps on :)\n";
67 } else {
68         dienice("lamp error '$result'");
69 }
70
71
72
73 my $ref=gettime();
74 $ref->[5]+=1900;
75 print "$ref->[2]:$ref->[1]:$ref->[0] $ref->[3]/$ref->[4]/$ref->[5]\n";
76
77 #settime();
78
79 #do_dmpaft();
80
81 while (1) {
82         get_loop();     # if you do anything after here - you need to wake up the device again
83         print "** do something else\n";
84         sleep 5;
85         $ob->write("\r");                                               #  wake
86         $ob->read_interval(500);                                # wait for a max of 300ms
87         my ($count, $result) = $ob->read(4096); # read any crap up to 4096 chars
88 }
89
90 #print "count=$count $result\n";
91 #for(my $i=0; $i<$count; $i++)
92 #{ printf("%02d ",ord(substr($result,$i,1))); }
93
94 #$ob->write("WRD\x12\x4d\n");
95
96 undef $ob;
97 exit 0;
98
99 sub dienice
100 {
101         my $err=shift;
102         print "$err\n";
103         undef $ob;
104         exit 9;
105 }
106
107 sub parse_loop_blck
108 {
109         my $blk = shift;
110         my $loo =  substr $blk,0,3;
111         unless ( $loo eq 'LOO') {
112                 warn("Block invalid loo -> $loo\n"); return "";
113         }
114         my $t;
115
116         #$hsh{'next_rec'}     = unpack("s", substr $blk,5,2);
117
118         $hsh{'Barometric_Trend'}    = unpack("C", substr $blk,3,1);
119         $hsh{'Barometric_Trend_txt'} = $bar_trend{$hsh{'Barometric_Trend'}};
120         $t = unpack("s", substr $blk,7,2) / 1000;
121         #       $hsh{'Barometric_Press_hg'}          = $t;
122         $hsh{'Barometric_Press_mb'} = sprintf("%.2f",$t*33.8637526);
123
124
125         $t = unpack("s", substr $blk,9,2) / 10;
126         #       $hsh{'Air_Temp_Inside_f'}      = $t;
127         $hsh{'Air_Temp_Inside_c'} = sprintf("%.1f",($t - 32) * 5/9);
128         my $tf  = unpack("s", substr $blk,12,2) / 10;
129         #       $hsh{'Air_Temp_Outside_f'}     = $tf;
130         $hsh{'Air_Temp_Outside_c'}  = sprintf("%.1f",($tf - 32) * 5/9);
131
132         $hsh{'Wind_Speed_mph'}   = unpack("C", substr $blk,14,1);
133         #       $hsh{'Wind_Speed_mps'} = sprintf("%.1f",$hsh{'Wind_Speed_mph'}*0.44704);
134         $hsh{'Wind_Speed_10min_Avg_mph'} = unpack("C", substr $blk,15,1);
135         #       $hsh{'Wind_Speed_10min_Avg_mps'} = sprintf("%.1f",$hsh{'Wind_Speed_10min_Avg_mph'}*0.44704);
136         $hsh{'Wind_Dir'}     = unpack("s", substr $blk,16,2);
137
138
139         $hsh{'Humidity_Outside'} = unpack("C", substr $blk,33,1);
140         $hsh{'Humidity_Inside'}  = unpack("C", substr $blk,11,1);
141         $hsh{'Dew_Point'}  = dew_point($tf, $hsh{'Humidity_Outside'});
142
143         #       $hsh{'UV'}         = unpack("C", substr $blk,43,1);
144         #       $hsh{'Solar'}  = unpack("s", substr $blk,44,2); # watt/m**2
145
146         $hsh{'Rain_Rate'}  = (unpack("s", substr $blk,41,2) / 100) * 25.4; # Inches per hr converted to mm
147         $hsh{'Rain_Storm'} = (unpack("s", substr $blk,46,2) / 100) * 25.4; # Inches per storm
148         #$hsh{'Storm_Date'} = unpack("s", substr $blk,48,2);  # Need to parse data (not sure what this is)
149         $hsh{'Rain_Day'}   = (unpack("s", substr $blk,50,2)/100) * 25.4;
150         $hsh{'Rain_Month'}  = (unpack("s", substr $blk,52,2)/100) * 25.4;
151         $hsh{'Rain_Year'}  = (unpack("s", substr $blk,54,2)/100) * 25.4;
152
153         $hsh{'ET_Day'}   = unpack("s", substr $blk,56,2)/1000;
154         $hsh{'ET_Month'}  = unpack("s", substr $blk,58,2)/100;
155         $hsh{'ET_Year'}  = unpack("s", substr $blk,60,2)/100;
156
157         #$hsh{'Alarms_Inside'}  = unpack("b8", substr $blk,70,1);
158         #$hsh{'Alarms_Rain'}  = unpack("b8", substr $blk,70,1);
159         #$hsh{'Alarms_Outside'}  = unpack("b8", substr $blk,70,1);
160
161         $hsh{'Batt_Transmitter'}  = unpack("C", substr $blk,86,1); #  * 0.005859375
162         $hsh{'Batt_Console'}  = unpack("s", substr $blk,87,2) * 0.005859375;
163
164         $hsh{'Forecast_Icon'}  = unpack("C", substr $blk,89,1);
165         $hsh{'Forecast_Rule'}  = unpack("C", substr $blk,90,1);
166
167         $hsh{'Sunrise'}  = sprintf( "%04d", unpack("S", substr $blk,91,2) );
168         $hsh{'Sunrise'}  =~ s/(\d{2})(\d{2})/$1:$2/;
169         $hsh{'Sunset'}   = sprintf( "%04d", unpack("S", substr $blk,93,2) );
170         $hsh{'Sunset'}  =~ s/(\d{2})(\d{2})/$1:$2/;
171
172         #my $nl  =  ord substr $blk,95,1;
173         #my $cr  =  ord substr $blk,96,1;
174
175         my $crc = unpack "%n", substr($blk,97,2);
176         my $crc_calc = CRC_CCITT($blk);
177
178         if ($crc_calc==0) {
179                 return 0;
180         }
181         else {
182                 print "CRC check failed for LOOP data!\n";
183                 return 1;
184         }
185         #delete @hsh{'crc', 'crc_calc', 'next_rec'};
186         #delete($hsh{crc})||die"cant delete crc";
187         #delete($hsh{crc_calc})||die"cant delete crc_calc";
188         #delete($hsh{next_rec})||die"cant delete next_rec";
189
190 }
191
192 sub dew_point
193 {
194         my $temp = shift @_;
195         my $rh   = shift @_;
196
197         #  Using the simplified approximation for dew point
198         #  Accurate to 1 degree C for humidities > 50 %
199         #  http://en.wikipedia.org/wiki/Dew_point
200
201         my $dew_point = $temp - ( (100 - $rh)/5 );
202
203         return $dew_point;
204 }
205
206 sub CRC_CCITT
207 {
208     # Expects packed data...
209     my $data_str = shift @_;
210
211         my $crc = 0;
212         my @lst = split //, $data_str;
213         foreach my $data (@lst) {
214                 my $data = unpack("c",$data);
215
216                 my $crc_prev = $crc;
217                 my $index = $crc >> 8 ^ $data;
218                 my $lhs = $crc_table[$index];
219                 #print "lhs=$lhs, crc=$crc\n";
220                 my $rhs = ($crc << 8) & 0xFFFF;
221                 $crc = $lhs ^ $rhs;
222
223
224         }
225
226         return $crc;
227 }
228
229 sub load_crc_table
230 {
231
232         @crc_table = (
233                                   0x0, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
234                                   0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
235                                   0x1231, 0x210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
236                                   0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
237                                   0x2462, 0x3443, 0x420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
238                                   0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
239                                   0x3653, 0x2672, 0x1611, 0x630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
240                                   0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
241                                   0x48c4, 0x58e5, 0x6886, 0x78a7, 0x840, 0x1861, 0x2802, 0x3823,
242                                   0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
243                                   0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0xa50, 0x3a33, 0x2a12,
244                                   0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
245                                   0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0xc60, 0x1c41,
246                                   0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
247                                   0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0xe70,
248                                   0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
249                                   0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
250                                   0x1080, 0xa1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
251                                   0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
252                                   0x2b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
253                                   0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
254                                   0x34e2, 0x24c3, 0x14a0, 0x481, 0x7466, 0x6447, 0x5424, 0x4405,
255                                   0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
256                                   0x26d3, 0x36f2, 0x691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
257                                   0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
258                                   0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x8e1, 0x3882, 0x28a3,
259                                   0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
260                                   0x4a75, 0x5a54, 0x6a37, 0x7a16, 0xaf1, 0x1ad0, 0x2ab3, 0x3a92,
261                                   0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
262                                   0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0xcc1,
263                                   0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
264                                   0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0xed1, 0x1ef0
265                                  );
266
267         $bar_trend{-60} = "Falling Rapidly";
268         $bar_trend{196} = "Falling Rapidly";
269         $bar_trend{-20} = "Falling Slowly";
270         $bar_trend{236} = "Falling Slowly";
271         $bar_trend{0} = "Steady";
272         $bar_trend{20} = "Rising Slowly";
273         $bar_trend{60} = "Rising Rapidly";
274 }
275
276 sub gettime
277 {
278     $ob->write("GETTIME\n");
279         $ob->read_interval(200);
280         my($cnt_in, $str) = $ob->read(9);
281         if ($cnt_in==0) {
282                 dienice("read error cnt_in=$cnt_in, str='$str'");
283         }
284
285         my $ck = CRC_CCITT(substr($str,1,9));
286         if ( $ck ) {
287                 warn "checksum error"; return 0;
288         }
289         my @rsp_lst =  split //, $str;
290         shift @rsp_lst;
291         @rsp_lst = map ord, @rsp_lst;
292     return \@rsp_lst;
293 }
294
295 sub settime
296 {
297     my $s_time = [ localtime() ];
298     $s_time->[4] += 1;
299
300         $ob->write("SETTIME\n");
301         $ob->read_interval(300);
302         my ($cnt_in, $str) = $ob->read(1);
303         my $ack = ord $str;
304         if ( $ack != 6 ) {
305                 warn "SETTIME not set ack $ack !"; return 0;
306         }
307         my ($sec, $min, $hour, $day, $mon, $yr) = @{$s_time};
308         $str = join "", map chr, ($sec, $min, $hour, $day, $mon, $yr);
309         my $ck = CRC_CCITT($str);
310         $str = $str . pack("n",$ck);
311         $ob->write($str);
312         ($cnt_in, $str) = $ob->read(1);
313         if ( ord($str) != 6 ) {
314                 warn "SETTIME not set!"; return 0;
315         }
316         sleep 3;                  # The console seems to need to some time here...
317 }
318
319 sub get_loop
320 {
321         print "** get loop at ", scalar localtime, "\n";
322         my $loops=1;
323         $ob->write("LOOP $loops\n");
324         $ob->read_interval(0);
325         ($count, $result) = $ob->read(1);
326         for (my $i=0; $i<$loops; $i+=1) {
327                 my $rc=loop_dump();
328                 if ($rc!=0) {
329                         last;
330                 }
331         }
332         return;
333
334 }
335
336 sub loop_dump
337 {
338         $ob->read_interval(0);
339         ($count, $result) = $ob->read(99);
340         if ($count != 99) {
341                 print "loop error - got $count bytes, expected 99\n";
342                 return 1;
343         }
344         print "LOOP data received\n";
345
346         if (ord(substr($result,0,1))==6) {
347                 $result=substr($result,1);
348         }
349
350         my $rc=parse_loop_blck($result);
351         if ($rc!=0) {
352                 return;
353         }                                                       # bad crc so goto next
354         foreach my $key (sort keys %hsh) {
355                 print "$key = $hsh{$key}\n";
356         }
357
358         my $stmt = 'INSERT INTO current (Date_Time,' . join(',', keys %hsh) . ') VALUES (NOW(),' . join(',', ('?') x keys %hsh) . ')';
359
360         $dbh->do( $stmt, undef, values %hsh);
361
362         %hsh=();
363         return 0;
364 }
365
366
367 sub do_dmpaft
368 {
369         #my $self = shift @_;
370         open(DMP,">dump.txt");
371         my $vDateStamp = shift @_;
372         my $vTimeStamp = shift @_;
373
374         # If not date/time stamp then assume 0 which will down load the entire archive
375         unless ( $vDateStamp ) {
376                 $vDateStamp = 0;
377         }
378         unless ( $vTimeStamp ) {
379                 $vTimeStamp = 0;
380         }
381
382         #my $port_obj = $self->{'port_obj'};
383
384         my $datetime = pack("ss",$vDateStamp, $vTimeStamp);
385
386         my $crc = CRC_CCITT($datetime);
387         my $cmd = pack("ssn",$vDateStamp,$vTimeStamp,$crc);
388
389         #-----------------------
390         #my $str = unpack("H*", $cmd);
391         #$str =~ s/(\w{2})/$1 /g;
392         # Documentation is wrong! The example should be <0xC6><0x06><0xA2><0x03> in section X
393         #print "cmd : $str \n";exit;
394         #-----------------------
395
396         #sleep 2; # Needed after loop
397         #$self->wake_up();
398
399         # Ok let's start the communication sequence....
400         my $cnt_out = $ob->write("DMPAFT\n");
401         unless ($cnt_out) {
402                 warn "write failed\n";
403         }
404         ;
405
406         $ob->read_interval(300);
407         my ($cnt_in, $str) = $ob->read(1);
408
409         my $ack = ord $str;
410         unless ($ack == 6) {
411                 warn "Ack not received on DMPAFT command: $ack"; exit -1;
412         }
413
414         $cnt_out = $ob->write($cmd);
415         unless ($cnt_out) {
416                 warn "write failed\n";
417         }
418         ;
419         ($cnt_in, $str) = $ob->read(7);
420
421         $ack = ord substr($str,0,1);
422
423         my $ls = unpack("H20",substr($str,1,4) );
424         $ls =~ s/(\w{2})/$1 /g;
425
426         my $pages = unpack("s",substr($str,1,2) );
427         my $rec_start = unpack("s",substr($str,3,2) );
428
429         $crc = CRC_CCITT(substr($str,1,6) );
430
431         print "Pages = $pages : rec = $rec_start Datestamp $vDateStamp $crc\n";
432
433         $cnt_out = $ob->write( pack("h", 0x06) );
434
435         #if ($pages == 513 ) { return -1 }
436
437         my @arc_rec_lst;
438         foreach my $page (1..$pages) {
439                 my $page_sz = 267;
440                 $ob->read_interval(0);
441                 my ($cnt_in, $str) = $ob->read($page_sz); #,3
442                 printf("len=%s\n",length($str));
443                 if ($cnt_in!=$page_sz) {
444                         dienice("hmm, dmpaft only got $cnt_in bytes. was expecting $page_sz");
445                 }
446                 print "Page $page\n";
447                 #print DMP $str,"\n";
448                 #print "ACK receipt of page $page\n";
449                 #$ob->write( pack("h", 0x06) );
450                 #next;
451                 my $calc_crc = CRC_CCITT($str);
452                 my $crc = unpack "%n", substr($str,265,2);
453                 print "page crc=$crc, calc_crc=$calc_crc\n";
454                 my $rec_sz = 52;
455                 my $date_prev = 0;
456                 my %hsh;
457
458                 foreach my $rec ( 0..4 ) {
459                         if ( ($page == 1) && ($rec < $rec_start ) ) {
460                                 next;
461                         }                                       # Find the right starting point...
462
463                         my $start_ptr = 1 + ($rec * $rec_sz );
464                         my $rec_str = substr($str, $start_ptr ,52);
465
466                         #print "$start_ptr \t > " . unpack( "h*", $rec_str) . "\n";
467
468                         my $date = substr($rec_str,0,2);
469                         my $date_curr =  unpack "s", $date;
470
471                         # Check if we have wrapped...
472                         if ( $date_curr < $date_prev ) {
473                                 last;
474                         }
475                         $date_prev = $date_curr;
476
477                         $hsh{'date_stamp'} =  $date_curr;
478                         $hsh{'time_stamp'} =  unpack "s", substr($rec_str,2,2);
479
480                         $hsh{'day'}    = unpack( "c", $date & pack("c",0x1F) );
481                         $hsh{'month'}  = ( $hsh{'date_stamp'} >> 5) & 0xF;
482                         $hsh{'year'}  =  ( $hsh{'date_stamp'} >> 9) + 2000;
483
484                         $hsh{'hour'}  = sprintf("%02d", int ( $hsh{'time_stamp'} / 100 ));
485
486                         $hsh{'min'}  =  $hsh{'time_stamp'} - ($hsh{'hour'} * 100);
487                         $hsh{'min'}  =  sprintf("%02d", $hsh{'min'});
488
489                         $hsh{'time_stamp_fmt'}  =  "$hsh{'hour'}:$hsh{'min'}:00";
490                         $hsh{'date_stamp_fmt'}  =  "$hsh{'year'}_$hsh{'month'}_$hsh{'day'}";
491
492                         #$hsh{'unixtime'} = timelocal(0,$hsh{min}, $hsh{hour}, $hsh{day}, $hsh{month}-1, $hsh{year}-1900);
493
494                         $hsh{'Air_Temp'} = unpack("s", substr($rec_str,4,2)) / 10;
495                         $hsh{'Air_Temp_Hi'} = unpack("s", substr($rec_str,6,2)) / 10;
496                         $hsh{'Air_Temp_Lo'} = unpack("s", substr($rec_str,8,2)) / 10;
497                         $hsh{'Rain_Clicks'} = unpack("s", substr($rec_str,10,2));
498                         $hsh{'Rain_Rate'}   = unpack("s", substr($rec_str,12,2)) / 100; # Inches per hour
499                         $hsh{'Barometric_Press'}   = unpack("s", substr $rec_str,14,2) / 1000;
500                         $hsh{'Solar'}   = unpack("s", substr $rec_str,16,2); # watt/m**2
501                         $hsh{'Wind_Samples'}  = unpack("s", substr $rec_str,18,2);
502                         $hsh{'Air_Temp_Inside'}  = unpack("s", substr $rec_str,20,2) / 10;
503
504                         $hsh{'Relative_Humidity_Inside'}  = unpack("C", substr $rec_str,22,1);
505                         $hsh{'Relative_Humidity'} = unpack("C", substr $rec_str,23,1);
506
507                         $hsh{'Wind_Speed'}    =  unpack("C", substr($rec_str,24,1));
508                         $hsh{'Wind_Gust_Max'} = unpack("C", substr($rec_str,25,1));
509                         $hsh{'Wind_Dir_Max'}  = unpack("C", substr($rec_str,26,1));
510                         $hsh{'Wind_Dir'}      = unpack("C", substr($rec_str,27,1));
511
512                         $hsh{'UV'} = unpack("C", substr($rec_str,28,1)) / 10;
513                         $hsh{'ET'} = unpack("C", substr($rec_str,29,1)) / 1000;
514
515                         $hsh{'Solar_Max'} = unpack("s", substr($rec_str,30,2));
516                         $hsh{'UV_Max'} = unpack("C", substr($rec_str,32,1));
517
518                         $hsh{'Forecast_Rule'} = unpack("C", substr($rec_str,33,1));
519
520                         #                       $hsh{'Dew_Point'}  = _dew_point($hsh{'Air_Temp'},$hsh{'Relative_Humidity'});
521
522                         # Miscellaneous others omitted for now
523
524                         print "date> $hsh{'Air_Temp'} $hsh{'time_stamp'} $hsh{'time_stamp_fmt'}  $hsh{'date_stamp'} $hsh{'date_stamp_fmt'}\n";
525                         #print Dumper \%hsh;
526
527                         push @arc_rec_lst, {%hsh};
528                 }
529
530                 #$in = <STDIN>; # Testing step through facility
531                 #if ($in =~ /q/i ) {  $port_obj->write( pack("h", 0x1B) ); last; }
532                 #else              {  $port_obj->write( pack("h", 0x06) ); }
533                 print "ACK receipt of page\n";
534                 $ob->write( pack("h", 0x06) );
535
536         }
537         close DMP;
538 }
539
540 package Device::SerialPort;
541
542 sub read_interval
543 {
544
545 }