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

Re: metar decoder to STDOUT



Beth,

I'm resending because the code that was sent makes a directory that it not
needed if the products are written to STDOUT. Directory  code is now
commented out.

Robb...

On Wed, 5 May 2004, Robb Kambic wrote:

> 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/
> ===============================================================================

===============================================================================
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