[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
metar decoder to STDOUT
- Subject: metar decoder to STDOUT
- Date: Wed, 5 May 2004 16:46:43 -0600 (MDT)
Beth,
Last week, I mentioned in my decoders talk that one could slighty modify
the metarWriter decoder to write the output to STDOUT. The code was
commented to block the write to the station file and then to STDOUT. ie
#open( STN, ">>$stn_name" ) ;
#print STN "$_\n" ;
#close STN ;
print STDOUT "$_\n" ;
A pqact entry would probably look similar to this:
# All aviation reports including metar tests, broken/written to stn files
DDS|IDS ^S(A....|P....|XUS8.) .... ([0-3][0-9])
PIPE /local/ldm/decoders/metarWriter (\2:yyyy)(\2:mm) | yourdecoder
Robb...
===============================================================================
Robb Kambic Unidata Program Center
Software Engineer III Univ. Corp for Atmospheric Research
address@hidden WWW: http://www.unidata.ucar.edu/
===============================================================================
#! /usr/local/bin/perl
#
# metarWriter
#
# Program to split metar type bulletins into individual reports, then write
# them to a directory structure ~/data/metar/yyyymmdd/stn using the station
# name as the file name. The additional reports for the hour are appended to
# file.
#
use Time::Local ;
# process command line switches
while ($_ = $ARGV[0], /^-/) {
shift;
last if /^--$/;
/^(-v)/ && $verbose++;
}
# process input parameters
if( $#ARGV == 0 ) {
$yyyymm = $ARGV[ 0 ] ;
die "yyyymm must be 6 in length: $!\n" if( length( $yyyymm ) != 6 ) ;
$theyear = substr( $yyyymm, 0, 4 ) ;
$themonth = substr( $yyyymm, 4 ) ;
} else {
die "usage: metarWriter yyyymm < rawMetars $!\n" ;
}
# set interrupt handler
$SIG{ 'INT' } = 'atexit' ;
$SIG{ 'KILL' } = 'atexit' ;
$SIG{ 'TERM' } = 'atexit' ;
$SIG{ 'QUIT' } = 'atexit' ;
chdir( "$datadir" ) ;
# Now begin parsing file and decoding observations breaking on cntrl C
$/ = "\cC" ;
# set select processing here from STDIN
START:
while( 1 ) {
open( STDIN, '-' ) ;
vec($rin,fileno(STDIN),1) = 1;
$timeout = 1200 ; # 20 minutes
$nfound = select( $rout = $rin, undef, undef, $timeout );
# timed out
if( ! $nfound ) {
print "Shut down, time out 20 minutes\n" ;
atexit() ;
}
atexit( "eof" ) if( eof( STDIN ) ) ;
# Process each line of metar bulletins, header first
$_ = <STDIN> ;
s#\cC## ;
s#\cM##g ;
s#\cA\n## ;
s#\c^##g ;
s#\d\d\d \n## ;
s#\w{4}\d{1,2} \w{4} (\d{2})(\d{2})(\d{2}).*\n## ;
$bday = $1 ;
$bhour = $2 ;
$bhour = "23" if( $bhour eq "24" ) ;
$bmin = $3 ;
next unless ( $bday && defined( $bhour ) && defined( $bmin ) ) ;
next if( $bmin > 59 || $bhour > 23 || $bday > 31 ) ;
# check for valid transmission times against current time
$cday = (gmtime())[ 3 ] ;
$chour = (gmtime())[ 2 ] ;
# skip bulletins over 24 hours old or in the future
if( $bday == $cday ) {
next if( $bhour > $chour ) ;
} else { # $bday != $cday, skip over day old reports
next if( $bday < $cday -1 ) ;
if( $bday > $cday ) {
next if( $cday != 1 || $bday < 28) ;
}
next if( $bhour < $chour ) ;
}
if( s#(METAR|SPECI) \d{4,6}Z?\n## ) {
$rep_type = $1 ;
} elsif( s#(METAR|SPECI)\s*\n## ) {
$rep_type = $1 ;
} elsif( s#^MTR\w{3}\s*\n## ) {
$rep_type = "METAR" ;
} else {
$rep_type = "METAR" ;
}
# Separate bulletins into reports
if( /=\n/ ) {
s#=\s+\n#=\n#g ;
@reports = split( /=\n/ ) ;
} else {
@reports = split ( /\n/ ) ;
}
for ( @reports ) { # Process each report in the bulletin
undef( $report ) ;
undef( $remarks ) ;
undef( $stn_name ) ;
next if( /^\n|NIL/ ) ;
s#^(METAR|M E T A R|SPECI|TESTM|TESTS)\s*\n?## ;
if( /\n\w{4} \d{4,6}Z/ ) { # reports appended together wrongly
( $_, $tmp ) = split( "\n", $_ ) ;
}
s#\n# #g ;
$rep_type = $1 if( s#^(METAR|SPECI|TESTM|TESTS)\s+## ) ;
$stn_name = $1 if( m#^(\w{4})\s+# ) ;
next unless( $stn_name ) ;
# Valid time needed for dir structure
if( m#(\d{2})(\d{2})(\d{2})Z# ) {
$rday = $1 ;
$rhour = $2 ;
$rmin = $3 ;
next unless
($rday && defined( $rhour ) && defined( $rmin
));
next if( $rmin > 59 || $rhour > 23 || $rday > 31 ) ;
# skip reports over 24 hours old
if( $rday == $cday ) {
next if( $rhour > $chour ) ;
$tmpyyyymm = $yyyymm ;
} else { # $rday != $cday, skip over day old reports
next if( $rday < ( $cday -1 ) ) ;
if( $rday > $cday ) {
next if( $cday != 1 || $rday < 28) ;
# cday = 1, reset month and year
$tmpmonth =
sprintf( "%02d", $themonth -1 );
if( $tmpmonth == 0 ) {
$tmpmonth = "12" ;
$tmpyear =
sprintf( "%04d", $theyear -1 );
} else {
$tmpyear = $theyear ;
}
$tmpyyyymm = $tmpyear . $tmpmonth ;
}
next if( $rhour < $chour ) ;
}
$yyyymmdd = $tmpyyyymm . $rday ;
mkdir( "$yyyymmdd", 0775 ) if( ! -e "$yyyymmdd" ) ;
chdir( "$yyyymmdd" ) ;
} else {
next ;
}
#open( STN, ">>$stn_name" ) ;
#print STN "$_\n" ;
#close STN ;
print STDOUT "$_\n" ;
chdir( ".." ) ;
} # end foreach report
} # end while( 1 )
atexit( "eof" );
exit( 0 ) ; #should never get here
# execute at exit
sub atexit
{
local( $sig ) = @_ ;
if( $sig eq "eof" ) {
print "eof on STDIN --shutting down\n" ;
} elsif( defined( $sig )) {
print "Caught SIG$sig --shutting down\n" ;
}
exit( 0 ) ;
} #end atexit