[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

metar decoder to STDOUT



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